blob: 132e248f2467f4f716fdc978c516ed324dff626e [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>
17using namespace clang;
18using namespace llvm;
19using llvm::sys::fs::UniqueID;
20
21namespace {
22class DummyFileSystem : public vfs::FileSystem {
23 int FSID; // used to produce UniqueIDs
24 int FileID; // used to produce UniqueIDs
25 std::map<std::string, vfs::Status> FilesAndDirs;
26
27 static int getNextFSID() {
28 static int Count = 0;
29 return Count++;
30 }
31
32public:
33 DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
34
35 ErrorOr<vfs::Status> status(const Twine &Path) {
36 std::map<std::string, vfs::Status>::iterator I =
Ben Langmuird51ba0b2014-02-21 23:39:37 +000037 FilesAndDirs.find(Path.str());
Ben Langmuirc8130a72014-02-20 21:59:23 +000038 if (I == FilesAndDirs.end())
Rafael Espindola71de0b62014-06-13 17:20:50 +000039 return make_error_code(llvm::errc::no_such_file_or_directory);
Ben Langmuirc8130a72014-02-20 21:59:23 +000040 return I->second;
41 }
Rafael Espindola8e650d72014-06-12 20:37:59 +000042 std::error_code openFileForRead(const Twine &Path,
43 std::unique_ptr<vfs::File> &Result) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000044 llvm_unreachable("unimplemented");
45 }
Rafael Espindola8e650d72014-06-12 20:37:59 +000046 std::error_code getBufferForFile(const Twine &Name,
47 std::unique_ptr<MemoryBuffer> &Result,
48 int64_t FileSize = -1,
49 bool RequiresNullTerminator = true) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000050 llvm_unreachable("unimplemented");
51 }
52
53 void addEntry(StringRef Path, const vfs::Status &Status) {
54 FilesAndDirs[Path] = Status;
55 }
56
Ben Langmuird51ba0b2014-02-21 23:39:37 +000057 void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000058 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
59 0, 0, 1024, sys::fs::file_type::regular_file, Perms);
60 addEntry(Path, S);
61 }
62
Ben Langmuird51ba0b2014-02-21 23:39:37 +000063 void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000064 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
65 0, 0, 0, sys::fs::file_type::directory_file, Perms);
66 addEntry(Path, S);
67 }
68
69 void addSymlink(StringRef Path) {
70 vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
71 0, 0, 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
72 addEntry(Path, S);
73 }
74};
75} // end anonymous namespace
76
Ben Langmuird51ba0b2014-02-21 23:39:37 +000077TEST(VirtualFileSystemTest, StatusQueries) {
Ben Langmuirc8130a72014-02-20 21:59:23 +000078 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
Rafael Espindola8e650d72014-06-12 20:37:59 +000079 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +000080
81 D->addRegularFile("/foo");
82 Status = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +000083 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +000084 EXPECT_TRUE(Status->isStatusKnown());
85 EXPECT_FALSE(Status->isDirectory());
86 EXPECT_TRUE(Status->isRegularFile());
87 EXPECT_FALSE(Status->isSymlink());
88 EXPECT_FALSE(Status->isOther());
89 EXPECT_TRUE(Status->exists());
90
91 D->addDirectory("/bar");
92 Status = D->status("/bar");
Rafael Espindola3ae06202014-05-31 03:20:52 +000093 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +000094 EXPECT_TRUE(Status->isStatusKnown());
95 EXPECT_TRUE(Status->isDirectory());
96 EXPECT_FALSE(Status->isRegularFile());
97 EXPECT_FALSE(Status->isSymlink());
98 EXPECT_FALSE(Status->isOther());
99 EXPECT_TRUE(Status->exists());
100
101 D->addSymlink("/baz");
102 Status = D->status("/baz");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000103 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000104 EXPECT_TRUE(Status->isStatusKnown());
105 EXPECT_FALSE(Status->isDirectory());
106 EXPECT_FALSE(Status->isRegularFile());
107 EXPECT_TRUE(Status->isSymlink());
108 EXPECT_FALSE(Status->isOther());
109 EXPECT_TRUE(Status->exists());
110
111 EXPECT_TRUE(Status->equivalent(*Status));
112 ErrorOr<vfs::Status> Status2 = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000113 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000114 EXPECT_FALSE(Status->equivalent(*Status2));
115}
116
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000117TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000118 IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
Rafael Espindola8e650d72014-06-12 20:37:59 +0000119 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000120 EXPECT_FALSE(Status = D->status("/foo"));
121
122 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
123 EXPECT_FALSE(Status = O->status("/foo"));
124
125 D->addRegularFile("/foo");
126 Status = D->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000127 EXPECT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000128
Rafael Espindola8e650d72014-06-12 20:37:59 +0000129 ErrorOr<vfs::Status> Status2((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000130 Status2 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000131 EXPECT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000132 EXPECT_TRUE(Status->equivalent(*Status2));
133}
134
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000135TEST(VirtualFileSystemTest, OverlayFiles) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000136 IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem());
137 IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
138 IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000139 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
140 new vfs::OverlayFileSystem(Base));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000141 O->pushOverlay(Middle);
142 O->pushOverlay(Top);
143
Rafael Espindola8e650d72014-06-12 20:37:59 +0000144 ErrorOr<vfs::Status> Status1((std::error_code())),
145 Status2((std::error_code())), Status3((std::error_code())),
146 StatusB((std::error_code())), StatusM((std::error_code())),
147 StatusT((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000148
149 Base->addRegularFile("/foo");
150 StatusB = Base->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000151 ASSERT_FALSE(StatusB.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000152 Status1 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000153 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000154 Middle->addRegularFile("/foo");
155 StatusM = Middle->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000156 ASSERT_FALSE(StatusM.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000157 Status2 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000158 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000159 Top->addRegularFile("/foo");
160 StatusT = Top->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000161 ASSERT_FALSE(StatusT.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000162 Status3 = O->status("/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000163 ASSERT_FALSE(Status3.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000164
165 EXPECT_TRUE(Status1->equivalent(*StatusB));
166 EXPECT_TRUE(Status2->equivalent(*StatusM));
167 EXPECT_TRUE(Status3->equivalent(*StatusT));
168
169 EXPECT_FALSE(Status1->equivalent(*Status2));
170 EXPECT_FALSE(Status2->equivalent(*Status3));
171 EXPECT_FALSE(Status1->equivalent(*Status3));
172}
173
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000174TEST(VirtualFileSystemTest, OverlayDirsNonMerged) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000175 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
176 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000177 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
178 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000179 O->pushOverlay(Upper);
180
181 Lower->addDirectory("/lower-only");
182 Upper->addDirectory("/upper-only");
183
184 // non-merged paths should be the same
185 ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000186 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000187 ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000188 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000189 EXPECT_TRUE(Status1->equivalent(*Status2));
190
191 Status1 = Upper->status("/upper-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000192 ASSERT_FALSE(Status1.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000193 Status2 = O->status("/upper-only");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000194 ASSERT_FALSE(Status2.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000195 EXPECT_TRUE(Status1->equivalent(*Status2));
196}
197
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000198TEST(VirtualFileSystemTest, MergedDirPermissions) {
Ben Langmuirc8130a72014-02-20 21:59:23 +0000199 // merged directories get the permissions of the upper dir
200 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
201 IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000202 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
203 new vfs::OverlayFileSystem(Lower));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000204 O->pushOverlay(Upper);
205
Rafael Espindola8e650d72014-06-12 20:37:59 +0000206 ErrorOr<vfs::Status> Status((std::error_code()));
Ben Langmuirc8130a72014-02-20 21:59:23 +0000207 Lower->addDirectory("/both", sys::fs::owner_read);
208 Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
209 Status = O->status("/both");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000210 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000211 EXPECT_EQ(0740, Status->getPermissions());
212
213 // permissions (as usual) are not recursively applied
214 Lower->addRegularFile("/both/foo", sys::fs::owner_read);
215 Upper->addRegularFile("/both/bar", sys::fs::owner_write);
216 Status = O->status("/both/foo");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000217 ASSERT_FALSE( Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000218 EXPECT_EQ(0400, Status->getPermissions());
219 Status = O->status("/both/bar");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000220 ASSERT_FALSE(Status.getError());
Ben Langmuirc8130a72014-02-20 21:59:23 +0000221 EXPECT_EQ(0200, Status->getPermissions());
222}
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000223
Ben Langmuir93853232014-03-05 21:32:20 +0000224// NOTE: in the tests below, we use '//root/' as our root directory, since it is
225// a legal *absolute* path on Windows as well as *nix.
Ben Langmuir97882e72014-02-24 20:56:37 +0000226class VFSFromYAMLTest : public ::testing::Test {
227public:
228 int NumDiagnostics;
Ben Langmuir93853232014-03-05 21:32:20 +0000229
Ben Langmuir97882e72014-02-24 20:56:37 +0000230 void SetUp() {
231 NumDiagnostics = 0;
232 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000233
Ben Langmuir97882e72014-02-24 20:56:37 +0000234 static void CountingDiagHandler(const SMDiagnostic &, void *Context) {
235 VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context);
236 ++Test->NumDiagnostics;
237 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000238
Ben Langmuir97882e72014-02-24 20:56:37 +0000239 IntrusiveRefCntPtr<vfs::FileSystem>
240 getFromYAMLRawString(StringRef Content,
241 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
242 MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Content);
243 return getVFSFromYAML(Buffer, CountingDiagHandler, this, ExternalFS);
244 }
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000245
Ben Langmuir97882e72014-02-24 20:56:37 +0000246 IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString(
247 StringRef Content,
248 IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) {
249 std::string VersionPlusContent("{\n 'version':0,\n");
250 VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
251 return getFromYAMLRawString(VersionPlusContent, ExternalFS);
252 }
Ben Langmuir97882e72014-02-24 20:56:37 +0000253};
254
255TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000256 IntrusiveRefCntPtr<vfs::FileSystem> FS;
257 FS = getFromYAMLString("");
Craig Topper416fa342014-06-08 08:38:12 +0000258 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000259 FS = getFromYAMLString("[]");
Craig Topper416fa342014-06-08 08:38:12 +0000260 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000261 FS = getFromYAMLString("'string'");
Craig Topper416fa342014-06-08 08:38:12 +0000262 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000263 EXPECT_EQ(3, NumDiagnostics);
264}
265
Ben Langmuir97882e72014-02-24 20:56:37 +0000266TEST_F(VFSFromYAMLTest, MappedFiles) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000267 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000268 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000269 IntrusiveRefCntPtr<vfs::FileSystem> FS =
270 getFromYAMLString("{ 'roots': [\n"
271 "{\n"
272 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000273 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000274 " 'contents': [ {\n"
275 " 'type': 'file',\n"
276 " 'name': 'file1',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000277 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000278 " },\n"
279 " {\n"
280 " 'type': 'file',\n"
281 " 'name': 'file2',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000282 " 'external-contents': '//root/foo/b'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000283 " }\n"
284 " ]\n"
285 "}\n"
286 "]\n"
287 "}",
288 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000289 ASSERT_TRUE(FS.getPtr() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000290
291 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
292 new vfs::OverlayFileSystem(Lower));
293 O->pushOverlay(FS);
294
295 // file
Ben Langmuir93853232014-03-05 21:32:20 +0000296 ErrorOr<vfs::Status> S = O->status("//root/file1");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000297 ASSERT_FALSE(S.getError());
Ben Langmuir93853232014-03-05 21:32:20 +0000298 EXPECT_EQ("//root/foo/bar/a", S->getName());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000299
Ben Langmuir93853232014-03-05 21:32:20 +0000300 ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
301 EXPECT_EQ("//root/foo/bar/a", SLower->getName());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000302 EXPECT_TRUE(S->equivalent(*SLower));
303
304 // directory
Ben Langmuir93853232014-03-05 21:32:20 +0000305 S = O->status("//root/");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000306 ASSERT_FALSE(S.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000307 EXPECT_TRUE(S->isDirectory());
Ben Langmuir93853232014-03-05 21:32:20 +0000308 EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000309
310 // broken mapping
Rafael Espindola71de0b62014-06-13 17:20:50 +0000311 EXPECT_EQ(O->status("//root/file2").getError(),
312 llvm::errc::no_such_file_or_directory);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000313 EXPECT_EQ(0, NumDiagnostics);
314}
315
Ben Langmuir97882e72014-02-24 20:56:37 +0000316TEST_F(VFSFromYAMLTest, CaseInsensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000317 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000318 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000319 IntrusiveRefCntPtr<vfs::FileSystem> FS =
320 getFromYAMLString("{ 'case-sensitive': 'false',\n"
321 " 'roots': [\n"
322 "{\n"
323 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000324 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000325 " 'contents': [ {\n"
326 " 'type': 'file',\n"
327 " 'name': 'XX',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000328 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000329 " }\n"
330 " ]\n"
331 "}]}",
332 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000333 ASSERT_TRUE(FS.getPtr() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000334
335 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
336 new vfs::OverlayFileSystem(Lower));
337 O->pushOverlay(FS);
338
Ben Langmuir93853232014-03-05 21:32:20 +0000339 ErrorOr<vfs::Status> S = O->status("//root/XX");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000340 ASSERT_FALSE(S.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000341
Ben Langmuir93853232014-03-05 21:32:20 +0000342 ErrorOr<vfs::Status> SS = O->status("//root/xx");
Rafael Espindola3ae06202014-05-31 03:20:52 +0000343 ASSERT_FALSE(SS.getError());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000344 EXPECT_TRUE(S->equivalent(*SS));
Ben Langmuir93853232014-03-05 21:32:20 +0000345 SS = O->status("//root/xX");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000346 EXPECT_TRUE(S->equivalent(*SS));
Ben Langmuir93853232014-03-05 21:32:20 +0000347 SS = O->status("//root/Xx");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000348 EXPECT_TRUE(S->equivalent(*SS));
349 EXPECT_EQ(0, NumDiagnostics);
350}
351
Ben Langmuir97882e72014-02-24 20:56:37 +0000352TEST_F(VFSFromYAMLTest, CaseSensitive) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000353 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000354 Lower->addRegularFile("//root/foo/bar/a");
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000355 IntrusiveRefCntPtr<vfs::FileSystem> FS =
356 getFromYAMLString("{ 'case-sensitive': 'true',\n"
357 " 'roots': [\n"
358 "{\n"
359 " 'type': 'directory',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000360 " 'name': '//root/',\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000361 " 'contents': [ {\n"
362 " 'type': 'file',\n"
363 " 'name': 'XX',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000364 " 'external-contents': '//root/foo/bar/a'\n"
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000365 " }\n"
366 " ]\n"
367 "}]}",
368 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000369 ASSERT_TRUE(FS.getPtr() != nullptr);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000370
371 IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
372 new vfs::OverlayFileSystem(Lower));
373 O->pushOverlay(FS);
374
Ben Langmuir93853232014-03-05 21:32:20 +0000375 ErrorOr<vfs::Status> SS = O->status("//root/xx");
Rafael Espindola71de0b62014-06-13 17:20:50 +0000376 EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
Ben Langmuir93853232014-03-05 21:32:20 +0000377 SS = O->status("//root/xX");
Rafael Espindola71de0b62014-06-13 17:20:50 +0000378 EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
Ben Langmuir93853232014-03-05 21:32:20 +0000379 SS = O->status("//root/Xx");
Rafael Espindola71de0b62014-06-13 17:20:50 +0000380 EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000381 EXPECT_EQ(0, NumDiagnostics);
382}
383
Ben Langmuir97882e72014-02-24 20:56:37 +0000384TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000385 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
386
387 // invalid YAML at top-level
388 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000389 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000390 // invalid YAML in roots
391 FS = getFromYAMLString("{ 'roots':[}", Lower);
392 // invalid YAML in directory
393 FS = getFromYAMLString(
394 "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
395 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000396 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000397
398 // invalid configuration
399 FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000400 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000401 FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000402 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000403
404 // invalid roots
405 FS = getFromYAMLString("{ 'roots':'' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000406 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000407 FS = getFromYAMLString("{ 'roots':{} }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000408 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000409
410 // invalid entries
411 FS = getFromYAMLString(
412 "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000413 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000414 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
415 "'external-contents': 'other' }",
416 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000417 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000418 FS = getFromYAMLString(
419 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
420 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000421 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000422 FS = getFromYAMLString(
423 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
424 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000425 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000426 FS = getFromYAMLString(
427 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
428 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000429 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000430 FS = getFromYAMLString(
431 "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
432 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000433 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000434 FS = getFromYAMLString(
435 "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
436 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000437 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000438
439 // missing mandatory fields
440 FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000441 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000442 FS = getFromYAMLString(
443 "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000444 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000445 FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000446 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000447
448 // duplicate keys
449 FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000450 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000451 FS = getFromYAMLString(
452 "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
453 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000454 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000455 FS =
456 getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
457 "'external-contents':'blah' } ] }",
458 Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000459 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000460
461 // missing version
462 FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000463 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000464
465 // bad version number
466 FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000467 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000468 FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000469 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000470 FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000471 EXPECT_EQ(nullptr, FS.getPtr());
Ben Langmuird51ba0b2014-02-21 23:39:37 +0000472 EXPECT_EQ(24, NumDiagnostics);
473}
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000474
Ben Langmuirb59cf672014-02-27 00:25:12 +0000475TEST_F(VFSFromYAMLTest, UseExternalName) {
476 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000477 Lower->addRegularFile("//root/external/file");
Ben Langmuirb59cf672014-02-27 00:25:12 +0000478
479 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
480 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000481 " { 'type': 'file', 'name': '//root/A',\n"
482 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000483 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000484 " { 'type': 'file', 'name': '//root/B',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000485 " 'use-external-name': true,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000486 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000487 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000488 " { 'type': 'file', 'name': '//root/C',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000489 " 'use-external-name': false,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000490 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000491 " }\n"
492 "] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000493 ASSERT_TRUE(nullptr != FS.getPtr());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000494
495 // default true
Ben Langmuir93853232014-03-05 21:32:20 +0000496 EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000497 // explicit
Ben Langmuir93853232014-03-05 21:32:20 +0000498 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
499 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000500
501 // global configuration
502 FS = getFromYAMLString(
503 "{ 'use-external-names': false,\n"
504 " 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000505 " { 'type': 'file', 'name': '//root/A',\n"
506 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000507 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000508 " { 'type': 'file', 'name': '//root/B',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000509 " 'use-external-name': true,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000510 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000511 " },\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000512 " { 'type': 'file', 'name': '//root/C',\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000513 " 'use-external-name': false,\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000514 " 'external-contents': '//root/external/file'\n"
Ben Langmuirb59cf672014-02-27 00:25:12 +0000515 " }\n"
516 "] }", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000517 ASSERT_TRUE(nullptr != FS.getPtr());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000518
519 // default
Ben Langmuir93853232014-03-05 21:32:20 +0000520 EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000521 // explicit
Ben Langmuir93853232014-03-05 21:32:20 +0000522 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
523 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
Ben Langmuirb59cf672014-02-27 00:25:12 +0000524}
525
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000526TEST_F(VFSFromYAMLTest, MultiComponentPath) {
527 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000528 Lower->addRegularFile("//root/other");
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000529
530 // file in roots
531 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
532 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000533 " { 'type': 'file', 'name': '//root/path/to/file',\n"
534 " 'external-contents': '//root/other' }]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000535 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000536 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000537 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
538 EXPECT_FALSE(FS->status("//root/path/to").getError());
539 EXPECT_FALSE(FS->status("//root/path").getError());
540 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000541
542 // at the start
543 FS = getFromYAMLString(
544 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000545 " { 'type': 'directory', 'name': '//root/path/to',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000546 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000547 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000548 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000549 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000550 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
551 EXPECT_FALSE(FS->status("//root/path/to").getError());
552 EXPECT_FALSE(FS->status("//root/path").getError());
553 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000554
555 // at the end
556 FS = getFromYAMLString(
557 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000558 " { 'type': 'directory', 'name': '//root/',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000559 " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000560 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000561 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000562 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000563 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
564 EXPECT_FALSE(FS->status("//root/path/to").getError());
565 EXPECT_FALSE(FS->status("//root/path").getError());
566 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000567}
568
569TEST_F(VFSFromYAMLTest, TrailingSlashes) {
570 IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
Ben Langmuir93853232014-03-05 21:32:20 +0000571 Lower->addRegularFile("//root/other");
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000572
573 // file in roots
574 IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
575 "{ 'roots': [\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000576 " { 'type': 'directory', 'name': '//root/path/to////',\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000577 " 'contents': [ { 'type': 'file', 'name': 'file',\n"
Ben Langmuir93853232014-03-05 21:32:20 +0000578 " 'external-contents': '//root/other' }]}]\n"
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000579 "}", Lower);
Craig Topper416fa342014-06-08 08:38:12 +0000580 ASSERT_TRUE(nullptr != FS.getPtr());
Rafael Espindola3ae06202014-05-31 03:20:52 +0000581 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
582 EXPECT_FALSE(FS->status("//root/path/to").getError());
583 EXPECT_FALSE(FS->status("//root/path").getError());
584 EXPECT_FALSE(FS->status("//root/").getError());
Ben Langmuir47ff9ab2014-02-25 04:34:14 +0000585}