1 //===-- RealpathPrefixesTest.cpp
2 //--------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #include "gtest/gtest.h"
12 #include "MockSymlinkFileSystem.h"
13 #include "lldb/Utility/FileSpecList.h"
14 #include "lldb/Utility/RealpathPrefixes.h"
16 using namespace lldb_private
;
18 static FileSpec
PosixSpec(llvm::StringRef path
) {
19 return FileSpec(path
, FileSpec::Style::posix
);
22 static FileSpec
WindowsSpec(llvm::StringRef path
) {
23 return FileSpec(path
, FileSpec::Style::windows
);
26 // Should resolve a symlink which match an absolute prefix
27 TEST(RealpathPrefixesTest
, MatchingAbsolutePrefix
) {
29 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(new MockSymlinkFileSystem(
30 PosixSpec("/dir1/link.h"), PosixSpec("/dir2/real.h"),
31 FileSpec::Style::posix
));
33 // Prepare RealpathPrefixes
34 FileSpecList file_spec_list
;
35 file_spec_list
.Append(PosixSpec("/dir1"));
36 RealpathPrefixes
prefixes(file_spec_list
, fs
);
39 std::optional
<FileSpec
> ret
=
40 prefixes
.ResolveSymlinks(PosixSpec("/dir1/link.h"));
41 EXPECT_EQ(ret
, PosixSpec("/dir2/real.h"));
44 // Should resolve a symlink which match a relative prefix
45 TEST(RealpathPrefixesTest
, MatchingRelativePrefix
) {
47 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(new MockSymlinkFileSystem(
48 PosixSpec("dir1/link.h"), PosixSpec("dir2/real.h"),
49 FileSpec::Style::posix
));
51 // Prepare RealpathPrefixes
52 FileSpecList file_spec_list
;
53 file_spec_list
.Append(PosixSpec("dir1"));
54 RealpathPrefixes
prefixes(file_spec_list
, fs
);
57 std::optional
<FileSpec
> ret
=
58 prefixes
.ResolveSymlinks(PosixSpec("dir1/link.h"));
59 EXPECT_EQ(ret
, PosixSpec("dir2/real.h"));
62 // Should resolve in Windows and/or with a case-insensitive support file
63 TEST(RealpathPrefixesTest
, WindowsAndCaseInsensitive
) {
65 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(new MockSymlinkFileSystem(
66 WindowsSpec("f:\\dir1\\link.h"), WindowsSpec("f:\\dir2\\real.h"),
67 FileSpec::Style::windows
));
69 // Prepare RealpathPrefixes
70 FileSpecList file_spec_list
;
71 file_spec_list
.Append(WindowsSpec("f:\\dir1"));
72 RealpathPrefixes
prefixes(file_spec_list
, fs
);
75 std::optional
<FileSpec
> ret
=
76 prefixes
.ResolveSymlinks(WindowsSpec("F:\\DIR1\\LINK.H"));
77 EXPECT_EQ(ret
, WindowsSpec("f:\\dir2\\real.h"));
80 // Should resolve a symlink when there is mixture of matching and mismatching
82 TEST(RealpathPrefixesTest
, MatchingAndMismatchingPrefix
) {
84 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(new MockSymlinkFileSystem(
85 PosixSpec("/dir1/link.h"), PosixSpec("/dir2/real.h"),
86 FileSpec::Style::posix
));
88 // Prepare RealpathPrefixes
89 FileSpecList file_spec_list
;
90 file_spec_list
.Append(PosixSpec("/fake/path1"));
91 file_spec_list
.Append(PosixSpec("/dir1")); // Matching prefix
92 file_spec_list
.Append(PosixSpec("/fake/path2"));
93 RealpathPrefixes
prefixes(file_spec_list
, fs
);
96 std::optional
<FileSpec
> ret
=
97 prefixes
.ResolveSymlinks(PosixSpec("/dir1/link.h"));
98 EXPECT_EQ(ret
, PosixSpec("/dir2/real.h"));
101 // Should resolve a symlink when the prefixes matches after normalization
102 TEST(RealpathPrefixesTest
, ComplexPrefixes
) {
104 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(new MockSymlinkFileSystem(
105 PosixSpec("dir1/link.h"), PosixSpec("dir2/real.h"),
106 FileSpec::Style::posix
));
108 // Prepare RealpathPrefixes
109 FileSpecList file_spec_list
;
110 file_spec_list
.Append(
111 PosixSpec("./dir1/foo/../bar/..")); // Equivalent to "/dir1"
112 RealpathPrefixes
prefixes(file_spec_list
, fs
);
115 std::optional
<FileSpec
> ret
=
116 prefixes
.ResolveSymlinks(PosixSpec("dir1/link.h"));
117 EXPECT_EQ(ret
, PosixSpec("dir2/real.h"));
120 // Should not resolve a symlink which doesn't match any prefixes
121 TEST(RealpathPrefixesTest
, MismatchingPrefixes
) {
123 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(new MockSymlinkFileSystem(
124 PosixSpec("/dir1/link.h"), PosixSpec("/dir2/real.h"),
125 FileSpec::Style::posix
));
127 // Prepare RealpathPrefixes
128 FileSpecList file_spec_list
;
129 file_spec_list
.Append(PosixSpec("/dir3"));
130 RealpathPrefixes
prefixes(file_spec_list
, fs
);
133 std::optional
<FileSpec
> ret
=
134 prefixes
.ResolveSymlinks(PosixSpec("/dir1/link.h"));
135 EXPECT_EQ(ret
, std::nullopt
);
138 // Should not resolve a realpath
139 TEST(RealpathPrefixesTest
, Realpath
) {
141 llvm::IntrusiveRefCntPtr
<MockSymlinkFileSystem
> fs(
142 new MockSymlinkFileSystem());
144 // Prepare RealpathPrefixes
145 FileSpecList file_spec_list
;
146 file_spec_list
.Append(PosixSpec("/symlink_dir"));
147 RealpathPrefixes
prefixes(file_spec_list
, fs
);
150 std::optional
<FileSpec
> ret
=
151 prefixes
.ResolveSymlinks(PosixSpec("/dir/real.h"));
152 EXPECT_EQ(ret
, std::nullopt
);