Mercurial > hg > CbC > CbC_llvm
comparison unittests/Support/FileCollectorTest.cpp @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
1 //===-- FileCollectorTest.cpp -----------------------------------*- C++ -*-===// | |
2 // | |
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
4 // See https://llvm.org/LICENSE.txt for license information. | |
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 | |
9 #include "gmock/gmock.h" | |
10 #include "gtest/gtest.h" | |
11 | |
12 #include "llvm/Support/FileCollector.h" | |
13 #include "llvm/Support/FileSystem.h" | |
14 | |
15 using namespace llvm; | |
16 | |
17 namespace llvm { | |
18 namespace vfs { | |
19 inline bool operator==(const llvm::vfs::YAMLVFSEntry &LHS, | |
20 const llvm::vfs::YAMLVFSEntry &RHS) { | |
21 return LHS.VPath == RHS.VPath && LHS.RPath == RHS.RPath; | |
22 } | |
23 } // namespace vfs | |
24 } // namespace llvm | |
25 | |
26 namespace { | |
27 class TestingFileCollector : public FileCollector { | |
28 public: | |
29 using FileCollector::FileCollector; | |
30 using FileCollector::Root; | |
31 using FileCollector::Seen; | |
32 using FileCollector::SymlinkMap; | |
33 using FileCollector::VFSWriter; | |
34 | |
35 bool hasSeen(StringRef fs) { | |
36 return Seen.find(fs) != Seen.end(); | |
37 } | |
38 }; | |
39 | |
40 struct ScopedDir { | |
41 SmallString<128> Path; | |
42 ScopedDir(const Twine &Name, bool Unique = false) { | |
43 std::error_code EC; | |
44 if (Unique) { | |
45 EC = llvm::sys::fs::createUniqueDirectory(Name, Path); | |
46 } else { | |
47 Path = Name.str(); | |
48 EC = llvm::sys::fs::create_directory(Twine(Path)); | |
49 } | |
50 if (EC) | |
51 Path = ""; | |
52 EXPECT_FALSE(EC); | |
53 // Ensure the path is the real path so tests can use it to compare against | |
54 // realpath output. | |
55 SmallString<128> RealPath; | |
56 if (!llvm::sys::fs::real_path(Path, RealPath)) | |
57 Path.swap(RealPath); | |
58 } | |
59 ~ScopedDir() { | |
60 if (Path != "") { | |
61 EXPECT_FALSE(llvm::sys::fs::remove_directories(Path.str())); | |
62 } | |
63 } | |
64 operator StringRef() { return Path.str(); } | |
65 }; | |
66 | |
67 struct ScopedLink { | |
68 SmallString<128> Path; | |
69 ScopedLink(const Twine &To, const Twine &From) { | |
70 Path = From.str(); | |
71 std::error_code EC = sys::fs::create_link(To, From); | |
72 if (EC) | |
73 Path = ""; | |
74 EXPECT_FALSE(EC); | |
75 } | |
76 ~ScopedLink() { | |
77 if (Path != "") { | |
78 EXPECT_FALSE(llvm::sys::fs::remove(Path.str())); | |
79 } | |
80 } | |
81 operator StringRef() { return Path.str(); } | |
82 }; | |
83 | |
84 struct ScopedFile { | |
85 SmallString<128> Path; | |
86 ScopedFile(const Twine &Name) { | |
87 std::error_code EC; | |
88 EC = llvm::sys::fs::createUniqueFile(Name, Path); | |
89 if (EC) | |
90 Path = ""; | |
91 EXPECT_FALSE(EC); | |
92 } | |
93 ~ScopedFile() { | |
94 if (Path != "") { | |
95 EXPECT_FALSE(llvm::sys::fs::remove(Path.str())); | |
96 } | |
97 } | |
98 operator StringRef() { return Path.str(); } | |
99 }; | |
100 } // end anonymous namespace | |
101 | |
102 TEST(FileCollectorTest, addFile) { | |
103 ScopedDir root("add_file_root", true); | |
104 std::string root_fs = root.Path.str(); | |
105 TestingFileCollector FileCollector(root_fs, root_fs); | |
106 | |
107 FileCollector.addFile("/path/to/a"); | |
108 FileCollector.addFile("/path/to/b"); | |
109 FileCollector.addFile("/path/to/c"); | |
110 | |
111 // Make sure the root is correct. | |
112 EXPECT_EQ(FileCollector.Root, root_fs); | |
113 | |
114 // Make sure we've seen all the added files. | |
115 EXPECT_TRUE(FileCollector.hasSeen("/path/to/a")); | |
116 EXPECT_TRUE(FileCollector.hasSeen("/path/to/b")); | |
117 EXPECT_TRUE(FileCollector.hasSeen("/path/to/c")); | |
118 | |
119 // Make sure we've only seen the added files. | |
120 EXPECT_FALSE(FileCollector.hasSeen("/path/to/d")); | |
121 } | |
122 | |
123 TEST(FileCollectorTest, copyFiles) { | |
124 ScopedDir file_root("file_root", true); | |
125 ScopedFile a(file_root + "/aaa"); | |
126 ScopedFile b(file_root + "/bbb"); | |
127 ScopedFile c(file_root + "/ccc"); | |
128 | |
129 // Create file collector and add files. | |
130 ScopedDir root("copy_files_root", true); | |
131 std::string root_fs = root.Path.str(); | |
132 TestingFileCollector FileCollector(root_fs, root_fs); | |
133 FileCollector.addFile(a.Path); | |
134 FileCollector.addFile(b.Path); | |
135 FileCollector.addFile(c.Path); | |
136 | |
137 // Make sure we can copy the files. | |
138 std::error_code ec = FileCollector.copyFiles(true); | |
139 EXPECT_FALSE(ec); | |
140 | |
141 // Now add a bogus file and make sure we error out. | |
142 FileCollector.addFile("/some/bogus/file"); | |
143 ec = FileCollector.copyFiles(true); | |
144 EXPECT_TRUE(ec); | |
145 | |
146 // However, if stop_on_error is true the copy should still succeed. | |
147 ec = FileCollector.copyFiles(false); | |
148 EXPECT_FALSE(ec); | |
149 } | |
150 | |
151 TEST(FileCollectorTest, recordAndConstructDirectory) { | |
152 ScopedDir file_root("dir_root", true); | |
153 ScopedDir subdir(file_root + "/subdir"); | |
154 ScopedDir subdir2(file_root + "/subdir2"); | |
155 ScopedFile a(subdir2 + "/a"); | |
156 | |
157 // Create file collector and add files. | |
158 ScopedDir root("copy_files_root", true); | |
159 std::string root_fs = root.Path.str(); | |
160 TestingFileCollector FileCollector(root_fs, root_fs); | |
161 FileCollector.addFile(a.Path); | |
162 | |
163 // The empty directory isn't seen until we add it. | |
164 EXPECT_TRUE(FileCollector.hasSeen(a.Path)); | |
165 EXPECT_FALSE(FileCollector.hasSeen(subdir.Path)); | |
166 | |
167 FileCollector.addFile(subdir.Path); | |
168 EXPECT_TRUE(FileCollector.hasSeen(subdir.Path)); | |
169 | |
170 // Make sure we can construct the directory. | |
171 std::error_code ec = FileCollector.copyFiles(true); | |
172 EXPECT_FALSE(ec); | |
173 bool IsDirectory = false; | |
174 llvm::SmallString<128> SubdirInRoot = root.Path; | |
175 llvm::sys::path::append(SubdirInRoot, | |
176 llvm::sys::path::relative_path(subdir.Path)); | |
177 ec = sys::fs::is_directory(SubdirInRoot, IsDirectory); | |
178 EXPECT_FALSE(ec); | |
179 ASSERT_TRUE(IsDirectory); | |
180 } | |
181 | |
182 TEST(FileCollectorTest, recordVFSAccesses) { | |
183 ScopedDir file_root("dir_root", true); | |
184 ScopedDir subdir(file_root + "/subdir"); | |
185 ScopedDir subdir2(file_root + "/subdir2"); | |
186 ScopedFile a(subdir2 + "/a"); | |
187 ScopedFile b(file_root + "/b"); | |
188 ScopedDir subdir3(file_root + "/subdir3"); | |
189 ScopedFile subdir3a(subdir3 + "/aa"); | |
190 ScopedDir subdir3b(subdir3 + "/subdirb"); | |
191 { | |
192 ScopedFile subdir3fileremoved(subdir3 + "/removed"); | |
193 } | |
194 | |
195 // Create file collector and add files. | |
196 ScopedDir root("copy_files_root", true); | |
197 std::string root_fs = root.Path.str(); | |
198 auto Collector = std::make_shared<TestingFileCollector>(root_fs, root_fs); | |
199 auto VFS = | |
200 FileCollector::createCollectorVFS(vfs::getRealFileSystem(), Collector); | |
201 VFS->status(a.Path); | |
202 EXPECT_TRUE(Collector->hasSeen(a.Path)); | |
203 | |
204 VFS->openFileForRead(b.Path); | |
205 EXPECT_TRUE(Collector->hasSeen(b.Path)); | |
206 | |
207 VFS->status(subdir.Path); | |
208 EXPECT_TRUE(Collector->hasSeen(subdir.Path)); | |
209 | |
210 #ifndef _WIN32 | |
211 std::error_code EC; | |
212 auto It = VFS->dir_begin(subdir3.Path, EC); | |
213 EXPECT_FALSE(EC); | |
214 EXPECT_TRUE(Collector->hasSeen(subdir3.Path)); | |
215 EXPECT_TRUE(Collector->hasSeen(subdir3a.Path)); | |
216 EXPECT_TRUE(Collector->hasSeen(subdir3b.Path)); | |
217 std::string RemovedFileName = (Twine(subdir3.Path) + "/removed").str(); | |
218 EXPECT_FALSE(Collector->hasSeen(RemovedFileName)); | |
219 #endif | |
220 } | |
221 | |
222 #ifndef _WIN32 | |
223 TEST(FileCollectorTest, Symlinks) { | |
224 // Root where the original files live. | |
225 ScopedDir file_root("file_root", true); | |
226 | |
227 // Create some files in the file root. | |
228 ScopedFile a(file_root + "/aaa"); | |
229 ScopedFile b(file_root + "/bbb"); | |
230 ScopedFile c(file_root + "/ccc"); | |
231 | |
232 // Create a directory foo with file ddd. | |
233 ScopedDir foo(file_root + "/foo"); | |
234 ScopedFile d(foo + "/ddd"); | |
235 | |
236 // Create a file eee in the foo's parent directory. | |
237 ScopedFile e(foo + "/../eee"); | |
238 | |
239 // Create a symlink bar pointing to foo. | |
240 ScopedLink symlink(file_root + "/foo", file_root + "/bar"); | |
241 | |
242 // Root where files are copied to. | |
243 ScopedDir reproducer_root("reproducer_root", true); | |
244 std::string root_fs = reproducer_root.Path.str(); | |
245 TestingFileCollector FileCollector(root_fs, root_fs); | |
246 | |
247 // Add all the files to the collector. | |
248 FileCollector.addFile(a.Path); | |
249 FileCollector.addFile(b.Path); | |
250 FileCollector.addFile(c.Path); | |
251 FileCollector.addFile(d.Path); | |
252 FileCollector.addFile(e.Path); | |
253 FileCollector.addFile(file_root + "/bar/ddd"); | |
254 | |
255 auto mapping = FileCollector.VFSWriter.getMappings(); | |
256 | |
257 { | |
258 // Make sure the common case works. | |
259 std::string vpath = (file_root + "/aaa").str(); | |
260 std::string rpath = (reproducer_root.Path + file_root.Path + "/aaa").str(); | |
261 printf("%s -> %s\n", vpath.c_str(), rpath.c_str()); | |
262 EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath))); | |
263 } | |
264 | |
265 { | |
266 // Make sure the virtual path points to the real source path. | |
267 std::string vpath = (file_root + "/bar/ddd").str(); | |
268 std::string rpath = | |
269 (reproducer_root.Path + file_root.Path + "/foo/ddd").str(); | |
270 printf("%s -> %s\n", vpath.c_str(), rpath.c_str()); | |
271 EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath))); | |
272 } | |
273 | |
274 { | |
275 // Make sure that .. is removed from the source path. | |
276 std::string vpath = (file_root + "/eee").str(); | |
277 std::string rpath = (reproducer_root.Path + file_root.Path + "/eee").str(); | |
278 printf("%s -> %s\n", vpath.c_str(), rpath.c_str()); | |
279 EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath))); | |
280 } | |
281 } | |
282 | |
283 TEST(FileCollectorTest, recordVFSSymlinkAccesses) { | |
284 ScopedDir file_root("dir_root", true); | |
285 ScopedFile a(file_root + "/a"); | |
286 ScopedLink symlink(file_root + "/a", file_root + "/b"); | |
287 | |
288 // Create file collector and add files. | |
289 ScopedDir root("copy_files_root", true); | |
290 std::string root_fs = root.Path.str(); | |
291 auto Collector = std::make_shared<TestingFileCollector>(root_fs, root_fs); | |
292 auto VFS = | |
293 FileCollector::createCollectorVFS(vfs::getRealFileSystem(), Collector); | |
294 SmallString<256> Output; | |
295 VFS->getRealPath(symlink.Path, Output); | |
296 EXPECT_TRUE(Collector->hasSeen(a.Path)); | |
297 EXPECT_TRUE(Collector->hasSeen(symlink.Path)); | |
298 } | |
299 #endif |