blob: 334b1a45ddf78dc821e29305864603bb5bf8d5af [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());
293 EXPECT_EQ("/file1", S->getName());
294 EXPECT_EQ("/foo/bar/a", S->getExternalName());
295
296 ErrorOr<vfs::Status> SLower = O->status("/foo/bar/a");
297 EXPECT_EQ("/foo/bar/a", SLower->getName());
298 EXPECT_TRUE(S->equivalent(*SLower));
299
300 // directory
301 S = O->status("/");
302 ASSERT_EQ(errc::success, S.getError());
303 EXPECT_TRUE(S->isDirectory());
304 EXPECT_TRUE(S->equivalent(*O->status("/"))); // non-volatile UniqueID
305
306 // broken mapping
307 EXPECT_EQ(errc::no_such_file_or_directory, O->status("/file2").getError());
308 EXPECT_EQ(0, NumDiagnostics);
309}
310
Ben Langmuir97882e72014-02-24 20:56:37 +0000311TEST_F(VFSFromYAMLTest, CaseInsensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000312 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
313 Lower->addRegularFile("/foo/bar/a");
314 IntrusiveRefCntPtr<vfs::FileSystem> FS =
315 getFromYAMLString("{ 'case-sensitive': 'false',\n"
316 " 'roots': [\n"
317 "{\n"
318 " 'type': 'directory',\n"
319 " 'name': '/',\n"
320 " 'contents': [ {\n"
321 " 'type': 'file',\n"
322 " 'name': 'XX',\n"
323 " 'external-contents': '/foo/bar/a'\n"
324 " }\n"
325 " ]\n"
326 "}]}",
327 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000328 ASSERT_TRUE(FS.getPtr() != NULL);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000329
330 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
331 new vfs::OverlayFileSystem(Lower));
332 O->pushOverlay(FS);
333
334 ErrorOr<vfs::Status> S = O->status("/XX");
335 ASSERT_EQ(errc::success, S.getError());
336
337 ErrorOr<vfs::Status> SS = O->status("/xx");
338 ASSERT_EQ(errc::success, SS.getError());
339 EXPECT_TRUE(S->equivalent(*SS));
340 SS = O->status("/xX");
341 EXPECT_TRUE(S->equivalent(*SS));
342 SS = O->status("/Xx");
343 EXPECT_TRUE(S->equivalent(*SS));
344 EXPECT_EQ(0, NumDiagnostics);
345}
346
Ben Langmuir97882e72014-02-24 20:56:37 +0000347TEST_F(VFSFromYAMLTest, CaseSensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000348 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
349 Lower->addRegularFile("/foo/bar/a");
350 IntrusiveRefCntPtr<vfs::FileSystem> FS =
351 getFromYAMLString("{ 'case-sensitive': 'true',\n"
352 " 'roots': [\n"
353 "{\n"
354 " 'type': 'directory',\n"
355 " 'name': '/',\n"
356 " 'contents': [ {\n"
357 " 'type': 'file',\n"
358 " 'name': 'XX',\n"
359 " 'external-contents': '/foo/bar/a'\n"
360 " }\n"
361 " ]\n"
362 "}]}",
363 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000364 ASSERT_TRUE(FS.getPtr() != NULL);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000365
366 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
367 new vfs::OverlayFileSystem(Lower));
368 O->pushOverlay(FS);
369
370 ErrorOr<vfs::Status> SS = O->status("/xx");
371 EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
372 SS = O->status("/xX");
373 EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
374 SS = O->status("/Xx");
375 EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
376 EXPECT_EQ(0, NumDiagnostics);
377}
378
Ben Langmuir97882e72014-02-24 20:56:37 +0000379TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000380 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
381
382 // invalid YAML at top-level
383 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000384 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000385 // invalid YAML in roots
386 FS = getFromYAMLString("{ 'roots':[}", Lower);
387 // invalid YAML in directory
388 FS = getFromYAMLString(
389 "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
390 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000391 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000392
393 // invalid configuration
394 FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000395 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000396 FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000397 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000398
399 // invalid roots
400 FS = getFromYAMLString("{ 'roots':'' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000401 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000402 FS = getFromYAMLString("{ 'roots':{} }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000403 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000404
405 // invalid entries
406 FS = getFromYAMLString(
407 "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000408 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000409 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
410 "'external-contents': 'other' }",
411 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000412 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000413 FS = getFromYAMLString(
414 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
415 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000416 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000417 FS = getFromYAMLString(
418 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
419 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000420 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000421 FS = getFromYAMLString(
422 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
423 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000424 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000425 FS = getFromYAMLString(
426 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
427 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000428 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000429 FS = getFromYAMLString(
430 "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
431 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000432 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000433
434 // missing mandatory fields
435 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000436 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000437 FS = getFromYAMLString(
438 "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000439 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000440 FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000441 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000442
443 // duplicate keys
444 FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000445 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000446 FS = getFromYAMLString(
447 "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
448 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000449 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000450 FS =
451 getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
452 "'external-contents':'blah' } ] }",
453 Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000454 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000455
456 // missing version
457 FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000458 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000459
460 // bad version number
461 FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000462 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000463 FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000464 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000465 FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
Ben Langmuir509fe8fd2014-02-24 23:44:17 +0000466 EXPECT_EQ(NULL, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000467 EXPECT_EQ(24, NumDiagnostics);
468}
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000469
470TEST_F(VFSFromYAMLTest, MultiComponentPath) {
471 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
472 Lower->addRegularFile("/other");
473
474 // file in roots
475 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
476 "{ 'roots': [\n"
477 " { 'type': 'file', 'name': '/path/to/file',\n"
478 " 'external-contents': '/other' }]\n"
479 "}", Lower);
480 ASSERT_TRUE(NULL != FS.getPtr());
481 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
482 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
483 EXPECT_EQ(errc::success, FS->status("/path").getError());
484 EXPECT_EQ(errc::success, FS->status("/").getError());
485
486 // at the start
487 FS = getFromYAMLString(
488 "{ 'roots': [\n"
489 " { 'type': 'directory', 'name': '/path/to',\n"
490 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
491 " 'external-contents': '/other' }]}]\n"
492 "}", Lower);
493 ASSERT_TRUE(NULL != FS.getPtr());
494 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
495 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
496 EXPECT_EQ(errc::success, FS->status("/path").getError());
497 EXPECT_EQ(errc::success, FS->status("/").getError());
498
499 // at the end
500 FS = getFromYAMLString(
501 "{ 'roots': [\n"
502 " { 'type': 'directory', 'name': '/',\n"
503 " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
504 " 'external-contents': '/other' }]}]\n"
505 "}", Lower);
506 ASSERT_TRUE(NULL != FS.getPtr());
507 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
508 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
509 EXPECT_EQ(errc::success, FS->status("/path").getError());
510 EXPECT_EQ(errc::success, FS->status("/").getError());
511}
512
513TEST_F(VFSFromYAMLTest, TrailingSlashes) {
514 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
515 Lower->addRegularFile("/other");
516
517 // file in roots
518 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
519 "{ 'roots': [\n"
520 " { 'type': 'directory', 'name': '/path/to////',\n"
521 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
522 " 'external-contents': '/other' }]}]\n"
523 "}", Lower);
524 ASSERT_TRUE(NULL != FS.getPtr());
525 EXPECT_EQ(errc::success, FS->status("/path/to/file").getError());
526 EXPECT_EQ(errc::success, FS->status("/path/to").getError());
527 EXPECT_EQ(errc::success, FS->status("/path").getError());
528 EXPECT_EQ(errc::success, FS->status("/").getError());
529}