1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===- unittests/Basic/VirtualFileSystem.cpp ---------------- VFS tests ---===// 2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// The LLVM Compiler Infrastructure 4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This file is distributed under the University of Illinois Open Source 6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// License. See LICENSE.TXT for details. 7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===// 9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/VirtualFileSystem.h" 11c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include "llvm/Support/Errc.h" 12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/MemoryBuffer.h" 13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/Path.h" 14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/SourceMgr.h" 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "gtest/gtest.h" 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <map> 17a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing namespace clang; 19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing namespace llvm; 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing llvm::sys::fs::UniqueID; 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace { 23a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarstruct DummyFile : public vfs::File { 24a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar vfs::Status S; 25a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar explicit DummyFile(vfs::Status S) : S(S) {} 26a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::ErrorOr<vfs::Status> status() override { return S; } 27a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 28a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, 29a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool IsVolatile) override { 30a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm_unreachable("unimplemented"); 31a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 32a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar virtual std::error_code close() override { return std::error_code(); } 33a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}; 34a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass DummyFileSystem : public vfs::FileSystem { 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int FSID; // used to produce UniqueIDs 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int FileID; // used to produce UniqueIDs 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::map<std::string, vfs::Status> FilesAndDirs; 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static int getNextFSID() { 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static int Count = 0; 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Count++; 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DummyFileSystem() : FSID(getNextFSID()), FileID(0) {} 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 48176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ErrorOr<vfs::Status> status(const Twine &Path) override { 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::map<std::string, vfs::Status>::iterator I = 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FilesAndDirs.find(Path.str()); 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I == FilesAndDirs.end()) 52c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return make_error_code(llvm::errc::no_such_file_or_directory); 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return I->second; 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ErrorOr<std::unique_ptr<vfs::File>> 56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines openFileForRead(const Twine &Path) override { 57a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto S = status(Path); 58a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (S) 59a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return std::unique_ptr<vfs::File>(new DummyFile{*S}); 60a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return S.getError(); 61a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 62a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { 63a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return std::string(); 64a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 65a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar std::error_code setCurrentWorkingDirectory(const Twine &Path) override { 66a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return std::error_code(); 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 69c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines struct DirIterImpl : public clang::vfs::detail::DirIterImpl { 70c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::map<std::string, vfs::Status> &FilesAndDirs; 71c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::map<std::string, vfs::Status>::iterator I; 72c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::string Path; 73c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool isInPath(StringRef S) { 74c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Path.size() < S.size() && S.find(Path) == 0) { 75c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines auto LastSep = S.find_last_of('/'); 76c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (LastSep == Path.size() || LastSep == Path.size()-1) 77c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return true; 78c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 79c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 80c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 81c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs, 82c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const Twine &_Path) 83c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()), 84c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Path(_Path.str()) { 85c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for ( ; I != FilesAndDirs.end(); ++I) { 86c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (isInPath(I->first)) { 87c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CurrentEntry = I->second; 88c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 89c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 90c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 91c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 92c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code increment() override { 93c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ++I; 94c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for ( ; I != FilesAndDirs.end(); ++I) { 95c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (isInPath(I->first)) { 96c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CurrentEntry = I->second; 97c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 98c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 99c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 100c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (I == FilesAndDirs.end()) 101c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CurrentEntry = vfs::Status(); 102c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return std::error_code(); 103c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 104c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 105c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 106c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines vfs::directory_iterator dir_begin(const Twine &Dir, 107c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code &EC) override { 108c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return vfs::directory_iterator( 109c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::make_shared<DirIterImpl>(FilesAndDirs, Dir)); 110c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 111c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addEntry(StringRef Path, const vfs::Status &Status) { 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FilesAndDirs[Path] = Status; 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { 117a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, 118a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1024, sys::fs::file_type::regular_file, Perms); 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addEntry(Path, S); 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { 123a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, 124a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 0, sys::fs::file_type::directory_file, Perms); 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addEntry(Path, S); 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addSymlink(StringRef Path) { 129a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, 130a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 0, sys::fs::file_type::symlink_file, sys::fs::all_all); 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addEntry(Path, S); 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // end anonymous namespace 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 136651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, StatusQueries) { 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); 138c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ErrorOr<vfs::Status> Status((std::error_code())); 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addRegularFile("/foo"); 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/foo"); 142c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status.getError()); 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isStatusKnown()); 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isDirectory()); 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isRegularFile()); 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isSymlink()); 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isOther()); 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->exists()); 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addDirectory("/bar"); 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/bar"); 152c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status.getError()); 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isStatusKnown()); 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isDirectory()); 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isRegularFile()); 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isSymlink()); 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isOther()); 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->exists()); 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addSymlink("/baz"); 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/baz"); 162c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status.getError()); 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isStatusKnown()); 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isDirectory()); 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isRegularFile()); 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isSymlink()); 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isOther()); 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->exists()); 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->equivalent(*Status)); 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> Status2 = D->status("/foo"); 172c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status2.getError()); 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->equivalent(*Status2)); 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 176651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, BaseOnlyOverlay) { 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); 178c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ErrorOr<vfs::Status> Status((std::error_code())); 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status = D->status("/foo")); 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D)); 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status = O->status("/foo")); 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addRegularFile("/foo"); 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/foo"); 186c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(Status.getError()); 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ErrorOr<vfs::Status> Status2((std::error_code())); 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status2 = O->status("/foo"); 190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(Status2.getError()); 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->equivalent(*Status2)); 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 194651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, OverlayFiles) { 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem()); 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Base)); 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Middle); 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Top); 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 203c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ErrorOr<vfs::Status> Status1((std::error_code())), 204c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Status2((std::error_code())), Status3((std::error_code())), 205c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines StatusB((std::error_code())), StatusM((std::error_code())), 206c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines StatusT((std::error_code())); 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Base->addRegularFile("/foo"); 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StatusB = Base->status("/foo"); 210c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(StatusB.getError()); 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status1 = O->status("/foo"); 212c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status1.getError()); 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Middle->addRegularFile("/foo"); 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StatusM = Middle->status("/foo"); 215c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(StatusM.getError()); 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status2 = O->status("/foo"); 217c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status2.getError()); 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Top->addRegularFile("/foo"); 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StatusT = Top->status("/foo"); 220c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(StatusT.getError()); 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status3 = O->status("/foo"); 222c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status3.getError()); 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status1->equivalent(*StatusB)); 225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status2->equivalent(*StatusM)); 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status3->equivalent(*StatusT)); 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status1->equivalent(*Status2)); 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status2->equivalent(*Status3)); 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status1->equivalent(*Status3)); 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 233651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, OverlayDirsNonMerged) { 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Upper); 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addDirectory("/lower-only"); 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Upper->addDirectory("/upper-only"); 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // non-merged paths should be the same 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only"); 245c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status1.getError()); 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> Status2 = O->status("/lower-only"); 247c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status2.getError()); 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status1->equivalent(*Status2)); 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status1 = Upper->status("/upper-only"); 251c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status1.getError()); 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status2 = O->status("/upper-only"); 253c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status2.getError()); 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status1->equivalent(*Status2)); 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 257651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, MergedDirPermissions) { 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // merged directories get the permissions of the upper dir 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Upper); 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 265c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ErrorOr<vfs::Status> Status((std::error_code())); 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addDirectory("/both", sys::fs::owner_read); 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read); 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = O->status("/both"); 269c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status.getError()); 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0740, Status->getPermissions()); 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // permissions (as usual) are not recursively applied 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("/both/foo", sys::fs::owner_read); 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Upper->addRegularFile("/both/bar", sys::fs::owner_write); 275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = O->status("/both/foo"); 276c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE( Status.getError()); 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0400, Status->getPermissions()); 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = O->status("/both/bar"); 279c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Status.getError()); 280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0200, Status->getPermissions()); 281651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 283c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace { 284c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstruct ScopedDir { 285c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SmallString<128> Path; 286c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir(const Twine &Name, bool Unique=false) { 287c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 288c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Unique) { 289c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EC = llvm::sys::fs::createUniqueDirectory(Name, Path); 290c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 291c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Path = Name.str(); 292c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EC = llvm::sys::fs::create_directory(Twine(Path)); 293c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 294c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (EC) 295c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Path = ""; 296c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(EC); 297c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 298c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ~ScopedDir() { 299c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Path != "") 300c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(llvm::sys::fs::remove(Path.str())); 301c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 302c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines operator StringRef() { return Path.str(); } 303c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}; 304a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} // end anonymous namespace 305c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 306c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(VirtualFileSystemTest, BasicRealFSIteration) { 307c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true); 308c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); 309c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 310c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 311c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC); 312c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(EC); 313c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(vfs::directory_iterator(), I); // empty directory is empty 314c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 315c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _a(TestDirectory+"/a"); 316c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _ab(TestDirectory+"/a/b"); 317c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _c(TestDirectory+"/c"); 318c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _cd(TestDirectory+"/c/d"); 319c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 320c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines I = FS->dir_begin(Twine(TestDirectory), EC); 321c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(EC); 322c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_NE(vfs::directory_iterator(), I); 323c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check either a or c, since we can't rely on the iteration order. 324c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c")); 325c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines I.increment(EC); 326c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(EC); 327c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_NE(vfs::directory_iterator(), I); 328c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c")); 329c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines I.increment(EC); 330c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(vfs::directory_iterator(), I); 331c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 332c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 333c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) { 334c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true); 335c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); 336c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 337c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 338c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC); 339c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(EC); 340c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(vfs::recursive_directory_iterator(), I); // empty directory is empty 341c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 342c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _a(TestDirectory+"/a"); 343c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _ab(TestDirectory+"/a/b"); 344c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _c(TestDirectory+"/c"); 345c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ScopedDir _cd(TestDirectory+"/c/d"); 346c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 347c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC); 348c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(EC); 349c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_NE(vfs::recursive_directory_iterator(), I); 350c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 351c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 352c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::vector<std::string> Contents; 353c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (auto E = vfs::recursive_directory_iterator(); !EC && I != E; 354c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines I.increment(EC)) { 355c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Contents.push_back(I->getName()); 356c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 357c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 358c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check contents, which may be in any order 359c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(4U, Contents.size()); 360c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines int Counts[4] = { 0, 0, 0, 0 }; 361c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (const std::string &Name : Contents) { 362c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(Name.empty()); 363c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines int Index = Name[Name.size()-1] - 'a'; 364c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(Index >= 0 && Index < 4); 365c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Counts[Index]++; 366c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 367c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(1, Counts[0]); // a 368c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(1, Counts[1]); // b 369c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(1, Counts[2]); // c 370c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(1, Counts[3]); // d 371c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 372c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 373c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T, size_t N> 374c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstd::vector<StringRef> makeStringRefVector(const T (&Arr)[N]) { 375c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::vector<StringRef> Vec; 376c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (size_t i = 0; i != N; ++i) 377c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Vec.push_back(Arr[i]); 378c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return Vec; 379c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 380c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 381c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename DirIter> 382c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic void checkContents(DirIter I, ArrayRef<StringRef> Expected) { 383c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 384c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end(); 385c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (DirIter E; 386c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines !EC && I != E && ExpectedIter != ExpectedEnd; 387c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines I.increment(EC), ++ExpectedIter) 388c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(*ExpectedIter, I->getName()); 389c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 390c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(ExpectedEnd, ExpectedIter); 391c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(DirIter(), I); 392c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 393c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 394c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(VirtualFileSystemTest, OverlayIteration) { 395c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 396c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 397c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 398c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines new vfs::OverlayFileSystem(Lower)); 399c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Upper); 400c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 401c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 402c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>()); 403c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 404c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/file1"); 405c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1")); 406c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 407c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/file2"); 408c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 409c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"/file2", "/file1"}; 410c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 411c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 412c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 413c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addDirectory("/dir1"); 414c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/dir1/foo"); 415c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addDirectory("/dir2"); 416c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/dir2/foo"); 417c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo")); 418c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 419c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"/dir2", "/file2", "/dir1", "/file1"}; 420c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 421c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 422c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 423c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 424c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(VirtualFileSystemTest, OverlayRecursiveIteration) { 425c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 426c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 427c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 428c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 429c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines new vfs::OverlayFileSystem(Lower)); 430c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Middle); 431c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Upper); 432c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 433c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 434c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 435c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ArrayRef<StringRef>()); 436c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 437c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/file1"); 438c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 439c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ArrayRef<StringRef>("/file1")); 440c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 441c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addDirectory("/dir"); 442c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/dir/file2"); 443c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 444c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"/dir", "/dir/file2", "/file1"}; 445c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 446c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines makeStringRefVector(Contents)); 447c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 448c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 449c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addDirectory("/dir1"); 450c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/dir1/foo"); 451c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addDirectory("/dir1/a"); 452c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/dir1/a/b"); 453c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addDirectory("/a"); 454c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addDirectory("/a/b"); 455c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addDirectory("/a/b/c"); 456c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addRegularFile("/a/b/c/d"); 457c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addRegularFile("/hiddenByUp"); 458c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addDirectory("/dir2"); 459c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/dir2/foo"); 460c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/hiddenByUp"); 461c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/dir2", EC), 462c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ArrayRef<StringRef>("/dir2/foo")); 463c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 464c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = { "/dir", "/dir/file2", "/dir2", "/dir2/foo", 465c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "/hiddenByUp", "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/dir1", "/dir1/a", 466c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "/dir1/a/b", "/dir1/foo", "/file1" }; 467c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 468c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines makeStringRefVector(Contents)); 469c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 470c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 471c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 472c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(VirtualFileSystemTest, ThreeLevelIteration) { 473c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 474c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 475c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 476c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 477c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines new vfs::OverlayFileSystem(Lower)); 478c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Middle); 479c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Upper); 480c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 481c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 482c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>()); 483c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 484c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addRegularFile("/file2"); 485c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2")); 486c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 487c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/file1"); 488c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/file3"); 489c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 490c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"/file3", "/file2", "/file1"}; 491c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 492c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 493c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 494c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 495c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(VirtualFileSystemTest, HiddenInIteration) { 496c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 497c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 498c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 499c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 500c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines new vfs::OverlayFileSystem(Lower)); 501c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Middle); 502c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(Upper); 503c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 504c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 505c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/onlyInLow", sys::fs::owner_read); 506c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/hiddenByMid", sys::fs::owner_read); 507c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("/hiddenByUp", sys::fs::owner_read); 508c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addRegularFile("/onlyInMid", sys::fs::owner_write); 509c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addRegularFile("/hiddenByMid", sys::fs::owner_write); 510c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Middle->addRegularFile("/hiddenByUp", sys::fs::owner_write); 511c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/onlyInUp", sys::fs::owner_all); 512c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Upper->addRegularFile("/hiddenByUp", sys::fs::owner_all); 513c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 514c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"/hiddenByUp", "/onlyInUp", "/hiddenByMid", 515c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "/onlyInMid", "/onlyInLow"}; 516c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 517c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 518c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 519c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Make sure we get the top-most entry 520c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 521c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 522c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines vfs::directory_iterator I = O->dir_begin("/", EC), E; 523c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for ( ; !EC && I != E; I.increment(EC)) 524c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (I->getName() == "/hiddenByUp") 525c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 526c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_NE(E, I); 527c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(sys::fs::owner_all, I->getPermissions()); 528c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 529c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 530c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 531c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines vfs::directory_iterator I = O->dir_begin("/", EC), E; 532c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for ( ; !EC && I != E; I.increment(EC)) 533c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (I->getName() == "/hiddenByMid") 534c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 535c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_NE(E, I); 536c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(sys::fs::owner_write, I->getPermissions()); 537c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 538c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 539c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 540a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarclass InMemoryFileSystemTest : public ::testing::Test { 541a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarprotected: 542a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar clang::vfs::InMemoryFileSystem FS; 543a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar clang::vfs::InMemoryFileSystem NormalizedFS; 544a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 545a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar InMemoryFileSystemTest() 546a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar : FS(/*UseNormalizedPaths=*/false), 547a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NormalizedFS(/*UseNormalizedPaths=*/true) {} 548a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}; 549a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 550a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, IsEmpty) { 551a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Stat = FS.status("/a"); 552a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ(Stat.getError(),errc::no_such_file_or_directory) << FS.toString(); 553a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = FS.status("/"); 554a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ(Stat.getError(), errc::no_such_file_or_directory) << FS.toString(); 555a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 556a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 557a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, WindowsPath) { 558a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("c:/windows/system128/foo.cpp", 0, MemoryBuffer::getMemBuffer("")); 559a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Stat = FS.status("c:"); 560a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if !defined(_WIN32) 561a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString(); 562a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif 563a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = FS.status("c:/windows/system128/foo.cpp"); 564a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString(); 565a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("d:/windows/foo.cpp", 0, MemoryBuffer::getMemBuffer("")); 566a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = FS.status("d:/windows/foo.cpp"); 567a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString(); 568a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 569a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 570a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, OverlayFile) { 571a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")); 572a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")); 573a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Stat = FS.status("/"); 574a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString(); 575a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = FS.status("/."); 576a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat); 577a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = NormalizedFS.status("/."); 578a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString(); 579a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = FS.status("/a"); 580a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); 581a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("/a", Stat->getName()); 582a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 583a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 584a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, OverlayFileNoOwn) { 585a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Buf = MemoryBuffer::getMemBuffer("a"); 586a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFileNoOwn("/a", 0, Buf.get()); 587a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Stat = FS.status("/a"); 588a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); 589a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("/a", Stat->getName()); 590a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 591a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 592a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, OpenFileForRead) { 593a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")); 594a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c")); 595a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d")); 596a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")); 597a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NormalizedFS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c")); 598a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NormalizedFS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d")); 599a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto File = FS.openFileForRead("/a"); 600a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer()); 601a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = FS.openFileForRead("/a"); // Open again. 602a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer()); 603a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = NormalizedFS.openFileForRead("/././a"); // Open again. 604a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer()); 605a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = FS.openFileForRead("/"); 606a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ(File.getError(), errc::invalid_argument) << FS.toString(); 607a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = FS.openFileForRead("/b"); 608a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ(File.getError(), errc::no_such_file_or_directory) << FS.toString(); 609a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = FS.openFileForRead("./c"); 610a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(File); 611a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = FS.openFileForRead("e/../d"); 612a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(File); 613a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = NormalizedFS.openFileForRead("./c"); 614a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("c", (*(*File)->getBuffer("ignored"))->getBuffer()); 615a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar File = NormalizedFS.openFileForRead("e/../d"); 616a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("d", (*(*File)->getBuffer("ignored"))->getBuffer()); 617a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 618a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 619a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, DuplicatedFile) { 620a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"))); 621a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("a"))); 622a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"))); 623a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("b"))); 624a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 625a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 626a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, DirectoryIteration) { 627a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("")); 628a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("/b/c", 0, MemoryBuffer::getMemBuffer("")); 629a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 630a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar std::error_code EC; 631a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar vfs::directory_iterator I = FS.dir_begin("/", EC); 632a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(EC); 633a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("/a", I->getName()); 634a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar I.increment(EC); 635a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(EC); 636a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("/b", I->getName()); 637a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar I.increment(EC); 638a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(EC); 639a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ(vfs::directory_iterator(), I); 640a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 641a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar I = FS.dir_begin("/b", EC); 642a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(EC); 643a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("/b/c", I->getName()); 644a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar I.increment(EC); 645a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(EC); 646a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ(vfs::directory_iterator(), I); 647a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 648a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 649a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST_F(InMemoryFileSystemTest, WorkingDirectory) { 650a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.setCurrentWorkingDirectory("/b"); 651a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FS.addFile("c", 0, MemoryBuffer::getMemBuffer("")); 652a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 653a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Stat = FS.status("/b/c"); 654a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); 655a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("c", Stat->getName()); 656a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_EQ("/b", *FS.getCurrentWorkingDirectory()); 657a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 658a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Stat = FS.status("c"); 659a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); 660a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 661a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// NOTE: in the tests below, we use '//root/' as our root directory, since it is 663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// a legal *absolute* path on Windows as well as *nix. 664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass VFSFromYAMLTest : public ::testing::Test { 665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int NumDiagnostics; 667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 66858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar void SetUp() override { NumDiagnostics = 0; } 669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void CountingDiagHandler(const SMDiagnostic &, void *Context) { 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context); 672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++Test->NumDiagnostics; 673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> 676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLRawString(StringRef Content, 677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) { 678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(Content); 679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, this, 680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExternalFS); 681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString( 684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Content, 685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) { 686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string VersionPlusContent("{\n 'version':0,\n"); 687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos); 688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return getFromYAMLRawString(VersionPlusContent, ExternalFS); 689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 692651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, BasicVFSFromYAML) { 693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS; 694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString(""); 695c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("[]"); 697c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("'string'"); 699c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(3, NumDiagnostics); 701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 703651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, MappedFiles) { 704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/foo/bar/a"); 706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'roots': [\n" 708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{\n" 709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'directory',\n" 710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': '//root/',\n" 711651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ {\n" 712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'file1',\n" 714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/bar/a'\n" 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " {\n" 717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'file2',\n" 719651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/b'\n" 720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " ]\n" 722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}\n" 723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "]\n" 724651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", 725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 726c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(FS.get() != nullptr); 727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(FS); 731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // file 733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> S = O->status("//root/file1"); 734c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(S.getError()); 735651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/foo/bar/a", S->getName()); 736a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar EXPECT_TRUE(S->IsVFSMapped); 737651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a"); 739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/foo/bar/a", SLower->getName()); 740651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SLower)); 741a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar EXPECT_FALSE(SLower->IsVFSMapped); 742a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 743a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // file after opening 744a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto OpenedF = O->openFileForRead("//root/file1"); 745a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(OpenedF.getError()); 746a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto OpenedS = (*OpenedF)->status(); 747a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_FALSE(OpenedS.getError()); 748a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar EXPECT_EQ("//root/foo/bar/a", OpenedS->getName()); 749a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar EXPECT_TRUE(OpenedS->IsVFSMapped); 750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // directory 752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S = O->status("//root/"); 753c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(S.getError()); 754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->isDirectory()); 755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID 756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 757651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // broken mapping 758c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(O->status("//root/file2").getError(), 759c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::errc::no_such_file_or_directory); 760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0, NumDiagnostics); 761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 763651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, CaseInsensitive) { 764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/foo/bar/a"); 766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'case-sensitive': 'false',\n" 768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'roots': [\n" 769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{\n" 770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'directory',\n" 771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': '//root/',\n" 772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ {\n" 773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'XX',\n" 775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/bar/a'\n" 776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " ]\n" 778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}]}", 779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 780c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(FS.get() != nullptr); 781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(FS); 785651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> S = O->status("//root/XX"); 787c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(S.getError()); 788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> SS = O->status("//root/xx"); 790c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_FALSE(SS.getError()); 791651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SS)); 792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/xX"); 793651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SS)); 794651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/Xx"); 795651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SS)); 796651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0, NumDiagnostics); 797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 799651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, CaseSensitive) { 800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 801651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/foo/bar/a"); 802651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'case-sensitive': 'true',\n" 804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'roots': [\n" 805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{\n" 806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'directory',\n" 807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': '//root/',\n" 808651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ {\n" 809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'XX',\n" 811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/bar/a'\n" 812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " ]\n" 814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}]}", 815651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 816c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(FS.get() != nullptr); 817651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 818651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(FS); 821651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 822651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> SS = O->status("//root/xx"); 823c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory); 824651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/xX"); 825c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory); 826651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/Xx"); 827c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory); 828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0, NumDiagnostics); 829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 831651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, IllegalVFSFile) { 832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 834651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid YAML at top-level 835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower); 836c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 837651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid YAML in roots 838651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[}", Lower); 839651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid YAML in directory 840651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 841651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}", 842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 843c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 845651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid configuration 846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower); 847c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower); 849c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 850651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 851651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid roots 852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':'' }", Lower); 853c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':{} }", Lower); 855c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid entries 858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower); 860c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 861651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], " 862651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "'external-contents': 'other' }", 863651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 864c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 865651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 866651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }", 867651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 868c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 869651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 870651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }", 871651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 872c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 873651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 874651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }", 875651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 876c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 877651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 878651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }", 879651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 880c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 881651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 882651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }", 883651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 884c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 885651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 886651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // missing mandatory fields 887651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower); 888c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 889651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 890651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower); 891c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 892651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower); 893c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 894651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 895651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // duplicate keys 896651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower); 897c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 898651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 899651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }", 900651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 901c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 902651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = 903651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', " 904651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "'external-contents':'blah' } ] }", 905651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 906c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 907651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 908651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // missing version 909651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'roots':[] }", Lower); 910c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 911651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 912651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // bad version number 913651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower); 914c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 915651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower); 916c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 917651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower); 918c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_EQ(nullptr, FS.get()); 919651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(24, NumDiagnostics); 920651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 921651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 922651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, UseExternalName) { 923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 924651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/external/file"); 925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 926651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( 927651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 928651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/A',\n" 929651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 931651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/B',\n" 932651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': true,\n" 933651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 934651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/C',\n" 936651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': false,\n" 937651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 938651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 939651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "] }", Lower); 940c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 941651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 942651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // default true 943651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName()); 944651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // explicit 945651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName()); 946651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/C", FS->status("//root/C")->getName()); 947651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 948651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // global configuration 949651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 950651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'use-external-names': false,\n" 951651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'roots': [\n" 952651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/A',\n" 953651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 955651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/B',\n" 956651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': true,\n" 957651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 958651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 959651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/C',\n" 960651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': false,\n" 961651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 963651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "] }", Lower); 964c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 965651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 966651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // default 967651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/A", FS->status("//root/A")->getName()); 968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // explicit 969651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName()); 970651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/C", FS->status("//root/C")->getName()); 971651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 972651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 973651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, MultiComponentPath) { 974651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 975651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/other"); 976651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 977651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // file in roots 978651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( 979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 980651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/path/to/file',\n" 981651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]\n" 982651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 983c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 984c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 985c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 986c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 987c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 989651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // at the start 990651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 991651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 992651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'directory', 'name': '//root/path/to',\n" 993651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ { 'type': 'file', 'name': 'file',\n" 994651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]}]\n" 995651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 996c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 997c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 998c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 999c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 1000c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 1001651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1002651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // at the end 1003651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 1004651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 1005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'directory', 'name': '//root/',\n" 1006651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n" 1007651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]}]\n" 1008651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 1009c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 1010c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 1011c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 1012c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 1013c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 1014651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1015651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1016651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, TrailingSlashes) { 1017651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 1018651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/other"); 1019651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1020651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // file in roots 1021651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( 1022651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 1023651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'directory', 'name': '//root/path/to////',\n" 1024651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ { 'type': 'file', 'name': 'file',\n" 1025651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]}]\n" 1026651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 1027c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 1028c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 1029c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 1030c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 1031c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 1032c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1033c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1034c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST_F(VFSFromYAMLTest, DirectoryIteration) { 1035c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 1036c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addDirectory("//root/"); 1037c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addDirectory("//root/foo"); 1038c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addDirectory("//root/foo/bar"); 1039c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("//root/foo/bar/a"); 1040c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("//root/foo/bar/b"); 1041c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower->addRegularFile("//root/file3"); 1042c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 1043c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getFromYAMLString("{ 'use-external-names': false,\n" 1044c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'roots': [\n" 1045c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "{\n" 1046c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'type': 'directory',\n" 1047c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'name': '//root/',\n" 1048c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'contents': [ {\n" 1049c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'type': 'file',\n" 1050c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'name': 'file1',\n" 1051c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'external-contents': '//root/foo/bar/a'\n" 1052c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " },\n" 1053c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " {\n" 1054c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'type': 'file',\n" 1055c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'name': 'file2',\n" 1056c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " 'external-contents': '//root/foo/bar/b'\n" 1057c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " }\n" 1058c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines " ]\n" 1059c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "}\n" 1060c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "]\n" 1061c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "}", 1062c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Lower); 1063a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ASSERT_TRUE(FS.get() != nullptr); 1064c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1065c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 1066c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines new vfs::OverlayFileSystem(Lower)); 1067c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines O->pushOverlay(FS); 1068c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1069c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 1070c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 1071c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"//root/file1", "//root/file2", "//root/file3", 1072c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "//root/foo"}; 1073c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("//root/", EC), makeStringRefVector(Contents)); 1074c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 1075c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1076c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { 1077c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *Contents[] = {"//root/foo/bar/a", "//root/foo/bar/b"}; 1078c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines checkContents(O->dir_begin("//root/foo/bar", EC), 1079c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines makeStringRefVector(Contents)); 1080c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 1081651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1082