xref: /llvm-project/lldb/unittests/Utility/RealpathPrefixesTest.cpp (revision 26670e7fa4f032a019d23d56c6a02926e854e8af)
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