1 | //===-- RealpathPrefixesTest.cpp |
2 | //--------------------------------------------------===// |
3 | // |
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 |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #include "gtest/gtest.h" |
11 | |
12 | #include "MockSymlinkFileSystem.h" |
13 | #include "lldb/Utility/FileSpecList.h" |
14 | #include "lldb/Utility/RealpathPrefixes.h" |
15 | |
16 | using namespace lldb_private; |
17 | |
18 | static FileSpec PosixSpec(llvm::StringRef path) { |
19 | return FileSpec(path, FileSpec::Style::posix); |
20 | } |
21 | |
22 | static FileSpec WindowsSpec(llvm::StringRef path) { |
23 | return FileSpec(path, FileSpec::Style::windows); |
24 | } |
25 | |
26 | // Should resolve a symlink which match an absolute prefix |
27 | TEST(RealpathPrefixesTest, MatchingAbsolutePrefix) { |
28 | // Prepare FS |
29 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( |
30 | PosixSpec(path: "/dir1/link.h" ), PosixSpec(path: "/dir2/real.h" ), |
31 | FileSpec::Style::posix)); |
32 | |
33 | // Prepare RealpathPrefixes |
34 | FileSpecList file_spec_list; |
35 | file_spec_list.Append(file: PosixSpec(path: "/dir1" )); |
36 | RealpathPrefixes prefixes(file_spec_list, fs); |
37 | |
38 | // Test |
39 | std::optional<FileSpec> ret = |
40 | prefixes.ResolveSymlinks(file_spec: PosixSpec(path: "/dir1/link.h" )); |
41 | EXPECT_EQ(ret, PosixSpec("/dir2/real.h" )); |
42 | } |
43 | |
44 | // Should resolve a symlink which match a relative prefix |
45 | TEST(RealpathPrefixesTest, MatchingRelativePrefix) { |
46 | // Prepare FS |
47 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( |
48 | PosixSpec(path: "dir1/link.h" ), PosixSpec(path: "dir2/real.h" ), |
49 | FileSpec::Style::posix)); |
50 | |
51 | // Prepare RealpathPrefixes |
52 | FileSpecList file_spec_list; |
53 | file_spec_list.Append(file: PosixSpec(path: "dir1" )); |
54 | RealpathPrefixes prefixes(file_spec_list, fs); |
55 | |
56 | // Test |
57 | std::optional<FileSpec> ret = |
58 | prefixes.ResolveSymlinks(file_spec: PosixSpec(path: "dir1/link.h" )); |
59 | EXPECT_EQ(ret, PosixSpec("dir2/real.h" )); |
60 | } |
61 | |
62 | // Should resolve in Windows and/or with a case-insensitive support file |
63 | TEST(RealpathPrefixesTest, WindowsAndCaseInsensitive) { |
64 | // Prepare FS |
65 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( |
66 | WindowsSpec(path: "f:\\dir1\\link.h" ), WindowsSpec(path: "f:\\dir2\\real.h" ), |
67 | FileSpec::Style::windows)); |
68 | |
69 | // Prepare RealpathPrefixes |
70 | FileSpecList file_spec_list; |
71 | file_spec_list.Append(file: WindowsSpec(path: "f:\\dir1" )); |
72 | RealpathPrefixes prefixes(file_spec_list, fs); |
73 | |
74 | // Test |
75 | std::optional<FileSpec> ret = |
76 | prefixes.ResolveSymlinks(file_spec: WindowsSpec(path: "F:\\DIR1\\LINK.H" )); |
77 | EXPECT_EQ(ret, WindowsSpec("f:\\dir2\\real.h" )); |
78 | } |
79 | |
80 | // Should resolve a symlink when there is mixture of matching and mismatching |
81 | // prefixex |
82 | TEST(RealpathPrefixesTest, MatchingAndMismatchingPrefix) { |
83 | // Prepare FS |
84 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( |
85 | PosixSpec(path: "/dir1/link.h" ), PosixSpec(path: "/dir2/real.h" ), |
86 | FileSpec::Style::posix)); |
87 | |
88 | // Prepare RealpathPrefixes |
89 | FileSpecList file_spec_list; |
90 | file_spec_list.Append(file: PosixSpec(path: "/fake/path1" )); |
91 | file_spec_list.Append(file: PosixSpec(path: "/dir1" )); // Matching prefix |
92 | file_spec_list.Append(file: PosixSpec(path: "/fake/path2" )); |
93 | RealpathPrefixes prefixes(file_spec_list, fs); |
94 | |
95 | // Test |
96 | std::optional<FileSpec> ret = |
97 | prefixes.ResolveSymlinks(file_spec: PosixSpec(path: "/dir1/link.h" )); |
98 | EXPECT_EQ(ret, PosixSpec("/dir2/real.h" )); |
99 | } |
100 | |
101 | // Should resolve a symlink when the prefixes matches after normalization |
102 | TEST(RealpathPrefixesTest, ComplexPrefixes) { |
103 | // Prepare FS |
104 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( |
105 | PosixSpec(path: "dir1/link.h" ), PosixSpec(path: "dir2/real.h" ), |
106 | FileSpec::Style::posix)); |
107 | |
108 | // Prepare RealpathPrefixes |
109 | FileSpecList file_spec_list; |
110 | file_spec_list.Append( |
111 | file: PosixSpec(path: "./dir1/foo/../bar/.." )); // Equivalent to "/dir1" |
112 | RealpathPrefixes prefixes(file_spec_list, fs); |
113 | |
114 | // Test |
115 | std::optional<FileSpec> ret = |
116 | prefixes.ResolveSymlinks(file_spec: PosixSpec(path: "dir1/link.h" )); |
117 | EXPECT_EQ(ret, PosixSpec("dir2/real.h" )); |
118 | } |
119 | |
120 | // Should not resolve a symlink which doesn't match any prefixes |
121 | TEST(RealpathPrefixesTest, MismatchingPrefixes) { |
122 | // Prepare FS |
123 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs(new MockSymlinkFileSystem( |
124 | PosixSpec(path: "/dir1/link.h" ), PosixSpec(path: "/dir2/real.h" ), |
125 | FileSpec::Style::posix)); |
126 | |
127 | // Prepare RealpathPrefixes |
128 | FileSpecList file_spec_list; |
129 | file_spec_list.Append(file: PosixSpec(path: "/dir3" )); |
130 | RealpathPrefixes prefixes(file_spec_list, fs); |
131 | |
132 | // Test |
133 | std::optional<FileSpec> ret = |
134 | prefixes.ResolveSymlinks(file_spec: PosixSpec(path: "/dir1/link.h" )); |
135 | EXPECT_EQ(ret, std::nullopt); |
136 | } |
137 | |
138 | // Should not resolve a realpath |
139 | TEST(RealpathPrefixesTest, Realpath) { |
140 | // Prepare FS |
141 | llvm::IntrusiveRefCntPtr<MockSymlinkFileSystem> fs( |
142 | new MockSymlinkFileSystem()); |
143 | |
144 | // Prepare RealpathPrefixes |
145 | FileSpecList file_spec_list; |
146 | file_spec_list.Append(file: PosixSpec(path: "/symlink_dir" )); |
147 | RealpathPrefixes prefixes(file_spec_list, fs); |
148 | |
149 | // Test |
150 | std::optional<FileSpec> ret = |
151 | prefixes.ResolveSymlinks(file_spec: PosixSpec(path: "/dir/real.h" )); |
152 | EXPECT_EQ(ret, std::nullopt); |
153 | } |
154 | |