blob: 63d533614ce266b40869855650f9dc6863d93843 [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())
Rafael Espindola1f243172014-06-12 11:35:17 +000038 return std::make_error_code(std::errc::no_such_file_or_directory);
Ben Langmuirc8130a72014-02-20 21:59:23 +000039 return I->second;
40 }
Rafael Espindola8e650d72014-06-12 20:37:59 +000041 std::error_code openFileForRead(const Twine &Path,
42 std::unique_ptr<vfs::File> &Result) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000043 llvm_unreachable("unimplemented");
44 }
Rafael Espindola8e650d72014-06-12 20:37:59 +000045 std::error_code getBufferForFile(const Twine &Name,
46 std::unique_ptr<MemoryBuffer> &Result,
47 int64_t FileSize = -1,
48 bool RequiresNullTerminator = true) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000049 llvm_unreachable("unimplemented");
50 }
51
52 void addEntry(StringRef Path, const vfs::Status &Status) {
53 FilesAndDirs[Path] = Status;
54 }
55
Ben Langmuird51ba0b2014-02-21 23:39:37 +000056 void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000057 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
58 0, 0, 1024, sys::fs::file_type::regular_file, Perms);
59 addEntry(Path, S);
60 }
61
Ben Langmuird51ba0b2014-02-21 23:39:37 +000062 void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000063 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
64 0, 0, 0, sys::fs::file_type::directory_file, Perms);
65 addEntry(Path, S);
66 }
67
68 void addSymlink(StringRef Path) {
69 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
70 0, 0, 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
71 addEntry(Path, S);
72 }
73};
74} // end anonymous namespace
75
Ben Langmuird51ba0b2014-02-21 23:39:37 +000076TEST(VirtualFileSystemTest, StatusQueries) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000077 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
Rafael Espindola8e650d72014-06-12 20:37:59 +000078 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +000079
80 D->addRegularFile("/foo");
81 Status = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +000082 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +000083 EXPECT_TRUE(Status->isStatusKnown());
84 EXPECT_FALSE(Status->isDirectory());
85 EXPECT_TRUE(Status->isRegularFile());
86 EXPECT_FALSE(Status->isSymlink());
87 EXPECT_FALSE(Status->isOther());
88 EXPECT_TRUE(Status->exists());
89
90 D->addDirectory("/bar");
91 Status = D->status("/bar");
Rafael Espindola3ae06202014-05-31 03:20:52 +000092 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +000093 EXPECT_TRUE(Status->isStatusKnown());
94 EXPECT_TRUE(Status->isDirectory());
95 EXPECT_FALSE(Status->isRegularFile());
96 EXPECT_FALSE(Status->isSymlink());
97 EXPECT_FALSE(Status->isOther());
98 EXPECT_TRUE(Status->exists());
99
100 D->addSymlink("/baz");
101 Status = D->status("/baz");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000102 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000103 EXPECT_TRUE(Status->isStatusKnown());
104 EXPECT_FALSE(Status->isDirectory());
105 EXPECT_FALSE(Status->isRegularFile());
106 EXPECT_TRUE(Status->isSymlink());
107 EXPECT_FALSE(Status->isOther());
108 EXPECT_TRUE(Status->exists());
109
110 EXPECT_TRUE(Status->equivalent(*Status));
111 ErrorOr<vfs::Status> Status2 = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000112 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000113 EXPECT_FALSE(Status->equivalent(*Status2));
114}
115
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000116TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000117 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
Rafael Espindola8e650d72014-06-12 20:37:59 +0000118 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000119 EXPECT_FALSE(Status = D->status("/foo"));
120
121 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
122 EXPECT_FALSE(Status = O->status("/foo"));
123
124 D->addRegularFile("/foo");
125 Status = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000126 EXPECT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000127
Rafael Espindola8e650d72014-06-12 20:37:59 +0000128 ErrorOr<vfs::Status> Status2((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000129 Status2 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000130 EXPECT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000131 EXPECT_TRUE(Status->equivalent(*Status2));
132}
133
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000134TEST(VirtualFileSystemTest, OverlayFiles) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000135 IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem());
136 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
137 IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000138 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
139 new vfs::OverlayFileSystem(Base));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000140 O->pushOverlay(Middle);
141 O->pushOverlay(Top);
142
Rafael Espindola8e650d72014-06-12 20:37:59 +0000143 ErrorOr<vfs::Status> Status1((std::error_code())),
144 Status2((std::error_code())), Status3((std::error_code())),
145 StatusB((std::error_code())), StatusM((std::error_code())),
146 StatusT((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000147
148 Base->addRegularFile("/foo");
149 StatusB = Base->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000150 ASSERT_FALSE(StatusB.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000151 Status1 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000152 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000153 Middle->addRegularFile("/foo");
154 StatusM = Middle->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000155 ASSERT_FALSE(StatusM.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000156 Status2 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000157 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000158 Top->addRegularFile("/foo");
159 StatusT = Top->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000160 ASSERT_FALSE(StatusT.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000161 Status3 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000162 ASSERT_FALSE(Status3.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000163
164 EXPECT_TRUE(Status1->equivalent(*StatusB));
165 EXPECT_TRUE(Status2->equivalent(*StatusM));
166 EXPECT_TRUE(Status3->equivalent(*StatusT));
167
168 EXPECT_FALSE(Status1->equivalent(*Status2));
169 EXPECT_FALSE(Status2->equivalent(*Status3));
170 EXPECT_FALSE(Status1->equivalent(*Status3));
171}
172
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000173TEST(VirtualFileSystemTest, OverlayDirsNonMerged) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000174 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
175 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000176 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
177 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000178 O->pushOverlay(Upper);
179
180 Lower->addDirectory("/lower-only");
181 Upper->addDirectory("/upper-only");
182
183 // non-merged paths should be the same
184 ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000185 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000186 ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000187 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000188 EXPECT_TRUE(Status1->equivalent(*Status2));
189
190 Status1 = Upper->status("/upper-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000191 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000192 Status2 = O->status("/upper-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000193 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000194 EXPECT_TRUE(Status1->equivalent(*Status2));
195}
196
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000197TEST(VirtualFileSystemTest, MergedDirPermissions) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000198 // merged directories get the permissions of the upper dir
199 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
200 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000201 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
202 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000203 O->pushOverlay(Upper);
204
Rafael Espindola8e650d72014-06-12 20:37:59 +0000205 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000206 Lower->addDirectory("/both", sys::fs::owner_read);
207 Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
208 Status = O->status("/both");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000209 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000210 EXPECT_EQ(0740, Status->getPermissions());
211
212 // permissions (as usual) are not recursively applied
213 Lower->addRegularFile("/both/foo", sys::fs::owner_read);
214 Upper->addRegularFile("/both/bar", sys::fs::owner_write);
215 Status = O->status("/both/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000216 ASSERT_FALSE( Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000217 EXPECT_EQ(0400, Status->getPermissions());
218 Status = O->status("/both/bar");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000219 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000220 EXPECT_EQ(0200, Status->getPermissions());
221}
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000222
Ben Langmuir93853232014-03-05 21:32:20 +0000223// NOTE: in the tests below, we use '//root/' as our root directory, since it is
224// a legal *absolute* path on Windows as well as *nix.
Ben Langmuir97882e72014-02-24 20:56:37 +0000225class VFSFromYAMLTest : public ::testing::Test {
226public:
227 int NumDiagnostics;
Ben Langmuir93853232014-03-05 21:32:20 +0000228
Ben Langmuir97882e72014-02-24 20:56:37 +0000229 void SetUp() {
230 NumDiagnostics = 0;
231 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000232
Ben Langmuir97882e72014-02-24 20:56:37 +0000233 static void CountingDiagHandler(const SMDiagnostic &, void *Context) {
234 VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context);
235 ++Test->NumDiagnostics;
236 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000237
Ben Langmuir97882e72014-02-24 20:56:37 +0000238 IntrusiveRefCntPtr<vfs::FileSystem>
239 getFromYAMLRawString(StringRef Content,
240 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
241 MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Content);
242 return getVFSFromYAML(Buffer, CountingDiagHandler, this, ExternalFS);
243 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000244
Ben Langmuir97882e72014-02-24 20:56:37 +0000245 IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString(
246 StringRef Content,
247 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) {
248 std::string VersionPlusContent("{\n 'version':0,\n");
249 VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
250 return getFromYAMLRawString(VersionPlusContent, ExternalFS);
251 }
Ben Langmuir97882e72014-02-24 20:56:37 +0000252};
253
254TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000255 IntrusiveRefCntPtr<vfs::FileSystem> FS;
256 FS = getFromYAMLString("");
Craig Topper416fa342014-06-08 08:38:12 +0000257 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000258 FS = getFromYAMLString("[]");
Craig Topper416fa342014-06-08 08:38:12 +0000259 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000260 FS = getFromYAMLString("'string'");
Craig Topper416fa342014-06-08 08:38:12 +0000261 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000262 EXPECT_EQ(3, NumDiagnostics);
263}
264
Ben Langmuir97882e72014-02-24 20:56:37 +0000265TEST_F(VFSFromYAMLTest, MappedFiles) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000266 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000267 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000268 IntrusiveRefCntPtr<vfs::FileSystem> FS =
269 getFromYAMLString("{ 'roots': [\n"
270 "{\n"
271 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000272 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000273 " 'contents': [ {\n"
274 " 'type': 'file',\n"
275 " 'name': 'file1',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000276 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000277 " },\n"
278 " {\n"
279 " 'type': 'file',\n"
280 " 'name': 'file2',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000281 " 'external-contents': '//root/foo/b'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000282 " }\n"
283 " ]\n"
284 "}\n"
285 "]\n"
286 "}",
287 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000288 ASSERT_TRUE(FS.getPtr() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000289
290 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
291 new vfs::OverlayFileSystem(Lower));
292 O->pushOverlay(FS);
293
294 // file
Ben Langmuir93853232014-03-05 21:32:20 +0000295 ErrorOr<vfs::Status> S = O->status("//root/file1");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000296 ASSERT_FALSE(S.getError());
Ben Langmuir93853232014-03-05 21:32:20 +0000297 EXPECT_EQ("//root/foo/bar/a", S->getName());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000298
Ben Langmuir93853232014-03-05 21:32:20 +0000299 ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
300 EXPECT_EQ("//root/foo/bar/a", SLower->getName());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000301 EXPECT_TRUE(S->equivalent(*SLower));
302
303 // directory
Ben Langmuir93853232014-03-05 21:32:20 +0000304 S = O->status("//root/");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000305 ASSERT_FALSE(S.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000306 EXPECT_TRUE(S->isDirectory());
Ben Langmuir93853232014-03-05 21:32:20 +0000307 EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000308
309 // broken mapping
Rafael Espindola96b03302014-06-11 19:05:55 +0000310 EXPECT_EQ(std::errc::no_such_file_or_directory,
311 O->status("//root/file2").getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000312 EXPECT_EQ(0, NumDiagnostics);
313}
314
Ben Langmuir97882e72014-02-24 20:56:37 +0000315TEST_F(VFSFromYAMLTest, CaseInsensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000316 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000317 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000318 IntrusiveRefCntPtr<vfs::FileSystem> FS =
319 getFromYAMLString("{ 'case-sensitive': 'false',\n"
320 " 'roots': [\n"
321 "{\n"
322 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000323 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000324 " 'contents': [ {\n"
325 " 'type': 'file',\n"
326 " 'name': 'XX',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000327 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000328 " }\n"
329 " ]\n"
330 "}]}",
331 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000332 ASSERT_TRUE(FS.getPtr() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000333
334 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
335 new vfs::OverlayFileSystem(Lower));
336 O->pushOverlay(FS);
337
Ben Langmuir93853232014-03-05 21:32:20 +0000338 ErrorOr<vfs::Status> S = O->status("//root/XX");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000339 ASSERT_FALSE(S.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000340
Ben Langmuir93853232014-03-05 21:32:20 +0000341 ErrorOr<vfs::Status> SS = O->status("//root/xx");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000342 ASSERT_FALSE(SS.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000343 EXPECT_TRUE(S->equivalent(*SS));
Ben Langmuir93853232014-03-05 21:32:20 +0000344 SS = O->status("//root/xX");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000345 EXPECT_TRUE(S->equivalent(*SS));
Ben Langmuir93853232014-03-05 21:32:20 +0000346 SS = O->status("//root/Xx");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000347 EXPECT_TRUE(S->equivalent(*SS));
348 EXPECT_EQ(0, NumDiagnostics);
349}
350
Ben Langmuir97882e72014-02-24 20:56:37 +0000351TEST_F(VFSFromYAMLTest, CaseSensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000352 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000353 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000354 IntrusiveRefCntPtr<vfs::FileSystem> FS =
355 getFromYAMLString("{ 'case-sensitive': 'true',\n"
356 " 'roots': [\n"
357 "{\n"
358 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000359 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000360 " 'contents': [ {\n"
361 " 'type': 'file',\n"
362 " 'name': 'XX',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000363 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000364 " }\n"
365 " ]\n"
366 "}]}",
367 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000368 ASSERT_TRUE(FS.getPtr() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000369
370 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
371 new vfs::OverlayFileSystem(Lower));
372 O->pushOverlay(FS);
373
Ben Langmuir93853232014-03-05 21:32:20 +0000374 ErrorOr<vfs::Status> SS = O->status("//root/xx");
Rafael Espindola96b03302014-06-11 19:05:55 +0000375 EXPECT_EQ(std::errc::no_such_file_or_directory, SS.getError());
Ben Langmuir93853232014-03-05 21:32:20 +0000376 SS = O->status("//root/xX");
Rafael Espindola96b03302014-06-11 19:05:55 +0000377 EXPECT_EQ(std::errc::no_such_file_or_directory, SS.getError());
Ben Langmuir93853232014-03-05 21:32:20 +0000378 SS = O->status("//root/Xx");
Rafael Espindola96b03302014-06-11 19:05:55 +0000379 EXPECT_EQ(std::errc::no_such_file_or_directory, SS.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000380 EXPECT_EQ(0, NumDiagnostics);
381}
382
Ben Langmuir97882e72014-02-24 20:56:37 +0000383TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000384 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
385
386 // invalid YAML at top-level
387 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000388 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000389 // invalid YAML in roots
390 FS = getFromYAMLString("{ 'roots':[}", Lower);
391 // invalid YAML in directory
392 FS = getFromYAMLString(
393 "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
394 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000395 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000396
397 // invalid configuration
398 FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000399 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000400 FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000401 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000402
403 // invalid roots
404 FS = getFromYAMLString("{ 'roots':'' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000405 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000406 FS = getFromYAMLString("{ 'roots':{} }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000407 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000408
409 // invalid entries
410 FS = getFromYAMLString(
411 "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000412 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000413 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
414 "'external-contents': 'other' }",
415 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000416 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000417 FS = getFromYAMLString(
418 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
419 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000420 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000421 FS = getFromYAMLString(
422 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
423 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000424 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000425 FS = getFromYAMLString(
426 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
427 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000428 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000429 FS = getFromYAMLString(
430 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
431 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000432 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000433 FS = getFromYAMLString(
434 "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
435 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000436 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000437
438 // missing mandatory fields
439 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000440 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000441 FS = getFromYAMLString(
442 "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000443 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000444 FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000445 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000446
447 // duplicate keys
448 FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000449 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000450 FS = getFromYAMLString(
451 "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
452 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000453 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000454 FS =
455 getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
456 "'external-contents':'blah' } ] }",
457 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000458 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000459
460 // missing version
461 FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000462 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000463
464 // bad version number
465 FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000466 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000467 FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000468 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000469 FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000470 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000471 EXPECT_EQ(24, NumDiagnostics);
472}
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000473
Ben Langmuirb59cf672014-02-27 00:25:12 +0000474TEST_F(VFSFromYAMLTest, UseExternalName) {
475 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000476 Lower->addRegularFile("//root/external/file");
Ben Langmuirb59cf672014-02-27 00:25:12 +0000477
478 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
479 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000480 " { 'type': 'file', 'name': '//root/A',\n"
481 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000482 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000483 " { 'type': 'file', 'name': '//root/B',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000484 " 'use-external-name': true,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000485 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000486 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000487 " { 'type': 'file', 'name': '//root/C',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000488 " 'use-external-name': false,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000489 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000490 " }\n"
491 "] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000492 ASSERT_TRUE(nullptr != FS.getPtr());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000493
494 // default true
Ben Langmuir93853232014-03-05 21:32:20 +0000495 EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000496 // explicit
Ben Langmuir93853232014-03-05 21:32:20 +0000497 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
498 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000499
500 // global configuration
501 FS = getFromYAMLString(
502 "{ 'use-external-names': false,\n"
503 " 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000504 " { 'type': 'file', 'name': '//root/A',\n"
505 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000506 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000507 " { 'type': 'file', 'name': '//root/B',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000508 " 'use-external-name': true,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000509 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000510 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000511 " { 'type': 'file', 'name': '//root/C',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000512 " 'use-external-name': false,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000513 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000514 " }\n"
515 "] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000516 ASSERT_TRUE(nullptr != FS.getPtr());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000517
518 // default
Ben Langmuir93853232014-03-05 21:32:20 +0000519 EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000520 // explicit
Ben Langmuir93853232014-03-05 21:32:20 +0000521 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
522 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000523}
524
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000525TEST_F(VFSFromYAMLTest, MultiComponentPath) {
526 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000527 Lower->addRegularFile("//root/other");
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000528
529 // file in roots
530 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
531 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000532 " { 'type': 'file', 'name': '//root/path/to/file',\n"
533 " 'external-contents': '//root/other' }]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000534 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000535 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000536 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
537 EXPECT_FALSE(FS->status("//root/path/to").getError());
538 EXPECT_FALSE(FS->status("//root/path").getError());
539 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000540
541 // at the start
542 FS = getFromYAMLString(
543 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000544 " { 'type': 'directory', 'name': '//root/path/to',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000545 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000546 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000547 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000548 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000549 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
550 EXPECT_FALSE(FS->status("//root/path/to").getError());
551 EXPECT_FALSE(FS->status("//root/path").getError());
552 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000553
554 // at the end
555 FS = getFromYAMLString(
556 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000557 " { 'type': 'directory', 'name': '//root/',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000558 " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000559 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000560 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000561 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000562 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
563 EXPECT_FALSE(FS->status("//root/path/to").getError());
564 EXPECT_FALSE(FS->status("//root/path").getError());
565 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000566}
567
568TEST_F(VFSFromYAMLTest, TrailingSlashes) {
569 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000570 Lower->addRegularFile("//root/other");
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000571
572 // file in roots
573 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
574 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000575 " { 'type': 'directory', 'name': '//root/path/to////',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000576 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000577 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000578 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000579 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000580 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
581 EXPECT_FALSE(FS->status("//root/path/to").getError());
582 EXPECT_FALSE(FS->status("//root/path").getError());
583 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000584}