blob: 7abc549292e2b693dd459ba7ed42f529fb0fd548 [file] [log] [blame]
Ben Langmuirc8130a72014-02-20 21:59:23 +00001//===- unittests/Basic/VirtualFileSystem.cpp ---------------- VFS tests ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Basic/VirtualFileSystem.h"
Rafael Espindola71de0b62014-06-13 17:20:50 +000011#include "llvm/Support/Errc.h"
Ben Langmuird51ba0b2014-02-21 23:39:37 +000012#include "llvm/Support/MemoryBuffer.h"
Ben Langmuirc8130a72014-02-20 21:59:23 +000013#include "llvm/Support/Path.h"
Ben Langmuird51ba0b2014-02-21 23:39:37 +000014#include "llvm/Support/SourceMgr.h"
Ben Langmuirc8130a72014-02-20 21:59:23 +000015#include "gtest/gtest.h"
16#include <map>
Hans Wennborgdcfba332015-10-06 23:40:43 +000017
Ben Langmuirc8130a72014-02-20 21:59:23 +000018using namespace clang;
19using namespace llvm;
20using llvm::sys::fs::UniqueID;
21
22namespace {
Ben Langmuirf13302e2015-12-10 23:41:39 +000023struct DummyFile : public vfs::File {
24 vfs::Status S;
25 explicit DummyFile(vfs::Status S) : S(S) {}
26 llvm::ErrorOr<vfs::Status> status() override { return S; }
27 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
28 getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
29 bool IsVolatile) override {
30 llvm_unreachable("unimplemented");
31 }
32 virtual std::error_code close() override { return std::error_code(); }
33};
34
Ben Langmuirc8130a72014-02-20 21:59:23 +000035class DummyFileSystem : public vfs::FileSystem {
36 int FSID; // used to produce UniqueIDs
37 int FileID; // used to produce UniqueIDs
38 std::map<std::string, vfs::Status> FilesAndDirs;
39
40 static int getNextFSID() {
41 static int Count = 0;
42 return Count++;
43 }
44
45public:
46 DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
47
Fariborz Jahanian5afc8692014-10-01 16:56:40 +000048 ErrorOr<vfs::Status> status(const Twine &Path) override {
Ben Langmuirc8130a72014-02-20 21:59:23 +000049 std::map<std::string, vfs::Status>::iterator I =
Ben Langmuird51ba0b2014-02-21 23:39:37 +000050 FilesAndDirs.find(Path.str());
Ben Langmuirc8130a72014-02-20 21:59:23 +000051 if (I == FilesAndDirs.end())
Rafael Espindola71de0b62014-06-13 17:20:50 +000052 return make_error_code(llvm::errc::no_such_file_or_directory);
Ben Langmuirc8130a72014-02-20 21:59:23 +000053 return I->second;
54 }
Benjamin Kramera8857962014-10-26 22:44:13 +000055 ErrorOr<std::unique_ptr<vfs::File>>
56 openFileForRead(const Twine &Path) override {
Ben Langmuirf13302e2015-12-10 23:41:39 +000057 auto S = status(Path);
58 if (S)
59 return std::unique_ptr<vfs::File>(new DummyFile{*S});
60 return S.getError();
Ben Langmuirc8130a72014-02-20 21:59:23 +000061 }
Benjamin Kramer7708b2a2015-10-05 13:55:20 +000062 llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
63 return std::string();
64 }
65 std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
66 return std::error_code();
67 }
Ben Langmuirc8130a72014-02-20 21:59:23 +000068
Ben Langmuir740812b2014-06-24 19:37:16 +000069 struct DirIterImpl : public clang::vfs::detail::DirIterImpl {
70 std::map<std::string, vfs::Status> &FilesAndDirs;
71 std::map<std::string, vfs::Status>::iterator I;
72 std::string Path;
Ben Langmuir7c9f6c82014-06-25 20:25:40 +000073 bool isInPath(StringRef S) {
74 if (Path.size() < S.size() && S.find(Path) == 0) {
75 auto LastSep = S.find_last_of('/');
76 if (LastSep == Path.size() || LastSep == Path.size()-1)
77 return true;
78 }
79 return false;
80 }
Ben Langmuir740812b2014-06-24 19:37:16 +000081 DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
82 const Twine &_Path)
83 : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
84 Path(_Path.str()) {
85 for ( ; I != FilesAndDirs.end(); ++I) {
Ben Langmuir7c9f6c82014-06-25 20:25:40 +000086 if (isInPath(I->first)) {
Ben Langmuir740812b2014-06-24 19:37:16 +000087 CurrentEntry = I->second;
88 break;
89 }
90 }
91 }
92 std::error_code increment() override {
93 ++I;
94 for ( ; I != FilesAndDirs.end(); ++I) {
Ben Langmuir7c9f6c82014-06-25 20:25:40 +000095 if (isInPath(I->first)) {
Ben Langmuir740812b2014-06-24 19:37:16 +000096 CurrentEntry = I->second;
97 break;
98 }
99 }
100 if (I == FilesAndDirs.end())
101 CurrentEntry = vfs::Status();
102 return std::error_code();
103 }
104 };
105
106 vfs::directory_iterator dir_begin(const Twine &Dir,
107 std::error_code &EC) override {
108 return vfs::directory_iterator(
109 std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
110 }
111
Ben Langmuirc8130a72014-02-20 21:59:23 +0000112 void addEntry(StringRef Path, const vfs::Status &Status) {
113 FilesAndDirs[Path] = Status;
114 }
115
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000116 void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Benjamin Kramer268b51a2015-10-05 13:15:33 +0000117 vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0,
118 1024, sys::fs::file_type::regular_file, Perms);
Ben Langmuirc8130a72014-02-20 21:59:23 +0000119 addEntry(Path, S);
120 }
121
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000122 void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Benjamin Kramer268b51a2015-10-05 13:15:33 +0000123 vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0,
124 0, sys::fs::file_type::directory_file, Perms);
Ben Langmuirc8130a72014-02-20 21:59:23 +0000125 addEntry(Path, S);
126 }
127
128 void addSymlink(StringRef Path) {
Benjamin Kramer268b51a2015-10-05 13:15:33 +0000129 vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0,
130 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
Ben Langmuirc8130a72014-02-20 21:59:23 +0000131 addEntry(Path, S);
132 }
133};
134} // end anonymous namespace
135
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000136TEST(VirtualFileSystemTest, StatusQueries) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000137 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
Rafael Espindola8e650d72014-06-12 20:37:59 +0000138 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000139
140 D->addRegularFile("/foo");
141 Status = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000142 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000143 EXPECT_TRUE(Status->isStatusKnown());
144 EXPECT_FALSE(Status->isDirectory());
145 EXPECT_TRUE(Status->isRegularFile());
146 EXPECT_FALSE(Status->isSymlink());
147 EXPECT_FALSE(Status->isOther());
148 EXPECT_TRUE(Status->exists());
149
150 D->addDirectory("/bar");
151 Status = D->status("/bar");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000152 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000153 EXPECT_TRUE(Status->isStatusKnown());
154 EXPECT_TRUE(Status->isDirectory());
155 EXPECT_FALSE(Status->isRegularFile());
156 EXPECT_FALSE(Status->isSymlink());
157 EXPECT_FALSE(Status->isOther());
158 EXPECT_TRUE(Status->exists());
159
160 D->addSymlink("/baz");
161 Status = D->status("/baz");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000162 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000163 EXPECT_TRUE(Status->isStatusKnown());
164 EXPECT_FALSE(Status->isDirectory());
165 EXPECT_FALSE(Status->isRegularFile());
166 EXPECT_TRUE(Status->isSymlink());
167 EXPECT_FALSE(Status->isOther());
168 EXPECT_TRUE(Status->exists());
169
170 EXPECT_TRUE(Status->equivalent(*Status));
171 ErrorOr<vfs::Status> Status2 = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000172 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000173 EXPECT_FALSE(Status->equivalent(*Status2));
174}
175
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000176TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000177 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
Rafael Espindola8e650d72014-06-12 20:37:59 +0000178 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000179 EXPECT_FALSE(Status = D->status("/foo"));
180
181 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
182 EXPECT_FALSE(Status = O->status("/foo"));
183
184 D->addRegularFile("/foo");
185 Status = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000186 EXPECT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000187
Rafael Espindola8e650d72014-06-12 20:37:59 +0000188 ErrorOr<vfs::Status> Status2((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000189 Status2 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000190 EXPECT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000191 EXPECT_TRUE(Status->equivalent(*Status2));
192}
193
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000194TEST(VirtualFileSystemTest, OverlayFiles) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000195 IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem());
196 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
197 IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000198 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
199 new vfs::OverlayFileSystem(Base));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000200 O->pushOverlay(Middle);
201 O->pushOverlay(Top);
202
Rafael Espindola8e650d72014-06-12 20:37:59 +0000203 ErrorOr<vfs::Status> Status1((std::error_code())),
204 Status2((std::error_code())), Status3((std::error_code())),
205 StatusB((std::error_code())), StatusM((std::error_code())),
206 StatusT((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000207
208 Base->addRegularFile("/foo");
209 StatusB = Base->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000210 ASSERT_FALSE(StatusB.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000211 Status1 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000212 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000213 Middle->addRegularFile("/foo");
214 StatusM = Middle->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000215 ASSERT_FALSE(StatusM.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000216 Status2 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000217 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000218 Top->addRegularFile("/foo");
219 StatusT = Top->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000220 ASSERT_FALSE(StatusT.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000221 Status3 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000222 ASSERT_FALSE(Status3.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000223
224 EXPECT_TRUE(Status1->equivalent(*StatusB));
225 EXPECT_TRUE(Status2->equivalent(*StatusM));
226 EXPECT_TRUE(Status3->equivalent(*StatusT));
227
228 EXPECT_FALSE(Status1->equivalent(*Status2));
229 EXPECT_FALSE(Status2->equivalent(*Status3));
230 EXPECT_FALSE(Status1->equivalent(*Status3));
231}
232
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000233TEST(VirtualFileSystemTest, OverlayDirsNonMerged) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000234 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
235 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000236 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
237 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000238 O->pushOverlay(Upper);
239
240 Lower->addDirectory("/lower-only");
241 Upper->addDirectory("/upper-only");
242
243 // non-merged paths should be the same
244 ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000245 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000246 ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000247 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000248 EXPECT_TRUE(Status1->equivalent(*Status2));
249
250 Status1 = Upper->status("/upper-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000251 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000252 Status2 = O->status("/upper-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000253 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000254 EXPECT_TRUE(Status1->equivalent(*Status2));
255}
256
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000257TEST(VirtualFileSystemTest, MergedDirPermissions) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000258 // merged directories get the permissions of the upper dir
259 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
260 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000261 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
262 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000263 O->pushOverlay(Upper);
264
Rafael Espindola8e650d72014-06-12 20:37:59 +0000265 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000266 Lower->addDirectory("/both", sys::fs::owner_read);
267 Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
268 Status = O->status("/both");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000269 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000270 EXPECT_EQ(0740, Status->getPermissions());
271
272 // permissions (as usual) are not recursively applied
273 Lower->addRegularFile("/both/foo", sys::fs::owner_read);
274 Upper->addRegularFile("/both/bar", sys::fs::owner_write);
275 Status = O->status("/both/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000276 ASSERT_FALSE( Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000277 EXPECT_EQ(0400, Status->getPermissions());
278 Status = O->status("/both/bar");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000279 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000280 EXPECT_EQ(0200, Status->getPermissions());
281}
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000282
Ben Langmuir740812b2014-06-24 19:37:16 +0000283namespace {
284struct ScopedDir {
285 SmallString<128> Path;
286 ScopedDir(const Twine &Name, bool Unique=false) {
287 std::error_code EC;
288 if (Unique) {
289 EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
290 } else {
291 Path = Name.str();
292 EC = llvm::sys::fs::create_directory(Twine(Path));
293 }
294 if (EC)
295 Path = "";
296 EXPECT_FALSE(EC);
297 }
298 ~ScopedDir() {
299 if (Path != "")
300 EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
301 }
302 operator StringRef() { return Path.str(); }
303};
Hans Wennborgdcfba332015-10-06 23:40:43 +0000304} // end anonymous namespace
Ben Langmuir740812b2014-06-24 19:37:16 +0000305
306TEST(VirtualFileSystemTest, BasicRealFSIteration) {
307 ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
308 IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
309
310 std::error_code EC;
311 vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC);
312 ASSERT_FALSE(EC);
313 EXPECT_EQ(vfs::directory_iterator(), I); // empty directory is empty
314
315 ScopedDir _a(TestDirectory+"/a");
316 ScopedDir _ab(TestDirectory+"/a/b");
317 ScopedDir _c(TestDirectory+"/c");
318 ScopedDir _cd(TestDirectory+"/c/d");
319
320 I = FS->dir_begin(Twine(TestDirectory), EC);
321 ASSERT_FALSE(EC);
322 ASSERT_NE(vfs::directory_iterator(), I);
Ben Langmuirefb8b602014-06-24 21:08:13 +0000323 // Check either a or c, since we can't rely on the iteration order.
324 EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c"));
Ben Langmuir740812b2014-06-24 19:37:16 +0000325 I.increment(EC);
326 ASSERT_FALSE(EC);
327 ASSERT_NE(vfs::directory_iterator(), I);
Ben Langmuirefb8b602014-06-24 21:08:13 +0000328 EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c"));
Ben Langmuir740812b2014-06-24 19:37:16 +0000329 I.increment(EC);
330 EXPECT_EQ(vfs::directory_iterator(), I);
331}
332
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000333TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
334 ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
335 IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
336
337 std::error_code EC;
338 auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
339 ASSERT_FALSE(EC);
340 EXPECT_EQ(vfs::recursive_directory_iterator(), I); // empty directory is empty
341
342 ScopedDir _a(TestDirectory+"/a");
343 ScopedDir _ab(TestDirectory+"/a/b");
344 ScopedDir _c(TestDirectory+"/c");
345 ScopedDir _cd(TestDirectory+"/c/d");
346
347 I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
348 ASSERT_FALSE(EC);
349 ASSERT_NE(vfs::recursive_directory_iterator(), I);
350
351
352 std::vector<std::string> Contents;
353 for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
354 I.increment(EC)) {
355 Contents.push_back(I->getName());
356 }
357
358 // Check contents, which may be in any order
359 EXPECT_EQ(4U, Contents.size());
360 int Counts[4] = { 0, 0, 0, 0 };
361 for (const std::string &Name : Contents) {
362 ASSERT_FALSE(Name.empty());
363 int Index = Name[Name.size()-1] - 'a';
364 ASSERT_TRUE(Index >= 0 && Index < 4);
365 Counts[Index]++;
366 }
367 EXPECT_EQ(1, Counts[0]); // a
368 EXPECT_EQ(1, Counts[1]); // b
369 EXPECT_EQ(1, Counts[2]); // c
370 EXPECT_EQ(1, Counts[3]); // d
371}
372
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000373template <typename DirIter>
374static void checkContents(DirIter I, ArrayRef<StringRef> Expected) {
Ben Langmuir740812b2014-06-24 19:37:16 +0000375 std::error_code EC;
376 auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end();
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000377 for (DirIter E;
Ben Langmuir740812b2014-06-24 19:37:16 +0000378 !EC && I != E && ExpectedIter != ExpectedEnd;
379 I.increment(EC), ++ExpectedIter)
380 EXPECT_EQ(*ExpectedIter, I->getName());
381
382 EXPECT_EQ(ExpectedEnd, ExpectedIter);
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000383 EXPECT_EQ(DirIter(), I);
Ben Langmuir740812b2014-06-24 19:37:16 +0000384}
385
386TEST(VirtualFileSystemTest, OverlayIteration) {
387 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
388 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
389 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
390 new vfs::OverlayFileSystem(Lower));
391 O->pushOverlay(Upper);
392
393 std::error_code EC;
NAKAMURA Takumi4669bd42014-06-25 04:34:10 +0000394 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
Ben Langmuir740812b2014-06-24 19:37:16 +0000395
396 Lower->addRegularFile("/file1");
NAKAMURA Takumi4669bd42014-06-25 04:34:10 +0000397 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1"));
Ben Langmuir740812b2014-06-24 19:37:16 +0000398
399 Upper->addRegularFile("/file2");
Benjamin Kramer2a23e552016-01-10 10:45:19 +0000400 checkContents(O->dir_begin("/", EC), {"/file2", "/file1"});
Ben Langmuir740812b2014-06-24 19:37:16 +0000401
402 Lower->addDirectory("/dir1");
403 Lower->addRegularFile("/dir1/foo");
404 Upper->addDirectory("/dir2");
405 Upper->addRegularFile("/dir2/foo");
NAKAMURA Takumi4669bd42014-06-25 04:34:10 +0000406 checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo"));
Benjamin Kramer2a23e552016-01-10 10:45:19 +0000407 checkContents(O->dir_begin("/", EC), {"/dir2", "/file2", "/dir1", "/file1"});
Ben Langmuir740812b2014-06-24 19:37:16 +0000408}
409
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000410TEST(VirtualFileSystemTest, OverlayRecursiveIteration) {
411 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
412 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
413 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
414 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
415 new vfs::OverlayFileSystem(Lower));
416 O->pushOverlay(Middle);
417 O->pushOverlay(Upper);
418
419 std::error_code EC;
420 checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
421 ArrayRef<StringRef>());
422
423 Lower->addRegularFile("/file1");
424 checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
425 ArrayRef<StringRef>("/file1"));
426
427 Upper->addDirectory("/dir");
428 Upper->addRegularFile("/dir/file2");
Benjamin Kramer2a23e552016-01-10 10:45:19 +0000429 checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
430 {"/dir", "/dir/file2", "/file1"});
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000431
432 Lower->addDirectory("/dir1");
433 Lower->addRegularFile("/dir1/foo");
434 Lower->addDirectory("/dir1/a");
435 Lower->addRegularFile("/dir1/a/b");
436 Middle->addDirectory("/a");
437 Middle->addDirectory("/a/b");
438 Middle->addDirectory("/a/b/c");
439 Middle->addRegularFile("/a/b/c/d");
440 Middle->addRegularFile("/hiddenByUp");
441 Upper->addDirectory("/dir2");
442 Upper->addRegularFile("/dir2/foo");
443 Upper->addRegularFile("/hiddenByUp");
444 checkContents(vfs::recursive_directory_iterator(*O, "/dir2", EC),
445 ArrayRef<StringRef>("/dir2/foo"));
Benjamin Kramer2a23e552016-01-10 10:45:19 +0000446 checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
447 {"/dir", "/dir/file2", "/dir2", "/dir2/foo", "/hiddenByUp",
448 "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/dir1", "/dir1/a",
449 "/dir1/a/b", "/dir1/foo", "/file1"});
Ben Langmuir7c9f6c82014-06-25 20:25:40 +0000450}
451
Ben Langmuir740812b2014-06-24 19:37:16 +0000452TEST(VirtualFileSystemTest, ThreeLevelIteration) {
453 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
454 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
455 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
456 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
457 new vfs::OverlayFileSystem(Lower));
458 O->pushOverlay(Middle);
459 O->pushOverlay(Upper);
460
461 std::error_code EC;
NAKAMURA Takumi4669bd42014-06-25 04:34:10 +0000462 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
Ben Langmuir740812b2014-06-24 19:37:16 +0000463
464 Middle->addRegularFile("/file2");
NAKAMURA Takumi4669bd42014-06-25 04:34:10 +0000465 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2"));
Ben Langmuir740812b2014-06-24 19:37:16 +0000466
467 Lower->addRegularFile("/file1");
468 Upper->addRegularFile("/file3");
Benjamin Kramer2a23e552016-01-10 10:45:19 +0000469 checkContents(O->dir_begin("/", EC), {"/file3", "/file2", "/file1"});
Ben Langmuir740812b2014-06-24 19:37:16 +0000470}
471
472TEST(VirtualFileSystemTest, HiddenInIteration) {
473 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
474 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
475 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
476 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
477 new vfs::OverlayFileSystem(Lower));
478 O->pushOverlay(Middle);
479 O->pushOverlay(Upper);
480
481 std::error_code EC;
482 Lower->addRegularFile("/onlyInLow", sys::fs::owner_read);
483 Lower->addRegularFile("/hiddenByMid", sys::fs::owner_read);
484 Lower->addRegularFile("/hiddenByUp", sys::fs::owner_read);
485 Middle->addRegularFile("/onlyInMid", sys::fs::owner_write);
486 Middle->addRegularFile("/hiddenByMid", sys::fs::owner_write);
487 Middle->addRegularFile("/hiddenByUp", sys::fs::owner_write);
488 Upper->addRegularFile("/onlyInUp", sys::fs::owner_all);
489 Upper->addRegularFile("/hiddenByUp", sys::fs::owner_all);
Benjamin Kramer2a23e552016-01-10 10:45:19 +0000490 checkContents(
491 O->dir_begin("/", EC),
492 {"/hiddenByUp", "/onlyInUp", "/hiddenByMid", "/onlyInMid", "/onlyInLow"});
Ben Langmuir740812b2014-06-24 19:37:16 +0000493
494 // Make sure we get the top-most entry
Ben Langmuirefb8b602014-06-24 21:08:13 +0000495 {
496 std::error_code EC;
497 vfs::directory_iterator I = O->dir_begin("/", EC), E;
498 for ( ; !EC && I != E; I.increment(EC))
499 if (I->getName() == "/hiddenByUp")
500 break;
501 ASSERT_NE(E, I);
502 EXPECT_EQ(sys::fs::owner_all, I->getPermissions());
503 }
504 {
505 std::error_code EC;
506 vfs::directory_iterator I = O->dir_begin("/", EC), E;
507 for ( ; !EC && I != E; I.increment(EC))
508 if (I->getName() == "/hiddenByMid")
509 break;
510 ASSERT_NE(E, I);
511 EXPECT_EQ(sys::fs::owner_write, I->getPermissions());
512 }
Ben Langmuir740812b2014-06-24 19:37:16 +0000513}
514
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000515class InMemoryFileSystemTest : public ::testing::Test {
516protected:
517 clang::vfs::InMemoryFileSystem FS;
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000518 clang::vfs::InMemoryFileSystem NormalizedFS;
519
520 InMemoryFileSystemTest()
521 : FS(/*UseNormalizedPaths=*/false),
522 NormalizedFS(/*UseNormalizedPaths=*/true) {}
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000523};
524
525TEST_F(InMemoryFileSystemTest, IsEmpty) {
526 auto Stat = FS.status("/a");
Rafael Espindolab7ab1872015-10-05 20:20:50 +0000527 ASSERT_EQ(Stat.getError(),errc::no_such_file_or_directory) << FS.toString();
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000528 Stat = FS.status("/");
Rafael Espindolab7ab1872015-10-05 20:20:50 +0000529 ASSERT_EQ(Stat.getError(), errc::no_such_file_or_directory) << FS.toString();
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000530}
531
532TEST_F(InMemoryFileSystemTest, WindowsPath) {
533 FS.addFile("c:/windows/system128/foo.cpp", 0, MemoryBuffer::getMemBuffer(""));
534 auto Stat = FS.status("c:");
NAKAMURA Takumi4c33a1a2015-10-06 12:16:27 +0000535#if !defined(_WIN32)
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000536 ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
NAKAMURA Takumi4c33a1a2015-10-06 12:16:27 +0000537#endif
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000538 Stat = FS.status("c:/windows/system128/foo.cpp");
539 ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
540 FS.addFile("d:/windows/foo.cpp", 0, MemoryBuffer::getMemBuffer(""));
541 Stat = FS.status("d:/windows/foo.cpp");
542 ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
543}
544
545TEST_F(InMemoryFileSystemTest, OverlayFile) {
546 FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000547 NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000548 auto Stat = FS.status("/");
549 ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000550 Stat = FS.status("/.");
551 ASSERT_FALSE(Stat);
552 Stat = NormalizedFS.status("/.");
553 ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000554 Stat = FS.status("/a");
555 ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
556 ASSERT_EQ("/a", Stat->getName());
557}
558
Benjamin Kramer2e2351a2015-10-06 10:04:08 +0000559TEST_F(InMemoryFileSystemTest, OverlayFileNoOwn) {
560 auto Buf = MemoryBuffer::getMemBuffer("a");
561 FS.addFileNoOwn("/a", 0, Buf.get());
562 auto Stat = FS.status("/a");
563 ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
564 ASSERT_EQ("/a", Stat->getName());
565}
566
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000567TEST_F(InMemoryFileSystemTest, OpenFileForRead) {
568 FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000569 FS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
570 FS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
571 NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
572 NormalizedFS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
573 NormalizedFS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000574 auto File = FS.openFileForRead("/a");
575 ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
576 File = FS.openFileForRead("/a"); // Open again.
577 ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000578 File = NormalizedFS.openFileForRead("/././a"); // Open again.
579 ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000580 File = FS.openFileForRead("/");
Rafael Espindolab7ab1872015-10-05 20:20:50 +0000581 ASSERT_EQ(File.getError(), errc::invalid_argument) << FS.toString();
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000582 File = FS.openFileForRead("/b");
Rafael Espindolab7ab1872015-10-05 20:20:50 +0000583 ASSERT_EQ(File.getError(), errc::no_such_file_or_directory) << FS.toString();
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000584 File = FS.openFileForRead("./c");
585 ASSERT_FALSE(File);
586 File = FS.openFileForRead("e/../d");
587 ASSERT_FALSE(File);
588 File = NormalizedFS.openFileForRead("./c");
Benjamin Kramerd5e0b582015-10-07 08:32:50 +0000589 ASSERT_EQ("c", (*(*File)->getBuffer("ignored"))->getBuffer());
Benjamin Kramer71ce3762015-10-12 16:16:39 +0000590 File = NormalizedFS.openFileForRead("e/../d");
591 ASSERT_EQ("d", (*(*File)->getBuffer("ignored"))->getBuffer());
592}
593
594TEST_F(InMemoryFileSystemTest, DuplicatedFile) {
595 ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")));
596 ASSERT_FALSE(FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("a")));
597 ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")));
598 ASSERT_FALSE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("b")));
Benjamin Kramera25dcfd2015-10-05 13:55:14 +0000599}
600
601TEST_F(InMemoryFileSystemTest, DirectoryIteration) {
602 FS.addFile("/a", 0, MemoryBuffer::getMemBuffer(""));
603 FS.addFile("/b/c", 0, MemoryBuffer::getMemBuffer(""));
604
605 std::error_code EC;
606 vfs::directory_iterator I = FS.dir_begin("/", EC);
607 ASSERT_FALSE(EC);
608 ASSERT_EQ("/a", I->getName());
609 I.increment(EC);
610 ASSERT_FALSE(EC);
611 ASSERT_EQ("/b", I->getName());
612 I.increment(EC);
613 ASSERT_FALSE(EC);
614 ASSERT_EQ(vfs::directory_iterator(), I);
615
616 I = FS.dir_begin("/b", EC);
617 ASSERT_FALSE(EC);
618 ASSERT_EQ("/b/c", I->getName());
619 I.increment(EC);
620 ASSERT_FALSE(EC);
621 ASSERT_EQ(vfs::directory_iterator(), I);
622}
623
Benjamin Kramer1b8dbe32015-10-06 14:45:16 +0000624TEST_F(InMemoryFileSystemTest, WorkingDirectory) {
625 FS.setCurrentWorkingDirectory("/b");
626 FS.addFile("c", 0, MemoryBuffer::getMemBuffer(""));
627
628 auto Stat = FS.status("/b/c");
629 ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
630 ASSERT_EQ("c", Stat->getName());
631 ASSERT_EQ("/b", *FS.getCurrentWorkingDirectory());
632
633 Stat = FS.status("c");
634 ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
Benjamin Kramere9e76072016-01-09 16:33:16 +0000635
Benjamin Kramer730338b2016-01-10 10:36:59 +0000636 auto ReplaceBackslashes = [](std::string S) {
637 std::replace(S.begin(), S.end(), '\\', '/');
638 return S;
639 };
Benjamin Kramere9e76072016-01-09 16:33:16 +0000640 NormalizedFS.setCurrentWorkingDirectory("/b/c");
641 NormalizedFS.setCurrentWorkingDirectory(".");
Benjamin Kramer730338b2016-01-10 10:36:59 +0000642 ASSERT_EQ("/b/c", ReplaceBackslashes(
643 NormalizedFS.getCurrentWorkingDirectory().get()));
Benjamin Kramere9e76072016-01-09 16:33:16 +0000644 NormalizedFS.setCurrentWorkingDirectory("..");
Benjamin Kramer730338b2016-01-10 10:36:59 +0000645 ASSERT_EQ("/b", ReplaceBackslashes(
646 NormalizedFS.getCurrentWorkingDirectory().get()));
Benjamin Kramer1b8dbe32015-10-06 14:45:16 +0000647}
648
Ben Langmuir93853232014-03-05 21:32:20 +0000649// NOTE: in the tests below, we use '//root/' as our root directory, since it is
650// a legal *absolute* path on Windows as well as *nix.
Ben Langmuir97882e72014-02-24 20:56:37 +0000651class VFSFromYAMLTest : public ::testing::Test {
652public:
653 int NumDiagnostics;
Ben Langmuir93853232014-03-05 21:32:20 +0000654
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000655 void SetUp() override { NumDiagnostics = 0; }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000656
Ben Langmuir97882e72014-02-24 20:56:37 +0000657 static void CountingDiagHandler(const SMDiagnostic &, void *Context) {
658 VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context);
659 ++Test->NumDiagnostics;
660 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000661
Ben Langmuir97882e72014-02-24 20:56:37 +0000662 IntrusiveRefCntPtr<vfs::FileSystem>
663 getFromYAMLRawString(StringRef Content,
664 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +0000665 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(Content);
Rafael Espindola91ac8df2014-08-17 23:27:13 +0000666 return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, this,
667 ExternalFS);
Ben Langmuir97882e72014-02-24 20:56:37 +0000668 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000669
Ben Langmuir97882e72014-02-24 20:56:37 +0000670 IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString(
671 StringRef Content,
672 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) {
673 std::string VersionPlusContent("{\n 'version':0,\n");
674 VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
675 return getFromYAMLRawString(VersionPlusContent, ExternalFS);
676 }
Ben Langmuir97882e72014-02-24 20:56:37 +0000677};
678
679TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000680 IntrusiveRefCntPtr<vfs::FileSystem> FS;
681 FS = getFromYAMLString("");
Alp Tokerf994cef2014-07-05 03:08:06 +0000682 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000683 FS = getFromYAMLString("[]");
Alp Tokerf994cef2014-07-05 03:08:06 +0000684 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000685 FS = getFromYAMLString("'string'");
Alp Tokerf994cef2014-07-05 03:08:06 +0000686 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000687 EXPECT_EQ(3, NumDiagnostics);
688}
689
Ben Langmuir97882e72014-02-24 20:56:37 +0000690TEST_F(VFSFromYAMLTest, MappedFiles) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000691 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000692 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000693 IntrusiveRefCntPtr<vfs::FileSystem> FS =
694 getFromYAMLString("{ 'roots': [\n"
695 "{\n"
696 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000697 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000698 " 'contents': [ {\n"
699 " 'type': 'file',\n"
700 " 'name': 'file1',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000701 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000702 " },\n"
703 " {\n"
704 " 'type': 'file',\n"
705 " 'name': 'file2',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000706 " 'external-contents': '//root/foo/b'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000707 " }\n"
708 " ]\n"
709 "}\n"
710 "]\n"
711 "}",
712 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000713 ASSERT_TRUE(FS.get() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000714
715 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
716 new vfs::OverlayFileSystem(Lower));
717 O->pushOverlay(FS);
718
719 // file
Ben Langmuir93853232014-03-05 21:32:20 +0000720 ErrorOr<vfs::Status> S = O->status("//root/file1");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000721 ASSERT_FALSE(S.getError());
Ben Langmuir93853232014-03-05 21:32:20 +0000722 EXPECT_EQ("//root/foo/bar/a", S->getName());
Ben Langmuirf13302e2015-12-10 23:41:39 +0000723 EXPECT_TRUE(S->IsVFSMapped);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000724
Ben Langmuir93853232014-03-05 21:32:20 +0000725 ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
726 EXPECT_EQ("//root/foo/bar/a", SLower->getName());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000727 EXPECT_TRUE(S->equivalent(*SLower));
Ben Langmuirf13302e2015-12-10 23:41:39 +0000728 EXPECT_FALSE(SLower->IsVFSMapped);
729
730 // file after opening
731 auto OpenedF = O->openFileForRead("//root/file1");
732 ASSERT_FALSE(OpenedF.getError());
733 auto OpenedS = (*OpenedF)->status();
734 ASSERT_FALSE(OpenedS.getError());
735 EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
736 EXPECT_TRUE(OpenedS->IsVFSMapped);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000737
738 // directory
Ben Langmuir93853232014-03-05 21:32:20 +0000739 S = O->status("//root/");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000740 ASSERT_FALSE(S.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000741 EXPECT_TRUE(S->isDirectory());
Ben Langmuir93853232014-03-05 21:32:20 +0000742 EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000743
744 // broken mapping
Rafael Espindola71de0b62014-06-13 17:20:50 +0000745 EXPECT_EQ(O->status("//root/file2").getError(),
746 llvm::errc::no_such_file_or_directory);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000747 EXPECT_EQ(0, NumDiagnostics);
748}
749
Ben Langmuir97882e72014-02-24 20:56:37 +0000750TEST_F(VFSFromYAMLTest, CaseInsensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000751 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000752 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000753 IntrusiveRefCntPtr<vfs::FileSystem> FS =
754 getFromYAMLString("{ 'case-sensitive': 'false',\n"
755 " 'roots': [\n"
756 "{\n"
757 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000758 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000759 " 'contents': [ {\n"
760 " 'type': 'file',\n"
761 " 'name': 'XX',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000762 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000763 " }\n"
764 " ]\n"
765 "}]}",
766 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000767 ASSERT_TRUE(FS.get() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000768
769 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
770 new vfs::OverlayFileSystem(Lower));
771 O->pushOverlay(FS);
772
Ben Langmuir93853232014-03-05 21:32:20 +0000773 ErrorOr<vfs::Status> S = O->status("//root/XX");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000774 ASSERT_FALSE(S.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000775
Ben Langmuir93853232014-03-05 21:32:20 +0000776 ErrorOr<vfs::Status> SS = O->status("//root/xx");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000777 ASSERT_FALSE(SS.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000778 EXPECT_TRUE(S->equivalent(*SS));
Ben Langmuir93853232014-03-05 21:32:20 +0000779 SS = O->status("//root/xX");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000780 EXPECT_TRUE(S->equivalent(*SS));
Ben Langmuir93853232014-03-05 21:32:20 +0000781 SS = O->status("//root/Xx");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000782 EXPECT_TRUE(S->equivalent(*SS));
783 EXPECT_EQ(0, NumDiagnostics);
784}
785
Ben Langmuir97882e72014-02-24 20:56:37 +0000786TEST_F(VFSFromYAMLTest, CaseSensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000787 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000788 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000789 IntrusiveRefCntPtr<vfs::FileSystem> FS =
790 getFromYAMLString("{ 'case-sensitive': 'true',\n"
791 " 'roots': [\n"
792 "{\n"
793 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000794 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000795 " 'contents': [ {\n"
796 " 'type': 'file',\n"
797 " 'name': 'XX',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000798 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000799 " }\n"
800 " ]\n"
801 "}]}",
802 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000803 ASSERT_TRUE(FS.get() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000804
805 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
806 new vfs::OverlayFileSystem(Lower));
807 O->pushOverlay(FS);
808
Ben Langmuir93853232014-03-05 21:32:20 +0000809 ErrorOr<vfs::Status> SS = O->status("//root/xx");
Rafael Espindola71de0b62014-06-13 17:20:50 +0000810 EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
Ben Langmuir93853232014-03-05 21:32:20 +0000811 SS = O->status("//root/xX");
Rafael Espindola71de0b62014-06-13 17:20:50 +0000812 EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
Ben Langmuir93853232014-03-05 21:32:20 +0000813 SS = O->status("//root/Xx");
Rafael Espindola71de0b62014-06-13 17:20:50 +0000814 EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000815 EXPECT_EQ(0, NumDiagnostics);
816}
817
Ben Langmuir97882e72014-02-24 20:56:37 +0000818TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000819 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
820
821 // invalid YAML at top-level
822 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000823 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000824 // invalid YAML in roots
825 FS = getFromYAMLString("{ 'roots':[}", Lower);
826 // invalid YAML in directory
827 FS = getFromYAMLString(
828 "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
829 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000830 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000831
832 // invalid configuration
833 FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000834 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000835 FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000836 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000837
838 // invalid roots
839 FS = getFromYAMLString("{ 'roots':'' }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000840 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000841 FS = getFromYAMLString("{ 'roots':{} }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000842 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000843
844 // invalid entries
845 FS = getFromYAMLString(
846 "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000847 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000848 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
849 "'external-contents': 'other' }",
850 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000851 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000852 FS = getFromYAMLString(
853 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
854 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000855 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000856 FS = getFromYAMLString(
857 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
858 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000859 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000860 FS = getFromYAMLString(
861 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
862 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000863 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000864 FS = getFromYAMLString(
865 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
866 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000867 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000868 FS = getFromYAMLString(
869 "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
870 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000871 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000872
873 // missing mandatory fields
874 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000875 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000876 FS = getFromYAMLString(
877 "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000878 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000879 FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000880 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000881
882 // duplicate keys
883 FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000884 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000885 FS = getFromYAMLString(
886 "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
887 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000888 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000889 FS =
890 getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
891 "'external-contents':'blah' } ] }",
892 Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000893 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000894
895 // missing version
896 FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000897 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000898
899 // bad version number
900 FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000901 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000902 FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000903 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000904 FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000905 EXPECT_EQ(nullptr, FS.get());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000906 EXPECT_EQ(24, NumDiagnostics);
907}
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000908
Ben Langmuirb59cf672014-02-27 00:25:12 +0000909TEST_F(VFSFromYAMLTest, UseExternalName) {
910 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000911 Lower->addRegularFile("//root/external/file");
Ben Langmuirb59cf672014-02-27 00:25:12 +0000912
913 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
914 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000915 " { 'type': 'file', 'name': '//root/A',\n"
916 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000917 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000918 " { 'type': 'file', 'name': '//root/B',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000919 " 'use-external-name': true,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000920 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000921 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000922 " { 'type': 'file', 'name': '//root/C',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000923 " 'use-external-name': false,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000924 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000925 " }\n"
926 "] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000927 ASSERT_TRUE(nullptr != FS.get());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000928
929 // default true
Ben Langmuir93853232014-03-05 21:32:20 +0000930 EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000931 // explicit
Ben Langmuir93853232014-03-05 21:32:20 +0000932 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
933 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000934
935 // global configuration
936 FS = getFromYAMLString(
937 "{ 'use-external-names': false,\n"
938 " 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000939 " { 'type': 'file', 'name': '//root/A',\n"
940 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000941 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000942 " { 'type': 'file', 'name': '//root/B',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000943 " 'use-external-name': true,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000944 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000945 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000946 " { 'type': 'file', 'name': '//root/C',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000947 " 'use-external-name': false,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000948 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000949 " }\n"
950 "] }", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000951 ASSERT_TRUE(nullptr != FS.get());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000952
953 // default
Ben Langmuir93853232014-03-05 21:32:20 +0000954 EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000955 // explicit
Ben Langmuir93853232014-03-05 21:32:20 +0000956 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
957 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000958}
959
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000960TEST_F(VFSFromYAMLTest, MultiComponentPath) {
961 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000962 Lower->addRegularFile("//root/other");
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000963
964 // file in roots
965 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
966 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000967 " { 'type': 'file', 'name': '//root/path/to/file',\n"
968 " 'external-contents': '//root/other' }]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000969 "}", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000970 ASSERT_TRUE(nullptr != FS.get());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000971 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
972 EXPECT_FALSE(FS->status("//root/path/to").getError());
973 EXPECT_FALSE(FS->status("//root/path").getError());
974 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000975
976 // at the start
977 FS = getFromYAMLString(
978 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000979 " { 'type': 'directory', 'name': '//root/path/to',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000980 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000981 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000982 "}", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000983 ASSERT_TRUE(nullptr != FS.get());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000984 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
985 EXPECT_FALSE(FS->status("//root/path/to").getError());
986 EXPECT_FALSE(FS->status("//root/path").getError());
987 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000988
989 // at the end
990 FS = getFromYAMLString(
991 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000992 " { 'type': 'directory', 'name': '//root/',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000993 " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000994 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000995 "}", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +0000996 ASSERT_TRUE(nullptr != FS.get());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000997 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
998 EXPECT_FALSE(FS->status("//root/path/to").getError());
999 EXPECT_FALSE(FS->status("//root/path").getError());
1000 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +00001001}
1002
1003TEST_F(VFSFromYAMLTest, TrailingSlashes) {
1004 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +00001005 Lower->addRegularFile("//root/other");
Ben Langmuir47ff9ab2014-02-25 04:34:14 +00001006
1007 // file in roots
1008 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
1009 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +00001010 " { 'type': 'directory', 'name': '//root/path/to////',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +00001011 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +00001012 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +00001013 "}", Lower);
Alp Tokerf994cef2014-07-05 03:08:06 +00001014 ASSERT_TRUE(nullptr != FS.get());
Rafael Espindola3ae06202014-05-31 03:20:52 +00001015 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
1016 EXPECT_FALSE(FS->status("//root/path/to").getError());
1017 EXPECT_FALSE(FS->status("//root/path").getError());
1018 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +00001019}
Ben Langmuir740812b2014-06-24 19:37:16 +00001020
1021TEST_F(VFSFromYAMLTest, DirectoryIteration) {
1022 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
1023 Lower->addDirectory("//root/");
1024 Lower->addDirectory("//root/foo");
1025 Lower->addDirectory("//root/foo/bar");
1026 Lower->addRegularFile("//root/foo/bar/a");
1027 Lower->addRegularFile("//root/foo/bar/b");
1028 Lower->addRegularFile("//root/file3");
1029 IntrusiveRefCntPtr<vfs::FileSystem> FS =
1030 getFromYAMLString("{ 'use-external-names': false,\n"
1031 " 'roots': [\n"
1032 "{\n"
1033 " 'type': 'directory',\n"
1034 " 'name': '//root/',\n"
1035 " 'contents': [ {\n"
1036 " 'type': 'file',\n"
1037 " 'name': 'file1',\n"
1038 " 'external-contents': '//root/foo/bar/a'\n"
1039 " },\n"
1040 " {\n"
1041 " 'type': 'file',\n"
1042 " 'name': 'file2',\n"
1043 " 'external-contents': '//root/foo/bar/b'\n"
1044 " }\n"
1045 " ]\n"
1046 "}\n"
1047 "]\n"
1048 "}",
1049 Lower);
Hans Wennborgdcfba332015-10-06 23:40:43 +00001050 ASSERT_TRUE(FS.get() != nullptr);
Ben Langmuir740812b2014-06-24 19:37:16 +00001051
1052 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
1053 new vfs::OverlayFileSystem(Lower));
1054 O->pushOverlay(FS);
1055
1056 std::error_code EC;
Benjamin Kramer2a23e552016-01-10 10:45:19 +00001057 checkContents(O->dir_begin("//root/", EC),
1058 {"//root/file1", "//root/file2", "//root/file3", "//root/foo"});
Ben Langmuir740812b2014-06-24 19:37:16 +00001059
Benjamin Kramer2a23e552016-01-10 10:45:19 +00001060 checkContents(O->dir_begin("//root/foo/bar", EC),
1061 {"//root/foo/bar/a", "//root/foo/bar/b"});
Ben Langmuir740812b2014-06-24 19:37:16 +00001062}