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" 11ef8225444452a1486bd721f3285301fe84643b00Stephen 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> 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing namespace clang; 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing namespace llvm; 19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing llvm::sys::fs::UniqueID; 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace { 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass DummyFileSystem : public vfs::FileSystem { 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int FSID; // used to produce UniqueIDs 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int FileID; // used to produce UniqueIDs 25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::map<std::string, vfs::Status> FilesAndDirs; 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static int getNextFSID() { 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static int Count = 0; 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Count++; 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DummyFileSystem() : FSID(getNextFSID()), FileID(0) {} 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> status(const Twine &Path) { 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::map<std::string, vfs::Status>::iterator I = 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FilesAndDirs.find(Path.str()); 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I == FilesAndDirs.end()) 39ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return make_error_code(llvm::errc::no_such_file_or_directory); 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return I->second; 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 42ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code openFileForRead(const Twine &Path, 43ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::unique_ptr<vfs::File> &Result) { 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm_unreachable("unimplemented"); 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 46ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code getBufferForFile(const Twine &Name, 47ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::unique_ptr<MemoryBuffer> &Result, 48ef8225444452a1486bd721f3285301fe84643b00Stephen Hines int64_t FileSize = -1, 49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool RequiresNullTerminator = true) { 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm_unreachable("unimplemented"); 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 53ef8225444452a1486bd721f3285301fe84643b00Stephen Hines struct DirIterImpl : public clang::vfs::detail::DirIterImpl { 54ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::map<std::string, vfs::Status> &FilesAndDirs; 55ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::map<std::string, vfs::Status>::iterator I; 56ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::string Path; 57ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool isInPath(StringRef S) { 58ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Path.size() < S.size() && S.find(Path) == 0) { 59ef8225444452a1486bd721f3285301fe84643b00Stephen Hines auto LastSep = S.find_last_of('/'); 60ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (LastSep == Path.size() || LastSep == Path.size()-1) 61ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return true; 62ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 63ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return false; 64ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 65ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs, 66ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const Twine &_Path) 67ef8225444452a1486bd721f3285301fe84643b00Stephen Hines : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()), 68ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Path(_Path.str()) { 69ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for ( ; I != FilesAndDirs.end(); ++I) { 70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (isInPath(I->first)) { 71ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CurrentEntry = I->second; 72ef8225444452a1486bd721f3285301fe84643b00Stephen Hines break; 73ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 74ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 75ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 76ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code increment() override { 77ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ++I; 78ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for ( ; I != FilesAndDirs.end(); ++I) { 79ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (isInPath(I->first)) { 80ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CurrentEntry = I->second; 81ef8225444452a1486bd721f3285301fe84643b00Stephen Hines break; 82ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 83ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 84ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (I == FilesAndDirs.end()) 85ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CurrentEntry = vfs::Status(); 86ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return std::error_code(); 87ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 88ef8225444452a1486bd721f3285301fe84643b00Stephen Hines }; 89ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 90ef8225444452a1486bd721f3285301fe84643b00Stephen Hines vfs::directory_iterator dir_begin(const Twine &Dir, 91ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code &EC) override { 92ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return vfs::directory_iterator( 93ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::make_shared<DirIterImpl>(FilesAndDirs, Dir)); 94ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 95ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addEntry(StringRef Path, const vfs::Status &Status) { 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FilesAndDirs[Path] = Status; 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 0, 0, 1024, sys::fs::file_type::regular_file, Perms); 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addEntry(Path, S); 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 0, 0, 0, sys::fs::file_type::directory_file, Perms); 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addEntry(Path, S); 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addSymlink(StringRef Path) { 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 0, 0, 0, sys::fs::file_type::symlink_file, sys::fs::all_all); 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addEntry(Path, S); 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // end anonymous namespace 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 120651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, StatusQueries) { 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); 122ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ErrorOr<vfs::Status> Status((std::error_code())); 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addRegularFile("/foo"); 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/foo"); 126ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status.getError()); 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isStatusKnown()); 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isDirectory()); 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isRegularFile()); 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isSymlink()); 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isOther()); 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->exists()); 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addDirectory("/bar"); 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/bar"); 136ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status.getError()); 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isStatusKnown()); 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isDirectory()); 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isRegularFile()); 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isSymlink()); 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isOther()); 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->exists()); 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addSymlink("/baz"); 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/baz"); 146ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status.getError()); 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isStatusKnown()); 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isDirectory()); 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isRegularFile()); 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->isSymlink()); 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->isOther()); 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->exists()); 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->equivalent(*Status)); 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> Status2 = D->status("/foo"); 156ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status2.getError()); 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status->equivalent(*Status2)); 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 160651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, BaseOnlyOverlay) { 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); 162ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ErrorOr<vfs::Status> Status((std::error_code())); 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status = D->status("/foo")); 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D)); 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status = O->status("/foo")); 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addRegularFile("/foo"); 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = D->status("/foo"); 170ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(Status.getError()); 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 172ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ErrorOr<vfs::Status> Status2((std::error_code())); 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status2 = O->status("/foo"); 174ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(Status2.getError()); 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status->equivalent(*Status2)); 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 178651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, OverlayFiles) { 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem()); 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Base)); 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Middle); 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Top); 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 187ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ErrorOr<vfs::Status> Status1((std::error_code())), 188ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Status2((std::error_code())), Status3((std::error_code())), 189ef8225444452a1486bd721f3285301fe84643b00Stephen Hines StatusB((std::error_code())), StatusM((std::error_code())), 190ef8225444452a1486bd721f3285301fe84643b00Stephen Hines StatusT((std::error_code())); 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Base->addRegularFile("/foo"); 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StatusB = Base->status("/foo"); 194ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(StatusB.getError()); 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status1 = O->status("/foo"); 196ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status1.getError()); 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Middle->addRegularFile("/foo"); 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StatusM = Middle->status("/foo"); 199ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(StatusM.getError()); 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status2 = O->status("/foo"); 201ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status2.getError()); 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Top->addRegularFile("/foo"); 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StatusT = Top->status("/foo"); 204ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(StatusT.getError()); 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status3 = O->status("/foo"); 206ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status3.getError()); 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status1->equivalent(*StatusB)); 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status2->equivalent(*StatusM)); 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status3->equivalent(*StatusT)); 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status1->equivalent(*Status2)); 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status2->equivalent(*Status3)); 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(Status1->equivalent(*Status3)); 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 217651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, OverlayDirsNonMerged) { 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Upper); 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addDirectory("/lower-only"); 225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Upper->addDirectory("/upper-only"); 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // non-merged paths should be the same 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only"); 229ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status1.getError()); 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> Status2 = O->status("/lower-only"); 231ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status2.getError()); 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status1->equivalent(*Status2)); 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status1 = Upper->status("/upper-only"); 235ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status1.getError()); 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status2 = O->status("/upper-only"); 237ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status2.getError()); 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(Status1->equivalent(*Status2)); 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 241651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(VirtualFileSystemTest, MergedDirPermissions) { 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // merged directories get the permissions of the upper dir 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(Upper); 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 249ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ErrorOr<vfs::Status> Status((std::error_code())); 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addDirectory("/both", sys::fs::owner_read); 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read); 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = O->status("/both"); 253ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status.getError()); 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0740, Status->getPermissions()); 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // permissions (as usual) are not recursively applied 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("/both/foo", sys::fs::owner_read); 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Upper->addRegularFile("/both/bar", sys::fs::owner_write); 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = O->status("/both/foo"); 260ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE( Status.getError()); 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0400, Status->getPermissions()); 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Status = O->status("/both/bar"); 263ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Status.getError()); 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0200, Status->getPermissions()); 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 267ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesnamespace { 268ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstruct ScopedDir { 269ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SmallString<128> Path; 270ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir(const Twine &Name, bool Unique=false) { 271ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 272ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Unique) { 273ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EC = llvm::sys::fs::createUniqueDirectory(Name, Path); 274ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } else { 275ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Path = Name.str(); 276ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EC = llvm::sys::fs::create_directory(Twine(Path)); 277ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 278ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (EC) 279ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Path = ""; 280ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(EC); 281ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 282ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ~ScopedDir() { 283ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Path != "") 284ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(llvm::sys::fs::remove(Path.str())); 285ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 286ef8225444452a1486bd721f3285301fe84643b00Stephen Hines operator StringRef() { return Path.str(); } 287ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}; 288ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 289ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 290ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST(VirtualFileSystemTest, BasicRealFSIteration) { 291ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true); 292ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); 293ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 294ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 295ef8225444452a1486bd721f3285301fe84643b00Stephen Hines vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC); 296ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(EC); 297ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(vfs::directory_iterator(), I); // empty directory is empty 298ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 299ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _a(TestDirectory+"/a"); 300ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _ab(TestDirectory+"/a/b"); 301ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _c(TestDirectory+"/c"); 302ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _cd(TestDirectory+"/c/d"); 303ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 304ef8225444452a1486bd721f3285301fe84643b00Stephen Hines I = FS->dir_begin(Twine(TestDirectory), EC); 305ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(EC); 306ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_NE(vfs::directory_iterator(), I); 307ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Check either a or c, since we can't rely on the iteration order. 308ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c")); 309ef8225444452a1486bd721f3285301fe84643b00Stephen Hines I.increment(EC); 310ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(EC); 311ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_NE(vfs::directory_iterator(), I); 312ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c")); 313ef8225444452a1486bd721f3285301fe84643b00Stephen Hines I.increment(EC); 314ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(vfs::directory_iterator(), I); 315ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 316ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 317ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) { 318ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true); 319ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem(); 320ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 321ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 322ef8225444452a1486bd721f3285301fe84643b00Stephen Hines auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC); 323ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(EC); 324ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(vfs::recursive_directory_iterator(), I); // empty directory is empty 325ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 326ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _a(TestDirectory+"/a"); 327ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _ab(TestDirectory+"/a/b"); 328ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _c(TestDirectory+"/c"); 329ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ScopedDir _cd(TestDirectory+"/c/d"); 330ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 331ef8225444452a1486bd721f3285301fe84643b00Stephen Hines I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC); 332ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(EC); 333ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_NE(vfs::recursive_directory_iterator(), I); 334ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 335ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 336ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::vector<std::string> Contents; 337ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (auto E = vfs::recursive_directory_iterator(); !EC && I != E; 338ef8225444452a1486bd721f3285301fe84643b00Stephen Hines I.increment(EC)) { 339ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Contents.push_back(I->getName()); 340ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 341ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 342ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Check contents, which may be in any order 343ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(4U, Contents.size()); 344ef8225444452a1486bd721f3285301fe84643b00Stephen Hines int Counts[4] = { 0, 0, 0, 0 }; 345ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (const std::string &Name : Contents) { 346ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(Name.empty()); 347ef8225444452a1486bd721f3285301fe84643b00Stephen Hines int Index = Name[Name.size()-1] - 'a'; 348ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(Index >= 0 && Index < 4); 349ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Counts[Index]++; 350ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 351ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(1, Counts[0]); // a 352ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(1, Counts[1]); // b 353ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(1, Counts[2]); // c 354ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(1, Counts[3]); // d 355ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 356ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 357ef8225444452a1486bd721f3285301fe84643b00Stephen Hinestemplate <typename T, size_t N> 358ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstd::vector<StringRef> makeStringRefVector(const T (&Arr)[N]) { 359ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::vector<StringRef> Vec; 360ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (size_t i = 0; i != N; ++i) 361ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Vec.push_back(Arr[i]); 362ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return Vec; 363ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 364ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 365ef8225444452a1486bd721f3285301fe84643b00Stephen Hinestemplate <typename DirIter> 366ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstatic void checkContents(DirIter I, ArrayRef<StringRef> Expected) { 367ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 368ef8225444452a1486bd721f3285301fe84643b00Stephen Hines auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end(); 369ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (DirIter E; 370ef8225444452a1486bd721f3285301fe84643b00Stephen Hines !EC && I != E && ExpectedIter != ExpectedEnd; 371ef8225444452a1486bd721f3285301fe84643b00Stephen Hines I.increment(EC), ++ExpectedIter) 372ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(*ExpectedIter, I->getName()); 373ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 374ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(ExpectedEnd, ExpectedIter); 375ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(DirIter(), I); 376ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 377ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 378ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST(VirtualFileSystemTest, OverlayIteration) { 379ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 380ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 381ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 382ef8225444452a1486bd721f3285301fe84643b00Stephen Hines new vfs::OverlayFileSystem(Lower)); 383ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Upper); 384ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 385ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 386ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>()); 387ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 388ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/file1"); 389ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1")); 390ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 391ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/file2"); 392ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 393ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"/file2", "/file1"}; 394ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 395ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 396ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 397ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addDirectory("/dir1"); 398ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/dir1/foo"); 399ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addDirectory("/dir2"); 400ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/dir2/foo"); 401ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo")); 402ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 403ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"/dir2", "/file2", "/dir1", "/file1"}; 404ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 405ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 406ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 407ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 408ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST(VirtualFileSystemTest, OverlayRecursiveIteration) { 409ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 410ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 411ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 412ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 413ef8225444452a1486bd721f3285301fe84643b00Stephen Hines new vfs::OverlayFileSystem(Lower)); 414ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Middle); 415ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Upper); 416ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 417ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 418ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 419ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ArrayRef<StringRef>()); 420ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 421ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/file1"); 422ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 423ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ArrayRef<StringRef>("/file1")); 424ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 425ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addDirectory("/dir"); 426ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/dir/file2"); 427ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 428ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"/dir", "/dir/file2", "/file1"}; 429ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 430ef8225444452a1486bd721f3285301fe84643b00Stephen Hines makeStringRefVector(Contents)); 431ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 432ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 433ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addDirectory("/dir1"); 434ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/dir1/foo"); 435ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addDirectory("/dir1/a"); 436ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/dir1/a/b"); 437ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addDirectory("/a"); 438ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addDirectory("/a/b"); 439ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addDirectory("/a/b/c"); 440ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addRegularFile("/a/b/c/d"); 441ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addRegularFile("/hiddenByUp"); 442ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addDirectory("/dir2"); 443ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/dir2/foo"); 444ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/hiddenByUp"); 445ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/dir2", EC), 446ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ArrayRef<StringRef>("/dir2/foo")); 447ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 448ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = { "/dir", "/dir/file2", "/dir2", "/dir2/foo", 449ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "/hiddenByUp", "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/dir1", "/dir1/a", 450ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "/dir1/a/b", "/dir1/foo", "/file1" }; 451ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(vfs::recursive_directory_iterator(*O, "/", EC), 452ef8225444452a1486bd721f3285301fe84643b00Stephen Hines makeStringRefVector(Contents)); 453ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 454ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 455ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 456ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST(VirtualFileSystemTest, ThreeLevelIteration) { 457ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 458ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 459ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 460ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 461ef8225444452a1486bd721f3285301fe84643b00Stephen Hines new vfs::OverlayFileSystem(Lower)); 462ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Middle); 463ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Upper); 464ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 465ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 466ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>()); 467ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 468ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addRegularFile("/file2"); 469ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2")); 470ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 471ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/file1"); 472ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/file3"); 473ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 474ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"/file3", "/file2", "/file1"}; 475ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 476ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 477ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 478ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 479ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST(VirtualFileSystemTest, HiddenInIteration) { 480ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 481ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); 482ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); 483ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 484ef8225444452a1486bd721f3285301fe84643b00Stephen Hines new vfs::OverlayFileSystem(Lower)); 485ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Middle); 486ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(Upper); 487ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 488ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 489ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/onlyInLow", sys::fs::owner_read); 490ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/hiddenByMid", sys::fs::owner_read); 491ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("/hiddenByUp", sys::fs::owner_read); 492ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addRegularFile("/onlyInMid", sys::fs::owner_write); 493ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addRegularFile("/hiddenByMid", sys::fs::owner_write); 494ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Middle->addRegularFile("/hiddenByUp", sys::fs::owner_write); 495ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/onlyInUp", sys::fs::owner_all); 496ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Upper->addRegularFile("/hiddenByUp", sys::fs::owner_all); 497ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 498ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"/hiddenByUp", "/onlyInUp", "/hiddenByMid", 499ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "/onlyInMid", "/onlyInLow"}; 500ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents)); 501ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 502ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 503ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Make sure we get the top-most entry 504ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 505ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 506ef8225444452a1486bd721f3285301fe84643b00Stephen Hines vfs::directory_iterator I = O->dir_begin("/", EC), E; 507ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for ( ; !EC && I != E; I.increment(EC)) 508ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (I->getName() == "/hiddenByUp") 509ef8225444452a1486bd721f3285301fe84643b00Stephen Hines break; 510ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_NE(E, I); 511ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(sys::fs::owner_all, I->getPermissions()); 512ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 513ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 514ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 515ef8225444452a1486bd721f3285301fe84643b00Stephen Hines vfs::directory_iterator I = O->dir_begin("/", EC), E; 516ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for ( ; !EC && I != E; I.increment(EC)) 517ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (I->getName() == "/hiddenByMid") 518ef8225444452a1486bd721f3285301fe84643b00Stephen Hines break; 519ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_NE(E, I); 520ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(sys::fs::owner_write, I->getPermissions()); 521ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 522ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 523ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// NOTE: in the tests below, we use '//root/' as our root directory, since it is 525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// a legal *absolute* path on Windows as well as *nix. 526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass VFSFromYAMLTest : public ::testing::Test { 527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int NumDiagnostics; 529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void SetUp() { 531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NumDiagnostics = 0; 532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void CountingDiagHandler(const SMDiagnostic &, void *Context) { 535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context); 536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++Test->NumDiagnostics; 537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> 540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLRawString(StringRef Content, 541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) { 542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Content); 543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return getVFSFromYAML(Buffer, CountingDiagHandler, this, ExternalFS); 544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString( 547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Content, 548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) { 549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string VersionPlusContent("{\n 'version':0,\n"); 550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos); 551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return getFromYAMLRawString(VersionPlusContent, ExternalFS); 552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 555651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, BasicVFSFromYAML) { 556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS; 557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString(""); 558ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("[]"); 560ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("'string'"); 562ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(3, NumDiagnostics); 564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 566651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, MappedFiles) { 567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/foo/bar/a"); 569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'roots': [\n" 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{\n" 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'directory',\n" 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': '//root/',\n" 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ {\n" 575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'file1',\n" 577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/bar/a'\n" 578651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " {\n" 580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'file2',\n" 582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/b'\n" 583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " ]\n" 585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}\n" 586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "]\n" 587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", 588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 589ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(FS.get() != nullptr); 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(FS); 594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // file 596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> S = O->status("//root/file1"); 597ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(S.getError()); 598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/foo/bar/a", S->getName()); 599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 600651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a"); 601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/foo/bar/a", SLower->getName()); 602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SLower)); 603651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // directory 605651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S = O->status("//root/"); 606ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(S.getError()); 607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->isDirectory()); 608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID 609651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // broken mapping 611ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(O->status("//root/file2").getError(), 612ef8225444452a1486bd721f3285301fe84643b00Stephen Hines llvm::errc::no_such_file_or_directory); 613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0, NumDiagnostics); 614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 616651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, CaseInsensitive) { 617651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 618651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/foo/bar/a"); 619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'case-sensitive': 'false',\n" 621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'roots': [\n" 622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{\n" 623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'directory',\n" 624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': '//root/',\n" 625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ {\n" 626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'XX',\n" 628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/bar/a'\n" 629651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " ]\n" 631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}]}", 632651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 633ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(FS.get() != nullptr); 634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(FS); 638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> S = O->status("//root/XX"); 640ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(S.getError()); 641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 642651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> SS = O->status("//root/xx"); 643ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_FALSE(SS.getError()); 644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SS)); 645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/xX"); 646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SS)); 647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/Xx"); 648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(S->equivalent(*SS)); 649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0, NumDiagnostics); 650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 652651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, CaseSensitive) { 653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/foo/bar/a"); 655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'case-sensitive': 'true',\n" 657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'roots': [\n" 658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{\n" 659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'directory',\n" 660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': '//root/',\n" 661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ {\n" 662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'type': 'file',\n" 663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'name': 'XX',\n" 664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/foo/bar/a'\n" 665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " ]\n" 667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}]}", 668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 669ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(FS.get() != nullptr); 670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new vfs::OverlayFileSystem(Lower)); 673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->pushOverlay(FS); 674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ErrorOr<vfs::Status> SS = O->status("//root/xx"); 676ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory); 677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/xX"); 678ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory); 679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SS = O->status("//root/Xx"); 680ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory); 681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(0, NumDiagnostics); 682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 684651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, IllegalVFSFile) { 685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid YAML at top-level 688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower); 689ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid YAML in roots 691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[}", Lower); 692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid YAML in directory 693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}", 695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 696ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid configuration 699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower); 700ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower); 702ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid roots 705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':'' }", Lower); 706ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':{} }", Lower); 708ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // invalid entries 711651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower); 713ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], " 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "'external-contents': 'other' }", 716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 717ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 719651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }", 720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 721ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }", 724651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 725ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 726651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }", 728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 729ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }", 732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 733ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 735651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }", 736651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 737ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // missing mandatory fields 740651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower); 741ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower); 744ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 745651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower); 746ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // duplicate keys 749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower); 750ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }", 753651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 754ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = 756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', " 757651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "'external-contents':'blah' } ] }", 758651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower); 759ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // missing version 762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'roots':[] }", Lower); 763ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // bad version number 766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower); 767ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower); 769ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower); 771ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(nullptr, FS.get()); 772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ(24, NumDiagnostics); 773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 775651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, UseExternalName) { 776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/external/file"); 778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( 780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/A',\n" 782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/B',\n" 785651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': true,\n" 786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/C',\n" 789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': false,\n" 790651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 791651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "] }", Lower); 793ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 794651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 795651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // default true 796651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName()); 797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // explicit 798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName()); 799651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/C", FS->status("//root/C")->getName()); 800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 801651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // global configuration 802651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'use-external-names': false,\n" 804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'roots': [\n" 805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/A',\n" 806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 808651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/B',\n" 809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': true,\n" 810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " },\n" 812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/C',\n" 813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'use-external-name': false,\n" 814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/external/file'\n" 815651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " }\n" 816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "] }", Lower); 817ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 818651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // default 820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/A", FS->status("//root/A")->getName()); 821651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // explicit 822651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName()); 823651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_EQ("//root/C", FS->status("//root/C")->getName()); 824651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 825651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 826651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, MultiComponentPath) { 827651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/other"); 829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // file in roots 831651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( 832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'file', 'name': '//root/path/to/file',\n" 834651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]\n" 835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 836ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 837ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 838ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 839ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 840ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 841651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // at the start 843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 845651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'directory', 'name': '//root/path/to',\n" 846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ { 'type': 'file', 'name': 'file',\n" 847651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]}]\n" 848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 849ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 850ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 851ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 852ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 853ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // at the end 856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FS = getFromYAMLString( 857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'directory', 'name': '//root/',\n" 859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n" 860651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]}]\n" 861651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 862ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 863ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 864ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 865ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 866ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 867651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 868651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 869651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST_F(VFSFromYAMLTest, TrailingSlashes) { 870651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 871651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Lower->addRegularFile("//root/other"); 872651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 873651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // file in roots 874651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( 875651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "{ 'roots': [\n" 876651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " { 'type': 'directory', 'name': '//root/path/to////',\n" 877651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'contents': [ { 'type': 'file', 'name': 'file',\n" 878651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines " 'external-contents': '//root/other' }]}]\n" 879651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "}", Lower); 880ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(nullptr != FS.get()); 881ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to/file").getError()); 882ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path/to").getError()); 883ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/path").getError()); 884ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_FALSE(FS->status("//root/").getError()); 885ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 886ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 887ef8225444452a1486bd721f3285301fe84643b00Stephen HinesTEST_F(VFSFromYAMLTest, DirectoryIteration) { 888ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); 889ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addDirectory("//root/"); 890ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addDirectory("//root/foo"); 891ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addDirectory("//root/foo/bar"); 892ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("//root/foo/bar/a"); 893ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("//root/foo/bar/b"); 894ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower->addRegularFile("//root/file3"); 895ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::FileSystem> FS = 896ef8225444452a1486bd721f3285301fe84643b00Stephen Hines getFromYAMLString("{ 'use-external-names': false,\n" 897ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'roots': [\n" 898ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "{\n" 899ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'type': 'directory',\n" 900ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'name': '//root/',\n" 901ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'contents': [ {\n" 902ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'type': 'file',\n" 903ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'name': 'file1',\n" 904ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'external-contents': '//root/foo/bar/a'\n" 905ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " },\n" 906ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " {\n" 907ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'type': 'file',\n" 908ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'name': 'file2',\n" 909ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " 'external-contents': '//root/foo/bar/b'\n" 910ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " }\n" 911ef8225444452a1486bd721f3285301fe84643b00Stephen Hines " ]\n" 912ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "}\n" 913ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "]\n" 914ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "}", 915ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Lower); 916ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ASSERT_TRUE(FS.get() != NULL); 917ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 918ef8225444452a1486bd721f3285301fe84643b00Stephen Hines IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( 919ef8225444452a1486bd721f3285301fe84643b00Stephen Hines new vfs::OverlayFileSystem(Lower)); 920ef8225444452a1486bd721f3285301fe84643b00Stephen Hines O->pushOverlay(FS); 921ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 922ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 923ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 924ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"//root/file1", "//root/file2", "//root/file3", 925ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "//root/foo"}; 926ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("//root/", EC), makeStringRefVector(Contents)); 927ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 928ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 929ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { 930ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const char *Contents[] = {"//root/foo/bar/a", "//root/foo/bar/b"}; 931ef8225444452a1486bd721f3285301fe84643b00Stephen Hines checkContents(O->dir_begin("//root/foo/bar", EC), 932ef8225444452a1486bd721f3285301fe84643b00Stephen Hines makeStringRefVector(Contents)); 933ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 934651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 935