147721d46Sroyitaqi //===-- RealpathPrefixesTest.cpp 247721d46Sroyitaqi //--------------------------------------------------===// 347721d46Sroyitaqi // 447721d46Sroyitaqi // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 547721d46Sroyitaqi // See https://llvm.org/LICENSE.txt for license information. 647721d46Sroyitaqi // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 747721d46Sroyitaqi // 847721d46Sroyitaqi //===----------------------------------------------------------------------===// 947721d46Sroyitaqi 1047721d46Sroyitaqi #include "gtest/gtest.h" 1147721d46Sroyitaqi 1247721d46Sroyitaqi #include "MockSymlinkFileSystem.h" 1347721d46Sroyitaqi #include "lldb/Utility/FileSpecList.h" 1447721d46Sroyitaqi #include "lldb/Utility/RealpathPrefixes.h" 1547721d46Sroyitaqi 1647721d46Sroyitaqi using namespace lldb_private; 1747721d46Sroyitaqi 18*26670e7fSroyitaqi static FileSpec PosixSpec(llvm::StringRef path) { 19*26670e7fSroyitaqi return FileSpec(path, FileSpec::Style::posix); 20*26670e7fSroyitaqi } 21*26670e7fSroyitaqi 22*26670e7fSroyitaqi static FileSpec WindowsSpec(llvm::StringRef path) { 23*26670e7fSroyitaqi return FileSpec(path, FileSpec::Style::windows); 24*26670e7fSroyitaqi } 25*26670e7fSroyitaqi 2647721d46Sroyitaqi // Should resolve a symlink which match an absolute prefix 2747721d46Sroyitaqi TEST(RealpathPrefixesTest, MatchingAbsolutePrefix) { 2847721d46Sroyitaqi // Prepare FS 2947721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( 30*26670e7fSroyitaqi PosixSpec("/dir1/link.h"), PosixSpec("/dir2/real.h"), 31*26670e7fSroyitaqi FileSpec::Style::posix)); 3247721d46Sroyitaqi 3347721d46Sroyitaqi // Prepare RealpathPrefixes 3447721d46Sroyitaqi FileSpecList file_spec_list; 35*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("/dir1")); 3647721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 3747721d46Sroyitaqi 3847721d46Sroyitaqi // Test 3947721d46Sroyitaqi std::optional<FileSpec> ret = 40*26670e7fSroyitaqi prefixes.ResolveSymlinks(PosixSpec("/dir1/link.h")); 41*26670e7fSroyitaqi EXPECT_EQ(ret, PosixSpec("/dir2/real.h")); 4247721d46Sroyitaqi } 4347721d46Sroyitaqi 4447721d46Sroyitaqi // Should resolve a symlink which match a relative prefix 4547721d46Sroyitaqi TEST(RealpathPrefixesTest, MatchingRelativePrefix) { 4647721d46Sroyitaqi // Prepare FS 4747721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( 48*26670e7fSroyitaqi PosixSpec("dir1/link.h"), PosixSpec("dir2/real.h"), 49*26670e7fSroyitaqi FileSpec::Style::posix)); 5047721d46Sroyitaqi 5147721d46Sroyitaqi // Prepare RealpathPrefixes 5247721d46Sroyitaqi FileSpecList file_spec_list; 53*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("dir1")); 5447721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 5547721d46Sroyitaqi 5647721d46Sroyitaqi // Test 5747721d46Sroyitaqi std::optional<FileSpec> ret = 58*26670e7fSroyitaqi prefixes.ResolveSymlinks(PosixSpec("dir1/link.h")); 59*26670e7fSroyitaqi EXPECT_EQ(ret, PosixSpec("dir2/real.h")); 6047721d46Sroyitaqi } 6147721d46Sroyitaqi 6247721d46Sroyitaqi // Should resolve in Windows and/or with a case-insensitive support file 6347721d46Sroyitaqi TEST(RealpathPrefixesTest, WindowsAndCaseInsensitive) { 6447721d46Sroyitaqi // Prepare FS 6547721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( 66*26670e7fSroyitaqi WindowsSpec("f:\\dir1\\link.h"), WindowsSpec("f:\\dir2\\real.h"), 6747721d46Sroyitaqi FileSpec::Style::windows)); 6847721d46Sroyitaqi 6947721d46Sroyitaqi // Prepare RealpathPrefixes 7047721d46Sroyitaqi FileSpecList file_spec_list; 71*26670e7fSroyitaqi file_spec_list.Append(WindowsSpec("f:\\dir1")); 7247721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 7347721d46Sroyitaqi 7447721d46Sroyitaqi // Test 75*26670e7fSroyitaqi std::optional<FileSpec> ret = 76*26670e7fSroyitaqi prefixes.ResolveSymlinks(WindowsSpec("F:\\DIR1\\LINK.H")); 77*26670e7fSroyitaqi EXPECT_EQ(ret, WindowsSpec("f:\\dir2\\real.h")); 7847721d46Sroyitaqi } 7947721d46Sroyitaqi 8047721d46Sroyitaqi // Should resolve a symlink when there is mixture of matching and mismatching 8147721d46Sroyitaqi // prefixex 8247721d46Sroyitaqi TEST(RealpathPrefixesTest, MatchingAndMismatchingPrefix) { 8347721d46Sroyitaqi // Prepare FS 8447721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( 85*26670e7fSroyitaqi PosixSpec("/dir1/link.h"), PosixSpec("/dir2/real.h"), 86*26670e7fSroyitaqi FileSpec::Style::posix)); 8747721d46Sroyitaqi 8847721d46Sroyitaqi // Prepare RealpathPrefixes 8947721d46Sroyitaqi FileSpecList file_spec_list; 90*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("/fake/path1")); 91*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("/dir1")); // Matching prefix 92*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("/fake/path2")); 9347721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 9447721d46Sroyitaqi 9547721d46Sroyitaqi // Test 9647721d46Sroyitaqi std::optional<FileSpec> ret = 97*26670e7fSroyitaqi prefixes.ResolveSymlinks(PosixSpec("/dir1/link.h")); 98*26670e7fSroyitaqi EXPECT_EQ(ret, PosixSpec("/dir2/real.h")); 9947721d46Sroyitaqi } 10047721d46Sroyitaqi 10147721d46Sroyitaqi // Should resolve a symlink when the prefixes matches after normalization 10247721d46Sroyitaqi TEST(RealpathPrefixesTest, ComplexPrefixes) { 10347721d46Sroyitaqi // Prepare FS 10447721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( 105*26670e7fSroyitaqi PosixSpec("dir1/link.h"), PosixSpec("dir2/real.h"), 106*26670e7fSroyitaqi FileSpec::Style::posix)); 10747721d46Sroyitaqi 10847721d46Sroyitaqi // Prepare RealpathPrefixes 10947721d46Sroyitaqi FileSpecList file_spec_list; 110*26670e7fSroyitaqi file_spec_list.Append( 111*26670e7fSroyitaqi PosixSpec("./dir1/foo/../bar/..")); // Equivalent to "/dir1" 11247721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 11347721d46Sroyitaqi 11447721d46Sroyitaqi // Test 11547721d46Sroyitaqi std::optional<FileSpec> ret = 116*26670e7fSroyitaqi prefixes.ResolveSymlinks(PosixSpec("dir1/link.h")); 117*26670e7fSroyitaqi EXPECT_EQ(ret, PosixSpec("dir2/real.h")); 11847721d46Sroyitaqi } 11947721d46Sroyitaqi 12047721d46Sroyitaqi // Should not resolve a symlink which doesn't match any prefixes 12147721d46Sroyitaqi TEST(RealpathPrefixesTest, MismatchingPrefixes) { 12247721d46Sroyitaqi // Prepare FS 12347721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( 124*26670e7fSroyitaqi PosixSpec("/dir1/link.h"), PosixSpec("/dir2/real.h"), 125*26670e7fSroyitaqi FileSpec::Style::posix)); 12647721d46Sroyitaqi 12747721d46Sroyitaqi // Prepare RealpathPrefixes 12847721d46Sroyitaqi FileSpecList file_spec_list; 129*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("/dir3")); 13047721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 13147721d46Sroyitaqi 13247721d46Sroyitaqi // Test 13347721d46Sroyitaqi std::optional<FileSpec> ret = 134*26670e7fSroyitaqi prefixes.ResolveSymlinks(PosixSpec("/dir1/link.h")); 13547721d46Sroyitaqi EXPECT_EQ(ret, std::nullopt); 13647721d46Sroyitaqi } 13747721d46Sroyitaqi 13847721d46Sroyitaqi // Should not resolve a realpath 13947721d46Sroyitaqi TEST(RealpathPrefixesTest, Realpath) { 14047721d46Sroyitaqi // Prepare FS 14147721d46Sroyitaqi llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs( 14247721d46Sroyitaqi new MockSymlinkFileSystem()); 14347721d46Sroyitaqi 14447721d46Sroyitaqi // Prepare RealpathPrefixes 14547721d46Sroyitaqi FileSpecList file_spec_list; 146*26670e7fSroyitaqi file_spec_list.Append(PosixSpec("/symlink_dir")); 14747721d46Sroyitaqi RealpathPrefixes prefixes(file_spec_list, fs); 14847721d46Sroyitaqi 14947721d46Sroyitaqi // Test 15047721d46Sroyitaqi std::optional<FileSpec> ret = 151*26670e7fSroyitaqi prefixes.ResolveSymlinks(PosixSpec("/dir/real.h")); 15247721d46Sroyitaqi EXPECT_EQ(ret, std::nullopt); 15347721d46Sroyitaqi } 154