Lines Matching +full:root +full:- +full:relative
1 //===- unittests/Support/VirtualFileSystem.cpp -------------- VFS tests ---===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 #include "llvm/Config/llvm-config.h"
67 return I->second;
89 if (I->second.isSymlink()) {
106 if (LastSep == Path.size() || LastSep == Path.size() - 1)
116 if (isInPath(I->first)) {
117 CurrentEntry = vfs::directory_entry(std::string(I->second.getName()),
118 I->second.getType());
126 if (isInPath(I->first)) {
127 CurrentEntry = vfs::directory_entry(std::string(I->second.getName()),
128 I->second.getType());
215 return Status && Status->exists();
219 /// Replace back-slashes by front-slashes.
231 D->addRegularFile("/foo");
232 Status = D->status("/foo");
234 EXPECT_TRUE(Status->isStatusKnown());
235 EXPECT_FALSE(Status->isDirectory());
236 EXPECT_TRUE(Status->isRegularFile());
237 EXPECT_FALSE(Status->isSymlink());
238 EXPECT_FALSE(Status->isOther());
239 EXPECT_TRUE(Status->exists());
241 D->addDirectory("/bar");
242 Status = D->status("/bar");
244 EXPECT_TRUE(Status->isStatusKnown());
245 EXPECT_TRUE(Status->isDirectory());
246 EXPECT_FALSE(Status->isRegularFile());
247 EXPECT_FALSE(Status->isSymlink());
248 EXPECT_FALSE(Status->isOther());
249 EXPECT_TRUE(Status->exists());
251 D->addSymlink("/baz");
252 Status = D->status("/baz");
254 EXPECT_TRUE(Status->isStatusKnown());
255 EXPECT_FALSE(Status->isDirectory());
256 EXPECT_FALSE(Status->isRegularFile());
257 EXPECT_TRUE(Status->isSymlink());
258 EXPECT_FALSE(Status->isOther());
259 EXPECT_TRUE(Status->exists());
261 EXPECT_TRUE(Status->equivalent(*Status));
262 ErrorOr<vfs::Status> Status2 = D->status("/foo");
264 EXPECT_FALSE(Status->equivalent(*Status2));
270 EXPECT_FALSE(Status = D->status("/foo"));
273 EXPECT_FALSE(Status = O->status("/foo"));
275 D->addRegularFile("/foo");
276 Status = D->status("/foo");
280 Status2 = O->status("/foo");
282 EXPECT_TRUE(Status->equivalent(*Status2));
287 Lower->addRegularFile("/foo");
288 Lower->addSymlink("/lower_link");
293 O->pushOverlay(Upper);
297 EXPECT_FALSE(O->getRealPath("/foo", RealPath));
301 EXPECT_FALSE(O->getRealPath("/lower_link", RealPath));
304 // Try a non-existing link.
305 EXPECT_EQ(O->getRealPath("/upper_link", RealPath),
309 Upper->addSymlink("/upper_link");
310 EXPECT_FALSE(O->getRealPath("/upper_link", RealPath));
320 O->pushOverlay(Middle);
321 O->pushOverlay(Top);
328 Base->addRegularFile("/foo");
329 StatusB = Base->status("/foo");
331 Status1 = O->status("/foo");
333 Middle->addRegularFile("/foo");
334 StatusM = Middle->status("/foo");
336 Status2 = O->status("/foo");
338 Top->addRegularFile("/foo");
339 StatusT = Top->status("/foo");
341 Status3 = O->status("/foo");
344 EXPECT_TRUE(Status1->equivalent(*StatusB));
345 EXPECT_TRUE(Status2->equivalent(*StatusM));
346 EXPECT_TRUE(Status3->equivalent(*StatusT));
348 EXPECT_FALSE(Status1->equivalent(*Status2));
349 EXPECT_FALSE(Status2->equivalent(*Status3));
350 EXPECT_FALSE(Status1->equivalent(*Status3));
358 O->pushOverlay(Upper);
360 Lower->addDirectory("/lower-only");
361 Upper->addDirectory("/upper-only");
363 // non-merged paths should be the same
364 ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
366 ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
368 EXPECT_TRUE(Status1->equivalent(*Status2));
370 Status1 = Upper->status("/upper-only");
372 Status2 = O->status("/upper-only");
374 EXPECT_TRUE(Status1->equivalent(*Status2));
383 O->pushOverlay(Upper);
386 Lower->addDirectory("/both", sys::fs::owner_read);
387 Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
388 Status = O->status("/both");
390 EXPECT_EQ(0740, Status->getPermissions());
393 Lower->addRegularFile("/both/foo", sys::fs::owner_read);
394 Upper->addRegularFile("/both/bar", sys::fs::owner_write);
395 Status = O->status("/both/foo");
397 EXPECT_EQ(0400, Status->getPermissions());
398 Status = O->status("/both/bar");
400 EXPECT_EQ(0200, Status->getPermissions());
405 Lower->addRegularFile("/foo");
410 O->pushOverlay(Upper);
414 auto it = O->overlays_begin();
415 auto end = O->overlays_end();
419 Status = (*it)->status("/foo");
425 Status = (*it)->status("/foo");
427 EXPECT_TRUE(Status->exists());
434 auto it = O->overlays_rbegin();
435 auto end = O->overlays_rend();
439 Status = (*it)->status("/foo");
441 EXPECT_TRUE(Status->exists());
446 Status = (*it)->status("/foo");
455 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
459 vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory.path()), EC);
468 I = FS->dir_begin(Twine(TestDirectory.path()), EC);
472 EXPECT_TRUE(I->path().ends_with("a") || I->path().ends_with("c"));
476 EXPECT_TRUE(I->path().ends_with("a") || I->path().ends_with("c"));
483 // Our root contains a/aa, b/bb, c, where c is a link to a/.
484 // Run tests both in root/b/ and root/c/ (to test "normal" and symlink dirs).
486 TempDir Root("r", /*Unique*/ true);
487 TempDir ADir(Root.path("a"));
488 TempDir BDir(Root.path("b"));
489 TempLink C(ADir.path(), Root.path("c"));
495 ASSERT_FALSE(BFS->setCurrentWorkingDirectory(BDir.path()));
496 ASSERT_FALSE(CFS->setCurrentWorkingDirectory(C.path()));
497 EXPECT_EQ(BDir.path(), *BFS->getCurrentWorkingDirectory());
498 EXPECT_EQ(C.path(), *CFS->getCurrentWorkingDirectory());
501 auto BBuf = BFS->getBufferForFile("bb");
503 EXPECT_EQ("bbbb", (*BBuf)->getBuffer());
505 auto ABuf = CFS->getBufferForFile("aa");
507 EXPECT_EQ("aaaa", (*ABuf)->getBuffer());
510 auto BStat = BFS->status("bb");
512 EXPECT_EQ("bb", BStat->getName());
514 auto AStat = CFS->status("aa");
516 EXPECT_EQ("aa", AStat->getName()); // unresolved name
520 ASSERT_FALSE(BFS->getRealPath("bb", BPath));
524 ASSERT_FALSE(CFS->getRealPath("aa", APath));
529 auto BIt = BFS->dir_begin(".", EC);
532 EXPECT_EQ((BDir.path() + "/./bb").str(), BIt->path());
537 auto CIt = CFS->dir_begin(".", EC);
541 CIt->path()); // Partly resolved name!
564 ASSERT_EQ(FS1->getCurrentWorkingDirectory().getError(),
566 ASSERT_EQ(FS1->setCurrentWorkingDirectory(D2.path()), std::error_code());
567 ASSERT_EQ(FS1->getCurrentWorkingDirectory().get(), D2.path());
568 EXPECT_EQ(FS2->getCurrentWorkingDirectory().getError(),
575 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
586 I = FS->dir_begin(Twine(TestDirectory.path()), EC),
590 StatResults[std::string(sys::path::filename(I->path()))] =
591 FS->status(I->path()).getError();
604 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
625 Contents.push_back(std::string(I->path()));
633 int Index = Name[Name.size() - 1] - 'a';
645 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
667 Contents.push_back(std::string(I->path()));
668 char last = I->path().back();
693 Contents.push_back(std::string(I->path()));
694 char last = I->path().back();
711 int Index = Name[Name.size() - 1] - 'a';
728 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
750 (FS->status(I->path()) ? VisitedNonBrokenSymlinks : VisitedBrokenSymlinks)
751 .push_back(std::string(I->path()));
775 InputToCheck.push_back(std::string(I->path()));
791 O->pushOverlay(Upper);
794 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
796 Lower->addRegularFile("/file1");
797 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1"));
799 Upper->addRegularFile("/file2");
800 checkContents(O->dir_begin("/", EC), {"/file2", "/file1"});
802 Lower->addDirectory("/dir1");
803 Lower->addRegularFile("/dir1/foo");
804 Upper->addDirectory("/dir2");
805 Upper->addRegularFile("/dir2/foo");
806 checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo"));
807 checkContents(O->dir_begin("/", EC), {"/dir2", "/file2", "/dir1", "/file1"});
816 O->pushOverlay(Middle);
817 O->pushOverlay(Upper);
823 Lower->addRegularFile("/file1");
827 Upper->addDirectory("/dir");
828 Upper->addRegularFile("/dir/file2");
832 Lower->addDirectory("/dir1");
833 Lower->addRegularFile("/dir1/foo");
834 Lower->addDirectory("/dir1/a");
835 Lower->addRegularFile("/dir1/a/b");
836 Middle->addDirectory("/a");
837 Middle->addDirectory("/a/b");
838 Middle->addDirectory("/a/b/c");
839 Middle->addRegularFile("/a/b/c/d");
840 Middle->addRegularFile("/hiddenByUp");
841 Upper->addDirectory("/dir2");
842 Upper->addRegularFile("/dir2/foo");
843 Upper->addRegularFile("/hiddenByUp");
858 O->pushOverlay(Middle);
859 O->pushOverlay(Upper);
862 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
864 Middle->addRegularFile("/file2");
865 checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2"));
867 Lower->addRegularFile("/file1");
868 Upper->addRegularFile("/file3");
869 checkContents(O->dir_begin("/", EC), {"/file3", "/file2", "/file1"});
878 O->pushOverlay(Middle);
879 O->pushOverlay(Upper);
882 Lower->addRegularFile("/onlyInLow");
883 Lower->addDirectory("/hiddenByMid");
884 Lower->addDirectory("/hiddenByUp");
885 Middle->addRegularFile("/onlyInMid");
886 Middle->addRegularFile("/hiddenByMid");
887 Middle->addDirectory("/hiddenByUp");
888 Upper->addRegularFile("/onlyInUp");
889 Upper->addRegularFile("/hiddenByUp");
891 O->dir_begin("/", EC),
894 // Make sure we get the top-most entry
897 vfs::directory_iterator I = O->dir_begin("/", EC), E;
899 if (I->path() == "/hiddenByUp")
902 EXPECT_EQ(sys::fs::file_type::regular_file, I->type());
906 vfs::directory_iterator I = O->dir_begin("/", EC), E;
908 if (I->path() == "/hiddenByMid")
911 EXPECT_EQ(sys::fs::file_type::regular_file, I->type());
921 O->pushOverlay(Middle);
922 O->pushOverlay(Top);
927 " 'redirecting-with': 'redirect-only',\n"
932 " 'external-contents': '/a',\n"
959 Overlay1->pushOverlay(Dummy);
961 Overlay2->pushOverlay(Dummy);
966 Overlay2->print(OuputStream, vfs::FileSystem::PrintType::Summary);
970 Overlay2->print(OuputStream, vfs::FileSystem::PrintType::Contents);
977 Overlay2->print(OuputStream, vfs::FileSystem::PrintType::RecursiveContents);
991 O->pushOverlay(Upper);
993 Lower->addDirectory("/both");
994 Upper->addDirectory("/both");
995 Lower->addRegularFile("/both/lower_file");
996 Upper->addRegularFile("/both/upper_file");
997 Lower->addDirectory("/lower");
998 Upper->addDirectory("/upper");
1000 EXPECT_TRUE(O->exists("/both"));
1001 EXPECT_TRUE(O->exists("/both"));
1002 EXPECT_TRUE(O->exists("/both/lower_file"));
1003 EXPECT_TRUE(O->exists("/both/upper_file"));
1004 EXPECT_TRUE(O->exists("/lower"));
1005 EXPECT_TRUE(O->exists("/upper"));
1006 EXPECT_FALSE(O->exists("/both/nope"));
1007 EXPECT_FALSE(O->exists("/nope"));
1015 Base->addFile("/a", 0, MemoryBuffer::getMemBuffer("test"));
1022 EXPECT_EQ("test", (*(*File)->getBuffer("ignored"))->getBuffer());
1027 ASSERT_EQ("/a", I->path());
1060 auto OpenedFrom = FS->openFileForRead(From);
1061 auto OpenedTo = FS->openFileForRead(To);
1063 (*OpenedFrom)->status()->getUniqueID() ==
1064 (*OpenedTo)->status()->getUniqueID();
1098 ASSERT_EQ("/a", Stat->getName());
1106 ASSERT_EQ("/a", Stat->getName());
1117 ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
1119 ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
1121 ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
1131 ASSERT_EQ("c", (*(*File)->getBuffer("ignored"))->getBuffer());
1133 ASSERT_EQ("d", (*(*File)->getBuffer("ignored"))->getBuffer());
1155 ASSERT_EQ("/a", I->path());
1158 ASSERT_EQ("/b", I->path());
1167 ASSERT_EQ("/b/c", getPosixPath(std::string(I->path())));
1179 ASSERT_EQ("/b/c", Stat->getName());
1233 ASSERT_TRUE(Stat->isDirectory());
1234 ASSERT_EQ(0xFEEDFACE, Stat->getUser());
1237 ASSERT_TRUE(Stat->isDirectory());
1238 ASSERT_EQ(0xFEEDFACE, Stat->getUser());
1241 ASSERT_TRUE(Stat->isRegularFile());
1242 ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions());
1243 ASSERT_EQ(0xFEEDFACE, Stat->getUser());
1251 ASSERT_TRUE(Stat->isDirectory());
1252 ASSERT_EQ(0xDABBAD00, Stat->getGroup());
1254 ASSERT_TRUE(Stat->isDirectory());
1256 ASSERT_EQ(0xDABBAD00, Stat->getGroup());
1259 ASSERT_TRUE(Stat->isRegularFile());
1260 ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions());
1261 ASSERT_EQ(0xDABBAD00, Stat->getGroup());
1269 ASSERT_TRUE(Stat->isDirectory());
1272 ASSERT_TRUE(Stat->isDirectory());
1275 ASSERT_EQ(sys::fs::file_type::socket_file, Stat->getType());
1276 ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions());
1285 ASSERT_TRUE(Stat->isDirectory());
1288 Stat->getPermissions());
1291 ASSERT_TRUE(Stat->isDirectory());
1294 Stat->getPermissions());
1297 ASSERT_TRUE(Stat->isRegularFile());
1299 Stat->getPermissions());
1310 ASSERT_TRUE(Stat->isDirectory());
1313 ASSERT_TRUE(Stat->isRegularFile());
1329 ASSERT_TRUE(Stat->isRegularFile());
1330 ASSERT_EQ("../b/c", Stat->getName());
1336 Stat = (*File)->status();
1339 ASSERT_TRUE(Stat->isRegularFile());
1340 ASSERT_EQ("../b/c", Stat->getName());
1347 ASSERT_EQ("../b/c", getPosixPath(std::string(It->path())));
1356 EXPECT_EQ(FS.status(FromLink)->getSize(), FS.status(Target)->getSize());
1357 EXPECT_EQ(FS.getBufferForFile(FromLink)->get()->getBuffer(),
1358 FS.getBufferForFile(Target)->get()->getBuffer());
1427 EXPECT_EQ((*FS.getBufferForFile("/hardlink"))->getBuffer(), "content");
1454 Nodes.push_back(getPosixPath(std::string(I->path())));
1464 EXPECT_EQ(FS.status("/a/b")->getUniqueID(), FS.status("/a/b")->getUniqueID());
1465 EXPECT_NE(FS.status("/a/b")->getUniqueID(), FS.status("/c/d")->getUniqueID());
1466 EXPECT_EQ(FS.status("/a/b")->getUniqueID(), FS.status("/e/f")->getUniqueID());
1467 EXPECT_EQ(FS.status("/a")->getUniqueID(), FS.status("/a")->getUniqueID());
1468 EXPECT_NE(FS.status("/a")->getUniqueID(), FS.status("/c")->getUniqueID());
1469 EXPECT_NE(FS.status("/a")->getUniqueID(), FS.status("/e")->getUniqueID());
1475 EXPECT_EQ(FS.status("/a/b")->getUniqueID(),
1476 FS2.status("/a/b")->getUniqueID());
1477 EXPECT_EQ(FS.status("/a")->getUniqueID(), FS2.status("/a")->getUniqueID());
1485 EXPECT_TRUE(Stat->isRegularFile());
1495 EXPECT_TRUE(Stat->isRegularFile());
1505 // Follow-through symlinks by default. This matches RealFileSystem's
1507 EXPECT_TRUE(Stat->isRegularFile());
1511 EXPECT_TRUE(Stat->isRegularFile());
1515 EXPECT_TRUE(Stat->isRegularFile());
1519 EXPECT_TRUE(FS.addSymbolicLink("/link-a", "/link-b", 0));
1520 EXPECT_TRUE(FS.addSymbolicLink("/link-b", "/link-a", 0));
1521 ErrorOr<vfs::Status> Stat = FS.status("/link-a/foo");
1537 Nodes.push_back(getPosixPath(std::string(I->path())));
1553 Nodes.push_back(getPosixPath(std::string(I->path())));
1559 // NOTE: in the tests below, we use '//root/' as our root directory, since it is
1569 ++Test->NumDiagnostics;
1610 Lower->addDirectory("//root/foo/bar");
1611 Lower->addRegularFile("//root/foo/bar/a");
1616 " 'name': '//root/',\n"
1620 " 'external-contents': '//root/foo/bar/a'\n"
1625 " 'external-contents': '//root/foo/b'\n"
1628 " 'type': 'directory-remap',\n"
1630 " 'external-contents': '//root/foo/bar'\n"
1633 " 'type': 'directory-remap',\n"
1635 " 'use-external-name': false,\n"
1636 " 'external-contents': '//root/foo/bar'\n"
1647 O->pushOverlay(FS);
1650 ErrorOr<vfs::Status> S = O->status("//root/file1");
1652 EXPECT_EQ("//root/foo/bar/a", S->getName());
1653 EXPECT_TRUE(S->ExposesExternalVFSPath);
1655 ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
1656 EXPECT_EQ("//root/foo/bar/a", SLower->getName());
1657 EXPECT_TRUE(S->equivalent(*SLower));
1658 EXPECT_FALSE(SLower->ExposesExternalVFSPath);
1661 auto OpenedF = O->openFileForRead("//root/file1");
1663 auto OpenedS = (*OpenedF)->status();
1665 EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
1666 EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1669 S = O->status("//root/");
1671 EXPECT_TRUE(S->isDirectory());
1672 EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
1675 S = O->status("//root/mappeddir");
1677 EXPECT_TRUE(S->isDirectory());
1678 EXPECT_TRUE(S->ExposesExternalVFSPath);
1679 EXPECT_TRUE(S->equivalent(*O->status("//root/foo/bar")));
1681 SLower = O->status("//root/foo/bar");
1682 EXPECT_EQ("//root/foo/bar", SLower->getName());
1683 EXPECT_TRUE(S->equivalent(*SLower));
1684 EXPECT_FALSE(SLower->ExposesExternalVFSPath);
1687 S = O->status("//root/mappeddir/a");
1689 EXPECT_FALSE(S->isDirectory());
1690 EXPECT_TRUE(S->ExposesExternalVFSPath);
1691 EXPECT_EQ("//root/foo/bar/a", S->getName());
1693 // file in remapped directory, with use-external-name=false
1694 S = O->status("//root/mappeddir2/a");
1696 EXPECT_FALSE(S->isDirectory());
1697 EXPECT_FALSE(S->ExposesExternalVFSPath);
1698 EXPECT_EQ("//root/mappeddir2/a", S->getName());
1701 OpenedF = O->openFileForRead("//root/mappeddir/a");
1703 OpenedS = (*OpenedF)->status();
1705 EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
1706 EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1708 // file contents in remapped directory, with use-external-name=false
1709 OpenedF = O->openFileForRead("//root/mappeddir2/a");
1711 OpenedS = (*OpenedF)->status();
1713 EXPECT_EQ("//root/mappeddir2/a", OpenedS->getName());
1714 EXPECT_FALSE(OpenedS->ExposesExternalVFSPath);
1717 EXPECT_EQ(O->status("//root/file2").getError(),
1724 Lower->addDirectory("//root/foo/bar");
1725 Lower->addRegularFile("//root/foo/bar/a");
1729 " 'type': 'directory-remap',\n"
1731 " 'external-contents': '//root/foo/bar'\n"
1740 O->pushOverlay(FS);
1743 ErrorOr<vfs::Status> S = O->status("//mappedroot/a");
1745 EXPECT_EQ("//root/foo/bar/a", S->getName());
1746 EXPECT_TRUE(S->ExposesExternalVFSPath);
1748 ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
1749 EXPECT_EQ("//root/foo/bar/a", SLower->getName());
1750 EXPECT_TRUE(S->equivalent(*SLower));
1751 EXPECT_FALSE(SLower->ExposesExternalVFSPath);
1754 auto OpenedF = O->openFileForRead("//mappedroot/a");
1756 auto OpenedS = (*OpenedF)->status();
1758 EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
1759 EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1766 Lower->addDirectory("//root/foo");
1767 Lower->addRegularFile("//root/foo/a");
1768 Lower->addDirectory("//root/bar");
1769 Lower->addRegularFile("//root/bar/b");
1770 Lower->addRegularFile("//root/bar/c");
1775 " 'name': '//root/',\n"
1777 " 'type': 'directory-remap',\n"
1779 " 'external-contents': '//root/foo'\n"
1788 O->pushOverlay(FS);
1790 ErrorOr<vfs::Status> S = O->status("//root/foo");
1793 ErrorOr<vfs::Status> SS = O->status("//root/bar");
1795 EXPECT_TRUE(S->equivalent(*SS));
1798 checkContents(O->dir_begin("//root/bar", EC),
1799 {"//root/foo/a", "//root/bar/b", "//root/bar/c"});
1801 Lower->addRegularFile("//root/foo/b");
1802 checkContents(O->dir_begin("//root/bar", EC),
1803 {"//root/foo/a", "//root/foo/b", "//root/bar/c"});
1810 Lower->addDirectory("//root/foo");
1811 Lower->addRegularFile("//root/foo/a");
1812 Lower->addDirectory("//root/bar");
1813 Lower->addRegularFile("//root/bar/b");
1814 Lower->addRegularFile("//root/bar/c");
1816 getFromYAMLString("{ 'use-external-names': false,\n"
1820 " 'name': '//root/',\n"
1822 " 'type': 'directory-remap',\n"
1824 " 'external-contents': '//root/foo'\n"
1831 ErrorOr<vfs::Status> S = FS->status("//root/foo");
1834 ErrorOr<vfs::Status> SS = FS->status("//root/bar");
1836 EXPECT_TRUE(S->equivalent(*SS));
1839 checkContents(FS->dir_begin("//root/bar", EC),
1840 {"//root/bar/a", "//root/bar/b", "//root/bar/c"});
1842 Lower->addRegularFile("//root/foo/b");
1843 checkContents(FS->dir_begin("//root/bar", EC),
1844 {"//root/bar/a", "//root/bar/b", "//root/bar/c"});
1851 Lower->addDirectory("//root/foo");
1852 Lower->addRegularFile("//root/foo/a");
1853 Lower->addDirectory("//root/bar");
1854 Lower->addRegularFile("//root/bar/b");
1855 Lower->addRegularFile("//root/bar/c");
1861 " 'name': '//root/',\n"
1863 " 'type': 'directory-remap',\n"
1865 " 'external-contents': '//root/foo'\n"
1872 ErrorOr<vfs::Status> S = Lower->status("//root/foo");
1875 ErrorOr<vfs::Status> SS = FS->status("//root/bar");
1877 EXPECT_TRUE(S->equivalent(*SS));
1880 checkContents(FS->dir_begin("//root/bar", EC), {"//root/foo/a"});
1882 Lower->addRegularFile("//root/foo/b");
1883 checkContents(FS->dir_begin("//root/bar", EC),
1884 {"//root/foo/a", "//root/foo/b"});
1892 BaseFS->addFile("//root/foo/a", 0,
1894 ASSERT_FALSE(BaseFS->setCurrentWorkingDirectory("//root/foo"));
1898 auto OpenedF = RemappedFS->openFileForRead("a");
1900 llvm::ErrorOr<std::string> Name = (*OpenedF)->getName();
1904 auto OpenedS = (*OpenedF)->status();
1906 EXPECT_EQ("a", OpenedS->getName());
1907 EXPECT_FALSE(OpenedS->ExposesExternalVFSPath);
1909 auto DirectS = RemappedFS->status("a");
1911 EXPECT_EQ("a", DirectS->getName());
1912 EXPECT_FALSE(DirectS->ExposesExternalVFSPath);
1920 BaseFS->addFile("//root/foo/realname", 0,
1923 getFromYAMLString("{ 'use-external-names': true,\n"
1927 " 'name': '//root/foo',\n"
1931 " 'external-contents': 'realname'\n"
1936 ASSERT_FALSE(FS->setCurrentWorkingDirectory("//root/foo"));
1938 auto OpenedF = FS->openFileForRead("vfsname");
1940 llvm::ErrorOr<std::string> Name = (*OpenedF)->getName();
1944 auto OpenedS = (*OpenedF)->status();
1946 EXPECT_EQ("realname", OpenedS->getName());
1947 EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1949 auto DirectS = FS->status("vfsname");
1951 EXPECT_EQ("realname", DirectS->getName());
1952 EXPECT_TRUE(DirectS->ExposesExternalVFSPath);
1959 Lower->addDirectory("//root/foo/bar");
1960 Lower->addRegularFile("//root/foo/bar/a");
1963 " 'case-sensitive': false,\n"
1964 " 'root-relative': 'overlay-dir',\n"
1967 " 'external-contents': '//root/foo/bar/a'\n"
1971 Lower, "//root/foo/bar/overlay");
1974 ErrorOr<vfs::Status> S = FS->status("//root/foo/bar/b");
1976 EXPECT_EQ("//root/foo/bar/a", S->getName());
1978 // On Windows, with overlay-relative set to true, the relative
1979 // path in external-contents field will be prepend by OverlayDir
1984 " 'case-sensitive': false,\n"
1985 " 'overlay-relative': true,\n"
1986 " 'root-relative': 'overlay-dir',\n"
1989 " 'external-contents': 'a'\n"
1993 Lower, "//root/foo/bar/overlay");
1995 S = FS->status("//root/foo/bar/b");
1997 EXPECT_EQ("//root/foo/bar/a", S->getName());
2000 LowerWindows->addDirectory("\\\\root\\foo\\bar");
2001 LowerWindows->addRegularFile("\\\\root\\foo\\bar\\a");
2003 " 'case-sensitive': false,\n"
2004 " 'overlay-relative': true,\n"
2005 " 'root-relative': 'overlay-dir',\n"
2008 " 'external-contents': 'a'\n"
2012 LowerWindows, "\\\\root\\foo\\bar\\overlay");
2014 S = FS->status("\\\\root\\foo\\bar\\b");
2016 EXPECT_EQ("\\\\root\\foo\\bar\\a", S->getName());
2023 BaseFS->addFile("//root/foo/realname", 0,
2026 getFromYAMLString("{ 'use-external-names': false,\n"
2030 " 'name': '//root/foo',\n"
2034 " 'external-contents': 'realname'\n"
2039 ASSERT_FALSE(FS->setCurrentWorkingDirectory("//root/foo"));
2041 auto OpenedF = FS->openFileForRead("vfsname");
2043 llvm::ErrorOr<std::string> Name = (*OpenedF)->getName();
2047 auto OpenedS = (*OpenedF)->status();
2049 EXPECT_EQ("vfsname", OpenedS->getName());
2050 EXPECT_FALSE(OpenedS->ExposesExternalVFSPath);
2052 auto DirectS = FS->status("vfsname");
2054 EXPECT_EQ("vfsname", DirectS->getName());
2055 EXPECT_FALSE(DirectS->ExposesExternalVFSPath);
2062 Lower->addRegularFile("//root/foo/bar/a");
2064 "{ 'case-sensitive': 'false',\n"
2068 " 'name': '//root/',\n"
2072 " 'external-contents': '//root/foo/bar/a'\n"
2081 O->pushOverlay(FS);
2083 ErrorOr<vfs::Status> S = O->status("//root/XX");
2086 ErrorOr<vfs::Status> SS = O->status("//root/xx");
2088 EXPECT_TRUE(S->equivalent(*SS));
2089 SS = O->status("//root/xX");
2090 EXPECT_TRUE(S->equivalent(*SS));
2091 SS = O->status("//root/Xx");
2092 EXPECT_TRUE(S->equivalent(*SS));
2098 Lower->addRegularFile("//root/foo/bar/a");
2100 "{ 'case-sensitive': 'true',\n"
2104 " 'name': '//root/',\n"
2108 " 'external-contents': '//root/foo/bar/a'\n"
2117 O->pushOverlay(FS);
2119 ErrorOr<vfs::Status> SS = O->status("//root/xx");
2121 SS = O->status("//root/xX");
2123 SS = O->status("//root/Xx");
2131 // invalid YAML at top-level
2145 FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
2159 "'external-contents': 'other' }",
2163 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
2167 "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
2187 "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
2196 "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
2201 "'external-contents':'blah' } ] }",
2212 FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
2217 // both 'external-contents' and 'contents' specified
2218 Lower->addDirectory("//root/external/dir");
2221 "{ 'type': 'directory', 'name': '//root/A', 'contents': [],\n"
2222 " 'external-contents': '//root/external/dir'}]}",
2226 // 'directory-remap' with 'contents'
2229 "{ 'type': 'directory-remap', 'name': '//root/A', 'contents': [] }]}",
2234 FS = getFromYAMLString("{ 'redirecting-with': 'none', 'roots': [{\n"
2235 " 'type': 'directory-remap',\n"
2236 " 'name': '//root/A',\n"
2237 " 'external-contents': '//root/B' }]}",
2242 FS = getFromYAMLString("{ 'redirecting-with': 'fallthrough',\n"
2245 " 'type': 'directory-remap',\n"
2246 " 'name': '//root/A',\n"
2247 " 'external-contents': '//root/B' }]}",
2256 Lower->addRegularFile("//root/external/file");
2260 " { 'type': 'file', 'name': '//root/A',\n"
2261 " 'external-contents': '//root/external/file'\n"
2263 " { 'type': 'file', 'name': '//root/B',\n"
2264 " 'use-external-name': true,\n"
2265 " 'external-contents': '//root/external/file'\n"
2267 " { 'type': 'file', 'name': '//root/C',\n"
2268 " 'use-external-name': false,\n"
2269 " 'external-contents': '//root/external/file'\n"
2276 EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
2278 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
2279 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
2282 FS = getFromYAMLString("{ 'use-external-names': false,\n"
2284 " { 'type': 'file', 'name': '//root/A',\n"
2285 " 'external-contents': '//root/external/file'\n"
2287 " { 'type': 'file', 'name': '//root/B',\n"
2288 " 'use-external-name': true,\n"
2289 " 'external-contents': '//root/external/file'\n"
2291 " { 'type': 'file', 'name': '//root/C',\n"
2292 " 'use-external-name': false,\n"
2293 " 'external-contents': '//root/external/file'\n"
2300 EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
2302 EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
2303 EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
2308 Lower->addRegularFile("//root/other");
2313 " { 'type': 'file', 'name': '//root/path/to/file',\n"
2314 " 'external-contents': '//root/other' }]\n"
2318 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
2319 EXPECT_FALSE(FS->status("//root/path/to").getError());
2320 EXPECT_FALSE(FS->status("//root/path").getError());
2321 EXPECT_FALSE(FS->status("//root/").getError());
2326 " { 'type': 'directory', 'name': '//root/path/to',\n"
2328 " 'external-contents': '//root/other' }]}]\n"
2332 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
2333 EXPECT_FALSE(FS->status("//root/path/to").getError());
2334 EXPECT_FALSE(FS->status("//root/path").getError());
2335 EXPECT_FALSE(FS->status("//root/").getError());
2340 " { 'type': 'directory', 'name': '//root/',\n"
2342 " 'external-contents': '//root/other' }]}]\n"
2346 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
2347 EXPECT_FALSE(FS->status("//root/path/to").getError());
2348 EXPECT_FALSE(FS->status("//root/path").getError());
2349 EXPECT_FALSE(FS->status("//root/").getError());
2354 Lower->addRegularFile("//root/other");
2359 " { 'type': 'directory', 'name': '//root/path/to////',\n"
2361 " 'external-contents': '//root/other' }]}]\n"
2365 EXPECT_FALSE(FS->status("//root/path/to/file").getError());
2366 EXPECT_FALSE(FS->status("//root/path/to").getError());
2367 EXPECT_FALSE(FS->status("//root/path").getError());
2368 EXPECT_FALSE(FS->status("//root/").getError());
2373 Lower->addDirectory("//root/");
2374 Lower->addDirectory("//root/foo");
2375 Lower->addDirectory("//root/foo/bar");
2376 Lower->addRegularFile("//root/foo/bar/a");
2377 Lower->addRegularFile("//root/foo/bar/b");
2378 Lower->addRegularFile("//root/file3");
2380 "{ 'use-external-names': false,\n"
2384 " 'name': '//root/',\n"
2388 " 'external-contents': '//root/foo/bar/a'\n"
2393 " 'external-contents': '//root/foo/bar/b'\n"
2404 O->pushOverlay(FS);
2407 checkContents(O->dir_begin("//root/", EC),
2408 {"//root/file1", "//root/file2", "//root/file3", "//root/foo"});
2410 checkContents(O->dir_begin("//root/foo/bar", EC),
2411 {"//root/foo/bar/a", "//root/foo/bar/b"});
2420 Lower->addDirectory("//root/zab");
2421 Lower->addDirectory("//root/baz");
2422 Lower->addRegularFile("//root/zab/a");
2423 Lower->addRegularFile("//root/zab/b");
2425 "{ 'use-external-names': false,\n"
2429 " 'name': '//root/baz/',\n"
2433 " 'external-contents': '//root/zab/a'\n"
2439 " 'name': '//root/baz/',\n"
2443 " 'external-contents': '//root/zab/b'\n"
2454 O->pushOverlay(FS);
2458 checkContents(O->dir_begin("//root/baz/", EC),
2459 {"//root/baz/x", "//root/baz/y"});
2465 Lower->addDirectory("//root/a");
2466 Lower->addDirectory("//root/a/b");
2467 Lower->addDirectory("//root/a/b/c");
2468 Lower->addRegularFile("//root/a/b/c/file");
2470 "{ 'use-external-names': false,\n"
2474 " 'name': '//root/a/b/c/',\n"
2478 " 'external-contents': '//root/a/b/c/file'\n"
2489 O->pushOverlay(FS);
2495 *O, "//root", EC),
2512 // Filename at root level without a parent directory.
2515 " { 'type': 'file', 'name': 'file-not-in-directory.h',\n"
2516 " 'external-contents': '//root/external/file'\n"
2521 SmallString<128> ExpectedPathNotInDir("file-not-in-directory.h");
2523 checkContents(FS->dir_begin(CWD, EC), {ExpectedPathNotInDir});
2525 // Relative file path.
2527 " { 'type': 'file', 'name': 'relative/path.h',\n"
2528 " 'external-contents': '//root/external/file'\n"
2533 SmallString<128> Parent("relative");
2535 auto I = FS->dir_begin(Parent, EC);
2538 ASSERT_EQ("relative/path.h",
2539 getPosixPath(std::string(I->path().substr(CWD.size() + 1))));
2541 // Relative directory path.
2544 " { 'type': 'directory', 'name': 'relative/directory/path.h',\n"
2550 SmallString<128> Root("relative/directory");
2551 llvm::sys::fs::make_absolute(Root);
2552 I = FS->dir_begin(Root, EC);
2554 ASSERT_EQ("path.h", std::string(I->path().substr(Root.size() + 1)));
2561 Lower->addDirectory("//root/");
2562 Lower->addRegularFile("//root/a");
2563 Lower->addRegularFile("//root/b");
2565 "{ 'use-external-names': false,\n"
2570 " 'name': '//root/',\n"
2574 " 'external-contents': '//root/a'\n"
2584 checkContents(FS->dir_begin("//root/", EC),
2585 {"//root/c"});
2590 Lower->addDirectory("//root/");
2591 Lower->addRegularFile("//root/a");
2592 Lower->addRegularFile("//root/b");
2594 "{ 'use-external-names': false,\n"
2598 " 'name': '//root/',\n"
2602 " 'external-contents': '//root/a'\n"
2612 checkContents(FS->dir_begin("//root/", EC),
2613 {"//root/a", "//root/b"});
2618 Lower->addDirectory("//root/");
2619 Lower->addDirectory("//root/foo");
2620 Lower->addRegularFile("//root/foo/a");
2621 Lower->addRegularFile("//root/foo/b");
2623 "{ 'use-external-names': false,\n"
2627 " 'name': '//root/',\n"
2631 " 'external-contents': '//root/foo/a'\n"
2641 checkContents(FS->dir_begin("//root/foo", EC),
2642 {"//root/foo/a", "//root/foo/b"});
2647 Lower->addDirectory("//dir/");
2648 Lower->addRegularFile("/foo");
2649 Lower->addSymlink("/link");
2651 "{ 'use-external-names': false,\n"
2652 " 'case-sensitive': false,\n"
2656 " 'name': '//root/',\n"
2660 " 'external-contents': '/link'\n"
2681 EXPECT_FALSE(FS->getRealPath("/foo", RealPath));
2685 EXPECT_FALSE(FS->getRealPath("//root/bar", RealPath));
2689 EXPECT_FALSE(FS->getRealPath("//ROOT/baz", RealPath));
2690 EXPECT_EQ(RealPath.str(), "//root/baz");
2692 // Try a non-existing file.
2693 EXPECT_EQ(FS->getRealPath("/non_existing", RealPath),
2699 Lower->addDirectory("//root/");
2700 Lower->addDirectory("//root/foo");
2701 Lower->addRegularFile("//root/foo/a");
2702 Lower->addRegularFile("//root/foo/b");
2704 "{ 'use-external-names': false,\n"
2708 " 'name': '//root/bar',\n"
2712 " 'external-contents': '//root/foo/a'\n"
2720 std::error_code EC = FS->setCurrentWorkingDirectory("//root/bar");
2723 llvm::ErrorOr<std::string> WorkingDir = FS->getCurrentWorkingDirectory();
2725 EXPECT_EQ(*WorkingDir, "//root/bar");
2727 llvm::ErrorOr<vfs::Status> Status = FS->status("./a");
2729 EXPECT_TRUE(Status->isStatusKnown());
2730 EXPECT_FALSE(Status->isDirectory());
2731 EXPECT_TRUE(Status->isRegularFile());
2732 EXPECT_FALSE(Status->isSymlink());
2733 EXPECT_FALSE(Status->isOther());
2734 EXPECT_TRUE(Status->exists());
2736 EC = FS->setCurrentWorkingDirectory("bogus");
2738 WorkingDir = FS->getCurrentWorkingDirectory();
2740 EXPECT_EQ(*WorkingDir, "//root/bar");
2742 EC = FS->setCurrentWorkingDirectory("//root/");
2744 WorkingDir = FS->getCurrentWorkingDirectory();
2746 EXPECT_EQ(*WorkingDir, "//root/");
2748 EC = FS->setCurrentWorkingDirectory("bar");
2750 WorkingDir = FS->getCurrentWorkingDirectory();
2752 EXPECT_EQ(*WorkingDir, "//root/bar");
2757 Lower->addDirectory("//root/");
2758 Lower->addDirectory("//root/foo");
2759 Lower->addRegularFile("//root/foo/a");
2760 Lower->addRegularFile("//root/foo/b");
2761 Lower->addRegularFile("//root/c");
2763 "{ 'use-external-names': false,\n"
2767 " 'name': '//root/bar',\n"
2771 " 'external-contents': '//root/foo/a'\n"
2777 " 'name': '//root/bar/baz',\n"
2781 " 'external-contents': '//root/foo/a'\n"
2789 std::error_code EC = FS->setCurrentWorkingDirectory("//root/");
2793 llvm::ErrorOr<vfs::Status> Status = FS->status("bar/a");
2795 EXPECT_TRUE(Status->exists());
2797 Status = FS->status("foo/a");
2799 EXPECT_TRUE(Status->exists());
2801 EC = FS->setCurrentWorkingDirectory("//root/bar");
2804 Status = FS->status("./a");
2806 EXPECT_TRUE(Status->exists());
2808 Status = FS->status("./b");
2811 Status = FS->status("./c");
2814 EC = FS->setCurrentWorkingDirectory("//root/");
2817 Status = FS->status("c");
2819 EXPECT_TRUE(Status->exists());
2821 Status = FS->status("./bar/baz/a");
2823 EXPECT_TRUE(Status->exists());
2825 EC = FS->setCurrentWorkingDirectory("//root/bar");
2828 Status = FS->status("./baz/a");
2830 EXPECT_TRUE(Status->exists());
2832 Status = FS->status("../bar/baz/a");
2834 EXPECT_TRUE(Status->exists());
2839 Lower->addDirectory("//root/");
2840 Lower->addDirectory("//root/foo");
2841 Lower->addRegularFile("//root/foo/a");
2842 Lower->addRegularFile("//root/foo/b");
2843 Lower->addRegularFile("//root/c");
2845 "{ 'use-external-names': false,\n"
2849 " 'name': '//root/bar',\n"
2853 " 'external-contents': '//root/foo/a'\n"
2861 std::error_code EC = FS->setCurrentWorkingDirectory("//root/");
2865 llvm::ErrorOr<vfs::Status> Status = FS->status("bar/a");
2867 EXPECT_TRUE(Status->exists());
2869 Status = FS->status("foo/a");
2871 EXPECT_TRUE(Status->exists());
2876 Lower->addDirectory("//root/");
2877 Lower->addDirectory("//root/foo");
2878 Lower->addRegularFile("//root/foo/a");
2879 Lower->addRegularFile("//root/foo/b");
2880 Lower->addRegularFile("//root/c");
2882 "{ 'use-external-names': false,\n"
2886 " 'name': '//root/bar',\n"
2890 " 'external-contents': '//root/foo/a'\n"
2898 std::error_code EC = FS->setCurrentWorkingDirectory("//root/bar");
2902 llvm::ErrorOr<vfs::Status> Status = FS->status("a");
2904 EXPECT_TRUE(Status->exists());
2908 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
2919 VFSWriter.addDirectoryMapping(_a.path(), "//root/a");
2920 VFSWriter.addFileMapping(_ab.path(), "//root/a/b");
2921 VFSWriter.addFileMapping(_cd.path(), "//root/c/d");
2922 VFSWriter.addDirectoryMapping(_e.path(), "//root/e");
2923 VFSWriter.addDirectoryMapping(_ef.path(), "//root/e/f");
2924 VFSWriter.addFileMapping(_g.path(), "//root/g");
2925 VFSWriter.addDirectoryMapping(_h.path(), "//root/h");
2932 Lower->addDirectory("//root/");
2933 Lower->addDirectory("//root/a");
2934 Lower->addRegularFile("//root/a/b");
2935 Lower->addDirectory("//root/b");
2936 Lower->addDirectory("//root/c");
2937 Lower->addRegularFile("//root/c/d");
2938 Lower->addDirectory("//root/e");
2939 Lower->addDirectory("//root/e/f");
2940 Lower->addRegularFile("//root/g");
2941 Lower->addDirectory("//root/h");
2946 EXPECT_TRUE(FS->exists(_a.path()));
2947 EXPECT_TRUE(FS->exists(_ab.path()));
2948 EXPECT_TRUE(FS->exists(_c.path()));
2949 EXPECT_TRUE(FS->exists(_cd.path()));
2950 EXPECT_TRUE(FS->exists(_e.path()));
2951 EXPECT_TRUE(FS->exists(_ef.path()));
2952 EXPECT_TRUE(FS->exists(_g.path()));
2953 EXPECT_TRUE(FS->exists(_h.path()));
2957 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
2968 VFSWriter.addDirectoryMapping(_a.path(), "//root/a");
2969 VFSWriter.addFileMapping(_ab.path(), "//root/a/b");
2970 VFSWriter.addDirectoryMapping(_ac.path(), "//root/a/c");
2971 VFSWriter.addFileMapping(_acd.path(), "//root/a/c/d");
2972 VFSWriter.addFileMapping(_ace.path(), "//root/a/c/e");
2973 VFSWriter.addFileMapping(_acf.path(), "//root/a/c/f");
2974 VFSWriter.addDirectoryMapping(_ag.path(), "//root/a/g");
2975 VFSWriter.addFileMapping(_agh.path(), "//root/a/g/h");
2987 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
2999 VFSWriter.addDirectoryMapping(_a.path(), "//root/a");
3000 VFSWriter.addFileMapping(_ab.path(), "//root/a/b");
3001 VFSWriter.addDirectoryMapping(_ac.path(), "//root/a/c");
3002 VFSWriter.addDirectoryMapping(_acd.path(), "//root/a/c/d");
3003 VFSWriter.addDirectoryMapping(_acde.path(), "//root/a/c/d/e");
3004 VFSWriter.addFileMapping(_acdef.path(), "//root/a/c/d/e/f");
3005 VFSWriter.addFileMapping(_acdeg.path(), "//root/a/c/d/e/g");
3006 VFSWriter.addDirectoryMapping(_ahi.path(), "//root/a/h");
3007 VFSWriter.addFileMapping(_ahi.path(), "//root/a/h/i");
3019 TempDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
3025 VFSWriter.addDirectoryMapping(_a.path(), "//root/a");
3026 VFSWriter.addDirectoryMapping(_b.path(), "//root/b");
3027 VFSWriter.addDirectoryMapping(_c.path(), "//root/c");
3033 // We didn't add a single file - only directories.
3037 Lower->addDirectory("//root/a");
3038 Lower->addDirectory("//root/b");
3039 Lower->addDirectory("//root/c");
3041 Lower->addRegularFile("//root/a/a");
3042 Lower->addRegularFile("//root/b/b");
3043 Lower->addRegularFile("//root/c/c");
3048 EXPECT_FALSE(FS->exists(_a.path("a")));
3049 EXPECT_FALSE(FS->exists(_b.path("b")));
3050 EXPECT_FALSE(FS->exists(_c.path("c")));
3055 Both->addDirectory("//root/a");
3056 Both->addRegularFile("//root/a/f");
3057 Both->addDirectory("//root/b");
3058 Both->addRegularFile("//root/b/f");
3061 AOnly->addDirectory("//root/a");
3062 AOnly->addRegularFile("//root/a/f");
3065 BOnly->addDirectory("//root/b");
3066 BOnly->addRegularFile("//root/b/f");
3070 " 'type': 'directory-remap',\n"
3071 " 'name': '//root/a',\n"
3072 " 'external-contents': '//root/b'\n"
3076 auto FallthroughStr = "{ 'redirecting-with': 'fallthrough',\n" + BaseStr;
3077 auto FallbackStr = "{ 'redirecting-with': 'fallback',\n" + BaseStr;
3078 auto RedirectOnlyStr = "{ 'redirecting-with': 'redirect-only',\n" + BaseStr;
3082 auto AF = FS.openFileForRead("//root/a/f");
3084 auto AFName = (*AF)->getName();
3088 auto AS = FS.status("//root/a/f");
3090 EXPECT_EQ(Expected.str(), AS->getName()) << Message;
3094 EXPECT_TRUE(FS.openFileForRead("//root/a/f").getError()) << Message;
3095 EXPECT_TRUE(FS.status("//root/a/f").getError()) << Message;
3101 // `fallthrough` tries `external-name` first, so should be `b`
3105 ExpectPath(*Fallthrough, "//root/b/f", "fallthrough, both exist");
3111 ExpectPath(*Fallback, "//root/a/f", "fallback, both exist");
3113 // `redirect-only` is the same as `fallthrough` but doesn't try the
3118 ExpectPath(*Redirect, "//root/b/f", "redirect-only, both exist");
3128 ExpectPath(*Fallthrough, "//root/a/f", "fallthrough, a only");
3134 ExpectPath(*Fallback, "//root/a/f", "fallback, a only");
3140 ExpectFailure(*Redirect, "redirect-only, a only");
3150 ExpectPath(*Fallthrough, "//root/b/f", "fallthrough, b only");
3156 ExpectPath(*Fallback, "//root/b/f", "fallback, b only");
3162 ExpectPath(*Redirect, "//root/b/f", "redirect-only, b only");
3171 BaseFS->addFile("//root/b", 0, MemoryBuffer::getMemBuffer("contents of b"));
3172 BaseFS->addFile("//root/c", 0, MemoryBuffer::getMemBuffer("contents of c"));
3175 {"//root/a/a", "//root/b"},
3176 {"//root/a/b/c", "//root/c"},
3181 auto StatA = RemappedFS->status("//root/a/a");
3182 auto StatB = RemappedFS->status("//root/a/b/c");
3185 EXPECT_EQ("//root/a/a", StatA->getName());
3186 EXPECT_EQ("//root/a/b/c", StatB->getName());
3188 auto BufferA = RemappedFS->getBufferForFile("//root/a/a");
3189 auto BufferB = RemappedFS->getBufferForFile("//root/a/b/c");
3192 EXPECT_EQ("contents of b", (*BufferA)->getBuffer());
3193 EXPECT_EQ("contents of c", (*BufferB)->getBuffer());
3199 BaseFS->addFile("//root/b", 0, MemoryBuffer::getMemBuffer("contents of b"));
3200 BaseFS->addFile("//root/c", 0, MemoryBuffer::getMemBuffer("contents of c"));
3203 {"//root/a/a", "//root/b"},
3204 {"//root/a/b/c", "//root/c"},
3209 auto StatA = RemappedFS->status("//root/a/a");
3210 auto StatB = RemappedFS->status("//root/a/b/c");
3213 EXPECT_EQ("//root/b", StatA->getName());
3214 EXPECT_EQ("//root/c", StatB->getName());
3216 auto BufferA = RemappedFS->getBufferForFile("//root/a/a");
3217 auto BufferB = RemappedFS->getBufferForFile("//root/a/b/c");
3220 EXPECT_EQ("contents of b", (*BufferA)->getBuffer());
3221 EXPECT_EQ("contents of c", (*BufferB)->getBuffer());
3227 BaseFS->addFile("//root/b", 0, MemoryBuffer::getMemBuffer("contents of b"));
3228 BaseFS->addFile("//root/c", 0, MemoryBuffer::getMemBuffer("contents of c"));
3231 {"//root/a", "//root/b"},
3232 {"//root/a", "//root/c"},
3239 auto StatKeepA = RemappedFSKeepName->status("//root/a");
3240 auto StatExternalA = RemappedFSExternalName->status("//root/a");
3243 EXPECT_EQ("//root/a", StatKeepA->getName());
3244 EXPECT_EQ("//root/c", StatExternalA->getName());
3246 auto BufferKeepA = RemappedFSKeepName->getBufferForFile("//root/a");
3247 auto BufferExternalA = RemappedFSExternalName->getBufferForFile("//root/a");
3250 EXPECT_EQ("contents of c", (*BufferKeepA)->getBuffer());
3251 EXPECT_EQ("contents of c", (*BufferExternalA)->getBuffer());
3260 " 'type': 'directory-remap',\n"
3262 " 'external-contents': '/a',\n"
3269 " 'type': 'directory-remap',\n"
3271 " 'external-contents': '/b'\n"
3272 " 'use-external-name': 'true'\n"
3277 " 'external-contents': '/c'\n"
3278 " 'use-external-name': 'false'\n"
3290 Redirecting->print(OuputStream, vfs::FileSystem::PrintType::Summary);
3294 Redirecting->print(OuputStream, vfs::FileSystem::PrintType::Contents);
3297 " 'dremap' -> '/a'\n"
3299 " 'dremap' -> '/b' (UseExternalName: true)\n"
3300 " 'vfile' -> '/c' (UseExternalName: false)\n"
3306 Redirecting->print(OuputStream, vfs::FileSystem::PrintType::Contents, 1);
3309 " 'dremap' -> '/a'\n"
3311 " 'dremap' -> '/b' (UseExternalName: true)\n"
3312 " 'vfile' -> '/c' (UseExternalName: false)\n"
3318 Redirecting->print(OuputStream,
3322 " 'dremap' -> '/a'\n"
3324 " 'dremap' -> '/b' (UseExternalName: true)\n"
3325 " 'vfile' -> '/c' (UseExternalName: false)\n"
3336 " 'redirecting-with': 'fallthrough',\n"
3341 " 'external-contents': '/a',\n"
3348 " 'redirecting-with': 'fallthrough',\n"
3353 " 'external-contents': '/b',\n"
3358 Dummy->addRegularFile("/a");
3359 Dummy->addRegularFile("/b");
3368 Redirecting1->setUsageTrackingActive(true);
3369 Redirecting2->setUsageTrackingActive(true);
3370 EXPECT_TRUE(Redirecting2->exists("/vfile1"));
3371 EXPECT_TRUE(Redirecting2->exists("/b"));
3372 EXPECT_TRUE(Redirecting1->hasBeenUsed());
3373 EXPECT_FALSE(Redirecting2->hasBeenUsed());
3416 BaseFS->setCurrentWorkingDirectory("/cwd");
3421 FS->status("/a/../b");
3422 FS->openFileForRead("c");
3423 FS->exists("./d");
3425 FS->isLocal("/e/./../f", IsLocal);
3426 FS->dir_begin(".././g", EC);
3431 EXPECT_EQ(CheckFS->SeenPaths, Expected);
3433 CheckFS->SeenPaths.clear();
3434 FS->setRedirection(vfs::RedirectingFileSystem::RedirectKind::Fallback);
3435 FS->status("/a/../b");
3436 FS->openFileForRead("c");
3437 FS->exists("./d");
3438 FS->isLocal("/e/./../f", IsLocal);
3439 FS->dir_begin(".././g", EC);
3441 EXPECT_EQ(CheckFS->SeenPaths, Expected);
3451 " 'type': 'directory-remap',\n"
3453 " 'external-contents': '/a',\n"
3456 " 'type': 'directory-remap',\n"
3458 " 'external-contents': '/dmissing',\n"
3467 " 'external-contents': '/c'\n"
3476 " 'type': 'directory-remap',\n"
3478 " 'external-contents': '/b'\n"
3483 " 'external-contents': '/missing'\n"
3488 " 'external-contents': '/c'\n"
3493 Dummy->addDirectory("/a");
3494 Dummy->addRegularFile("/a/foo");
3495 Dummy->addDirectory("/b");
3496 Dummy->addRegularFile("/c");
3497 Dummy->addRegularFile("/both/foo");
3502 EXPECT_TRUE(Redirecting->exists("/dremap"));
3503 EXPECT_FALSE(Redirecting->exists("/dmissing"));
3504 EXPECT_FALSE(Redirecting->exists("/unknown"));
3505 EXPECT_TRUE(Redirecting->exists("/both"));
3506 EXPECT_TRUE(Redirecting->exists("/both/foo"));
3507 EXPECT_TRUE(Redirecting->exists("/both/vfile"));
3508 EXPECT_TRUE(Redirecting->exists("/vdir"));
3509 EXPECT_TRUE(Redirecting->exists("/vdir/dremap"));
3510 EXPECT_FALSE(Redirecting->exists("/vdir/missing"));
3511 EXPECT_TRUE(Redirecting->exists("/vdir/vfile"));
3512 EXPECT_FALSE(Redirecting->exists("/vdir/unknown"));
3520 " 'redirecting-with': 'fallback',\n"
3525 " 'external-contents': '/missing',\n"
3530 Dummy->addRegularFile("/fallback");
3535 EXPECT_TRUE(Redirecting->exists("/fallback"));
3536 EXPECT_FALSE(Redirecting->exists("/missing"));
3544 " 'redirecting-with': 'redirect-only',\n"
3549 " 'external-contents': '/a',\n"
3554 Dummy->addRegularFile("/a");
3555 Dummy->addRegularFile("/b");
3560 EXPECT_FALSE(Redirecting->exists("/a"));
3561 EXPECT_FALSE(Redirecting->exists("/b"));
3562 EXPECT_TRUE(Redirecting->exists("/vfile"));
3570 EXPECT_EQ(TracingFS->NumStatusCalls, 0u);
3571 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 0u);
3572 EXPECT_EQ(TracingFS->NumDirBeginCalls, 0u);
3573 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u);
3574 EXPECT_EQ(TracingFS->NumExistsCalls, 0u);
3575 EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u);
3577 (void)TracingFS->status("/foo");
3578 EXPECT_EQ(TracingFS->NumStatusCalls, 1u);
3579 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 0u);
3580 EXPECT_EQ(TracingFS->NumDirBeginCalls, 0u);
3581 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u);
3582 EXPECT_EQ(TracingFS->NumExistsCalls, 0u);
3583 EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u);
3585 (void)TracingFS->openFileForRead("/foo");
3586 EXPECT_EQ(TracingFS->NumStatusCalls, 1u);
3587 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u);
3588 EXPECT_EQ(TracingFS->NumDirBeginCalls, 0u);
3589 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u);
3590 EXPECT_EQ(TracingFS->NumExistsCalls, 0u);
3591 EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u);
3594 (void)TracingFS->dir_begin("/foo", EC);
3595 EXPECT_EQ(TracingFS->NumStatusCalls, 1u);
3596 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u);
3597 EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u);
3598 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u);
3599 EXPECT_EQ(TracingFS->NumExistsCalls, 0u);
3600 EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u);
3603 (void)TracingFS->getRealPath("/foo", RealPath);
3604 EXPECT_EQ(TracingFS->NumStatusCalls, 1u);
3605 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u);
3606 EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u);
3607 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 1u);
3608 EXPECT_EQ(TracingFS->NumExistsCalls, 0u);
3609 EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u);
3611 (void)TracingFS->exists("/foo");
3612 EXPECT_EQ(TracingFS->NumStatusCalls, 1u);
3613 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u);
3614 EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u);
3615 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 1u);
3616 EXPECT_EQ(TracingFS->NumExistsCalls, 1u);
3617 EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u);
3620 (void)TracingFS->isLocal("/foo", IsLocal);
3621 EXPECT_EQ(TracingFS->NumStatusCalls, 1u);
3622 EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u);
3623 EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u);
3624 EXPECT_EQ(TracingFS->NumGetRealPathCalls, 1u);
3625 EXPECT_EQ(TracingFS->NumExistsCalls, 1u);
3626 EXPECT_EQ(TracingFS->NumIsLocalCalls, 1u);
3634 (void)TracingFS->status("/foo");
3636 (void)TracingFS->openFileForRead("/foo");
3637 (void)TracingFS->openFileForRead("/foo");
3640 (void)TracingFS->dir_begin("/foo", EC);
3641 (void)TracingFS->dir_begin("/foo", EC);
3642 (void)TracingFS->dir_begin("/foo", EC);
3645 (void)TracingFS->getRealPath("/foo", RealPath);
3646 (void)TracingFS->getRealPath("/foo", RealPath);
3647 (void)TracingFS->getRealPath("/foo", RealPath);
3648 (void)TracingFS->getRealPath("/foo", RealPath);
3650 (void)TracingFS->exists("/foo");
3651 (void)TracingFS->exists("/foo");
3652 (void)TracingFS->exists("/foo");
3653 (void)TracingFS->exists("/foo");
3654 (void)TracingFS->exists("/foo");
3657 (void)TracingFS->isLocal("/foo", IsLocal);
3658 (void)TracingFS->isLocal("/foo", IsLocal);
3659 (void)TracingFS->isLocal("/foo", IsLocal);
3660 (void)TracingFS->isLocal("/foo", IsLocal);
3661 (void)TracingFS->isLocal("/foo", IsLocal);
3662 (void)TracingFS->isLocal("/foo", IsLocal);
3666 TracingFS->print(OS);