blob: 367e79492a8f51ca56aaaab4257cc33150e27d23 [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"
Ben Langmuird51ba0b2014-02-21 23:39:37 +000011#include "llvm/Support/MemoryBuffer.h"
Ben Langmuirc8130a72014-02-20 21:59:23 +000012#include "llvm/Support/Path.h"
Ben Langmuird51ba0b2014-02-21 23:39:37 +000013#include "llvm/Support/SourceMgr.h"
Ben Langmuirc8130a72014-02-20 21:59:23 +000014#include "gtest/gtest.h"
15#include <map>
16using namespace clang;
17using namespace llvm;
18using llvm::sys::fs::UniqueID;
19
20namespace {
21class DummyFileSystem : public vfs::FileSystem {
22 int FSID; // used to produce UniqueIDs
23 int FileID; // used to produce UniqueIDs
24 std::map<std::string, vfs::Status> FilesAndDirs;
25
26 static int getNextFSID() {
27 static int Count = 0;
28 return Count++;
29 }
30
31public:
32 DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
33
34 ErrorOr<vfs::Status> status(const Twine &Path) {
35 std::map<std::string, vfs::Status>::iterator I =
Ben Langmuird51ba0b2014-02-21 23:39:37 +000036 FilesAndDirs.find(Path.str());
Ben Langmuirc8130a72014-02-20 21:59:23 +000037 if (I == FilesAndDirs.end())
38 return error_code(errc::no_such_file_or_directory, posix_category());
39 return I->second;
40 }
41 error_code openFileForRead(const Twine &Path, OwningPtr<vfs::File> &Result) {
42 llvm_unreachable("unimplemented");
43 }
44 error_code getBufferForFile(const Twine &Name,
45 OwningPtr<MemoryBuffer> &Result,
46 int64_t FileSize = -1,
47 bool RequiresNullTerminator = true) {
48 llvm_unreachable("unimplemented");
49 }
50
51 void addEntry(StringRef Path, const vfs::Status &Status) {
52 FilesAndDirs[Path] = Status;
53 }
54
Ben Langmuird51ba0b2014-02-21 23:39:37 +000055 void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000056 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
57 0, 0, 1024, sys::fs::file_type::regular_file, Perms);
58 addEntry(Path, S);
59 }
60
Ben Langmuird51ba0b2014-02-21 23:39:37 +000061 void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000062 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
63 0, 0, 0, sys::fs::file_type::directory_file, Perms);
64 addEntry(Path, S);
65 }
66
67 void addSymlink(StringRef Path) {
68 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
69 0, 0, 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
70 addEntry(Path, S);
71 }
72};
73} // end anonymous namespace
74
Ben Langmuird51ba0b2014-02-21 23:39:37 +000075TEST(VirtualFileSystemTest, StatusQueries) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000076 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
77 ErrorOr<vfs::Status> Status((error_code()));
78
79 D->addRegularFile("/foo");
80 Status = D->status("/foo");
81 ASSERT_EQ(errc::success, Status.getError());
82 EXPECT_TRUE(Status->isStatusKnown());
83 EXPECT_FALSE(Status->isDirectory());
84 EXPECT_TRUE(Status->isRegularFile());
85 EXPECT_FALSE(Status->isSymlink());
86 EXPECT_FALSE(Status->isOther());
87 EXPECT_TRUE(Status->exists());
88
89 D->addDirectory("/bar");
90 Status = D->status("/bar");
91 ASSERT_EQ(errc::success, Status.getError());
92 EXPECT_TRUE(Status->isStatusKnown());
93 EXPECT_TRUE(Status->isDirectory());
94 EXPECT_FALSE(Status->isRegularFile());
95 EXPECT_FALSE(Status->isSymlink());
96 EXPECT_FALSE(Status->isOther());
97 EXPECT_TRUE(Status->exists());
98
99 D->addSymlink("/baz");
100 Status = D->status("/baz");
101 ASSERT_EQ(errc::success, Status.getError());
102 EXPECT_TRUE(Status->isStatusKnown());
103 EXPECT_FALSE(Status->isDirectory());
104 EXPECT_FALSE(Status->isRegularFile());
105 EXPECT_TRUE(Status->isSymlink());
106 EXPECT_FALSE(Status->isOther());
107 EXPECT_TRUE(Status->exists());
108
109 EXPECT_TRUE(Status->equivalent(*Status));
110 ErrorOr<vfs::Status> Status2 = D->status("/foo");
111 ASSERT_EQ(errc::success, Status2.getError());
112 EXPECT_FALSE(Status->equivalent(*Status2));
113}
114
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000115TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000116 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
117 ErrorOr<vfs::Status> Status((error_code()));
118 EXPECT_FALSE(Status = D->status("/foo"));
119
120 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
121 EXPECT_FALSE(Status = O->status("/foo"));
122
123 D->addRegularFile("/foo");
124 Status = D->status("/foo");
125 EXPECT_EQ(errc::success, Status.getError());
126
127 ErrorOr<vfs::Status> Status2((error_code()));
128 Status2 = O->status("/foo");
129 EXPECT_EQ(errc::success, Status2.getError());
130 EXPECT_TRUE(Status->equivalent(*Status2));
131}
132
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000133TEST(VirtualFileSystemTest, OverlayFiles) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000134 IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem());
135 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
136 IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000137 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
138 new vfs::OverlayFileSystem(Base));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000139 O->pushOverlay(Middle);
140 O->pushOverlay(Top);
141
142 ErrorOr<vfs::Status> Status1((error_code())), Status2((error_code())),
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000143 Status3((error_code())), StatusB((error_code())), StatusM((error_code())),
144 StatusT((error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000145
146 Base->addRegularFile("/foo");
147 StatusB = Base->status("/foo");
148 ASSERT_EQ(errc::success, StatusB.getError());
149 Status1 = O->status("/foo");
150 ASSERT_EQ(errc::success, Status1.getError());
151 Middle->addRegularFile("/foo");
152 StatusM = Middle->status("/foo");
153 ASSERT_EQ(errc::success, StatusM.getError());
154 Status2 = O->status("/foo");
155 ASSERT_EQ(errc::success, Status2.getError());
156 Top->addRegularFile("/foo");
157 StatusT = Top->status("/foo");
158 ASSERT_EQ(errc::success, StatusT.getError());
159 Status3 = O->status("/foo");
160 ASSERT_EQ(errc::success, Status3.getError());
161
162 EXPECT_TRUE(Status1->equivalent(*StatusB));
163 EXPECT_TRUE(Status2->equivalent(*StatusM));
164 EXPECT_TRUE(Status3->equivalent(*StatusT));
165
166 EXPECT_FALSE(Status1->equivalent(*Status2));
167 EXPECT_FALSE(Status2->equivalent(*Status3));
168 EXPECT_FALSE(Status1->equivalent(*Status3));
169}
170
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000171TEST(VirtualFileSystemTest, OverlayDirsNonMerged) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000172 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
173 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000174 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
175 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000176 O->pushOverlay(Upper);
177
178 Lower->addDirectory("/lower-only");
179 Upper->addDirectory("/upper-only");
180
181 // non-merged paths should be the same
182 ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
183 ASSERT_EQ(errc::success, Status1.getError());
184 ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
185 ASSERT_EQ(errc::success, Status2.getError());
186 EXPECT_TRUE(Status1->equivalent(*Status2));
187
188 Status1 = Upper->status("/upper-only");
189 ASSERT_EQ(errc::success, Status1.getError());
190 Status2 = O->status("/upper-only");
191 ASSERT_EQ(errc::success, Status2.getError());
192 EXPECT_TRUE(Status1->equivalent(*Status2));
193}
194
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000195TEST(VirtualFileSystemTest, MergedDirPermissions) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000196 // merged directories get the permissions of the upper dir
197 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
198 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000199 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
200 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000201 O->pushOverlay(Upper);
202
203 ErrorOr<vfs::Status> Status((error_code()));
204 Lower->addDirectory("/both", sys::fs::owner_read);
205 Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
206 Status = O->status("/both");
207 ASSERT_EQ(errc::success, Status.getError());
208 EXPECT_EQ(0740, Status->getPermissions());
209
210 // permissions (as usual) are not recursively applied
211 Lower->addRegularFile("/both/foo", sys::fs::owner_read);
212 Upper->addRegularFile("/both/bar", sys::fs::owner_write);
213 Status = O->status("/both/foo");
214 ASSERT_EQ(errc::success, Status.getError());
215 EXPECT_EQ(0400, Status->getPermissions());
216 Status = O->status("/both/bar");
217 ASSERT_EQ(errc::success, Status.getError());
218 EXPECT_EQ(0200, Status->getPermissions());
219}
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000220
Ben Langmuir97882e72014-02-24 20:56:37 +0000221class VFSFromYAMLTest : public ::testing::Test {
222public:
223 int NumDiagnostics;
224 void SetUp() {
225 NumDiagnostics = 0;
226 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000227
Ben Langmuir97882e72014-02-24 20:56:37 +0000228 static void CountingDiagHandler(const SMDiagnostic &, void *Context) {
229 VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context);
230 ++Test->NumDiagnostics;
231 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000232
Ben Langmuir97882e72014-02-24 20:56:37 +0000233 IntrusiveRefCntPtr<vfs::FileSystem>
234 getFromYAMLRawString(StringRef Content,
235 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
236 MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Content);
237 return getVFSFromYAML(Buffer, CountingDiagHandler, this, ExternalFS);
238 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000239
Ben Langmuir97882e72014-02-24 20:56:37 +0000240 IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString(
241 StringRef Content,
242 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) {
243 std::string VersionPlusContent("{\n 'version':0,\n");
244 VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
245 return getFromYAMLRawString(VersionPlusContent, ExternalFS);
246 }
247
248};
249
250TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000251 IntrusiveRefCntPtr<vfs::FileSystem> FS;
252 FS = getFromYAMLString("");
253 EXPECT_EQ(NULL, FS.getPtr());
254 FS = getFromYAMLString("[]");
255 EXPECT_EQ(NULL, FS.getPtr());
256 FS = getFromYAMLString("'string'");
257 EXPECT_EQ(NULL, FS.getPtr());
258 EXPECT_EQ(3, NumDiagnostics);
259}
260
Ben Langmuir97882e72014-02-24 20:56:37 +0000261TEST_F(VFSFromYAMLTest, MappedFiles) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000262 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
263 Lower->addRegularFile("/foo/bar/a");
264 IntrusiveRefCntPtr<vfs::FileSystem> FS =
265 getFromYAMLString("{ 'roots': [\n"
266 "{\n"
267 " 'type': 'directory',\n"
268 " 'name': '/',\n"
269 " 'contents': [ {\n"
270 " 'type': 'file',\n"
271 " 'name': 'file1',\n"
272 " 'external-contents': '/foo/bar/a'\n"
273 " },\n"
274 " {\n"
275 " 'type': 'file',\n"
276 " 'name': 'file2',\n"
277 " 'external-contents': '/foo/b'\n"
278 " }\n"
279 " ]\n"
280 "}\n"
281 "]\n"
282 "}",
283 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000284 ASSERT_TRUE(FS.getPtr() != NULL);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000285
286 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
287 new vfs::OverlayFileSystem(Lower));
288 O->pushOverlay(FS);
289
290 // file
291 ErrorOr<vfs::Status> S = O->status("/file1");
292 ASSERT_EQ(errc::success, S.getError());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000293 EXPECT_EQ("/foo/bar/a", S->getName());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000294
295 ErrorOr<vfs::Status> SLower = O->status("/foo/bar/a");
296 EXPECT_EQ("/foo/bar/a", SLower->getName());
297 EXPECT_TRUE(S->equivalent(*SLower));
298
299 // directory
300 S = O->status("/");
301 ASSERT_EQ(errc::success, S.getError());
302 EXPECT_TRUE(S->isDirectory());
303 EXPECT_TRUE(S->equivalent(*O->status("/"))); // non-volatile UniqueID
304
305 // broken mapping
306 EXPECT_EQ(errc::no_such_file_or_directory, O->status("/file2").getError());
307 EXPECT_EQ(0, NumDiagnostics);
308}
309
Ben Langmuir97882e72014-02-24 20:56:37 +0000310TEST_F(VFSFromYAMLTest, CaseInsensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000311 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
312 Lower->addRegularFile("/foo/bar/a");
313 IntrusiveRefCntPtr<vfs::FileSystem> FS =
314 getFromYAMLString("{ 'case-sensitive': 'false',\n"
315 " 'roots': [\n"
316 "{\n"
317 " 'type': 'directory',\n"
318 " 'name': '/',\n"
319 " 'contents': [ {\n"
320 " 'type': 'file',\n"
321 " 'name': 'XX',\n"
322 " 'external-contents': '/foo/bar/a'\n"
323 " }\n"
324 " ]\n"
325 "}]}",
326 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000327 ASSERT_TRUE(FS.getPtr() != NULL);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000328
329 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
330 new vfs::OverlayFileSystem(Lower));
331 O->pushOverlay(FS);
332
333 ErrorOr<vfs::Status> S = O->status("/XX");
334 ASSERT_EQ(errc::success, S.getError());
335
336 ErrorOr<vfs::Status> SS = O->status("/xx");
337 ASSERT_EQ(errc::success, SS.getError());
338 EXPECT_TRUE(S->equivalent(*SS));
339 SS = O->status("/xX");
340 EXPECT_TRUE(S->equivalent(*SS));
341 SS = O->status("/Xx");
342 EXPECT_TRUE(S->equivalent(*SS));
343 EXPECT_EQ(0, NumDiagnostics);
344}
345
Ben Langmuir97882e72014-02-24 20:56:37 +0000346TEST_F(VFSFromYAMLTest, CaseSensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000347 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
348 Lower->addRegularFile("/foo/bar/a");
349 IntrusiveRefCntPtr<vfs::FileSystem> FS =
350 getFromYAMLString("{ 'case-sensitive': 'true',\n"
351 " 'roots': [\n"
352 "{\n"
353 " 'type': 'directory',\n"
354 " 'name': '/',\n"
355 " 'contents': [ {\n"
356 " 'type': 'file',\n"
357 " 'name': 'XX',\n"
358 " 'external-contents': '/foo/bar/a'\n"
359 " }\n"
360 " ]\n"
361 "}]}",
362 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000363 ASSERT_TRUE(FS.getPtr() != NULL);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000364
365 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
366 new vfs::OverlayFileSystem(Lower));
367 O->pushOverlay(FS);
368
369 ErrorOr<vfs::Status> SS = O->status("/xx");
370 EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
371 SS = O->status("/xX");
372 EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
373 SS = O->status("/Xx");
374 EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
375 EXPECT_EQ(0, NumDiagnostics);
376}
377
Ben Langmuir97882e72014-02-24 20:56:37 +0000378TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000379 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
380
381 // invalid YAML at top-level
382 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000383 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000384 // invalid YAML in roots
385 FS = getFromYAMLString("{ 'roots':[}", Lower);
386 // invalid YAML in directory
387 FS = getFromYAMLString(
388 "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
389 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000390 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000391
392 // invalid configuration
393 FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000394 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000395 FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000396 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000397
398 // invalid roots
399 FS = getFromYAMLString("{ 'roots':'' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000400 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000401 FS = getFromYAMLString("{ 'roots':{} }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000402 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000403
404 // invalid entries
405 FS = getFromYAMLString(
406 "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000407 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000408 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
409 "'external-contents': 'other' }",
410 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000411 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000412 FS = getFromYAMLString(
413 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
414 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000415 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000416 FS = getFromYAMLString(
417 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
418 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000419 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000420 FS = getFromYAMLString(
421 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
422 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000423 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000424 FS = getFromYAMLString(
425 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
426 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000427 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000428 FS = getFromYAMLString(
429 "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
430 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000431 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000432
433 // missing mandatory fields
434 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000435 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000436 FS = getFromYAMLString(
437 "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000438 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000439 FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000440 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000441
442 // duplicate keys
443 FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000444 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000445 FS = getFromYAMLString(
446 "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
447 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000448 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000449 FS =
450 getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
451 "'external-contents':'blah' } ] }",
452 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000453 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000454
455 // missing version
456 FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000457 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000458
459 // bad version number
460 FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000461 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000462 FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000463 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000464 FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000465 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000466 EXPECT_EQ(24, NumDiagnostics);
467}
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000468
Ben Langmuirb59cf672014-02-27 00:25:12 +0000469TEST_F(VFSFromYAMLTest, UseExternalName) {
470 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
471 Lower->addRegularFile("/external/file");
472
473 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
474 "{ 'roots': [\n"
475 " { 'type': 'file', 'name': '/A',\n"
476 " 'external-contents': '/external/file'\n"
477 " },\n"
478 " { 'type': 'file', 'name': '/B',\n"
479 " 'use-external-name': true,\n"
480 " 'external-contents': '/external/file'\n"
481 " },\n"
482 " { 'type': 'file', 'name': '/C',\n"
483 " 'use-external-name': false,\n"
484 " 'external-contents': '/external/file'\n"
485 " }\n"
486 "] }", Lower);
487 ASSERT_TRUE(NULL != FS.getPtr());
488
489 // default true
490 EXPECT_EQ("/external/file", FS->status("/A")->getName());
491 // explicit
492 EXPECT_EQ("/external/file", FS->status("/B")->getName());
493 EXPECT_EQ("/C", FS->status("/C")->getName());
494
495 // global configuration
496 FS = getFromYAMLString(
497 "{ 'use-external-names': false,\n"
498 " 'roots': [\n"
499 " { 'type': 'file', 'name': '/A',\n"
500 " 'external-contents': '/external/file'\n"
501 " },\n"
502 " { 'type': 'file', 'name': '/B',\n"
503 " 'use-external-name': true,\n"
504 " 'external-contents': '/external/file'\n"
505 " },\n"
506 " { 'type': 'file', 'name': '/C',\n"
507 " 'use-external-name': false,\n"
508 " 'external-contents': '/external/file'\n"
509 " }\n"
510 "] }", Lower);
511 ASSERT_TRUE(NULL != FS.getPtr());
512
513 // default
514 EXPECT_EQ("/A", FS->status("/A")->getName());
515 // explicit
516 EXPECT_EQ("/external/file", FS->status("/B")->getName());
517 EXPECT_EQ("/C", FS->status("/C")->getName());
518}
519
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000520TEST_F(VFSFromYAMLTest, MultiComponentPath) {
521 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
522 Lower->addRegularFile("/other");
523
524 // file in roots
525 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
526 "{ 'roots': [\n"
527 " { 'type': 'file', 'name': '/path/to/file',\n"
528 " 'external-contents': '/other' }]\n"
529 "}", Lower);
530 ASSERT_TRUE(NULL != FS.getPtr());
531 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
532 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
533 EXPECT_EQ(errc::success, FS->status("/path").getError());
534 EXPECT_EQ(errc::success, FS->status("/").getError());
535
536 // at the start
537 FS = getFromYAMLString(
538 "{ 'roots': [\n"
539 " { 'type': 'directory', 'name': '/path/to',\n"
540 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
541 " 'external-contents': '/other' }]}]\n"
542 "}", Lower);
543 ASSERT_TRUE(NULL != FS.getPtr());
544 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
545 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
546 EXPECT_EQ(errc::success, FS->status("/path").getError());
547 EXPECT_EQ(errc::success, FS->status("/").getError());
548
549 // at the end
550 FS = getFromYAMLString(
551 "{ 'roots': [\n"
552 " { 'type': 'directory', 'name': '/',\n"
553 " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
554 " 'external-contents': '/other' }]}]\n"
555 "}", Lower);
556 ASSERT_TRUE(NULL != FS.getPtr());
557 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
558 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
559 EXPECT_EQ(errc::success, FS->status("/path").getError());
560 EXPECT_EQ(errc::success, FS->status("/").getError());
561}
562
563TEST_F(VFSFromYAMLTest, TrailingSlashes) {
564 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
565 Lower->addRegularFile("/other");
566
567 // file in roots
568 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
569 "{ 'roots': [\n"
570 " { 'type': 'directory', 'name': '/path/to////',\n"
571 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
572 " 'external-contents': '/other' }]}]\n"
573 "}", Lower);
574 ASSERT_TRUE(NULL != FS.getPtr());
575 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
576 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
577 EXPECT_EQ(errc::success, FS->status("/path").getError());
578 EXPECT_EQ(errc::success, FS->status("/").getError());
579}