diff options
Diffstat (limited to 'clang/unittests/Basic/VirtualFileSystemTest.cpp')
-rw-r--r-- | clang/unittests/Basic/VirtualFileSystemTest.cpp | 278 |
1 files changed, 263 insertions, 15 deletions
diff --git a/clang/unittests/Basic/VirtualFileSystemTest.cpp b/clang/unittests/Basic/VirtualFileSystemTest.cpp index e545e9c0597..50d11019f30 100644 --- a/clang/unittests/Basic/VirtualFileSystemTest.cpp +++ b/clang/unittests/Basic/VirtualFileSystemTest.cpp @@ -8,7 +8,9 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/VirtualFileSystem.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" #include <map> using namespace clang; @@ -31,7 +33,7 @@ public: ErrorOr<vfs::Status> status(const Twine &Path) { std::map<std::string, vfs::Status>::iterator I = - FilesAndDirs.find(Path.str()); + FilesAndDirs.find(Path.str()); if (I == FilesAndDirs.end()) return error_code(errc::no_such_file_or_directory, posix_category()); return I->second; @@ -50,13 +52,13 @@ public: FilesAndDirs[Path] = Status; } - void addRegularFile(StringRef Path, sys::fs::perms Perms=sys::fs::all_all) { + void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, 1024, sys::fs::file_type::regular_file, Perms); addEntry(Path, S); } - void addDirectory(StringRef Path, sys::fs::perms Perms=sys::fs::all_all) { + void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0, 0, sys::fs::file_type::directory_file, Perms); addEntry(Path, S); @@ -70,7 +72,7 @@ public: }; } // end anonymous namespace -TEST(VirtualFileSystemTest, statusQueries) { +TEST(VirtualFileSystemTest, StatusQueries) { IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); ErrorOr<vfs::Status> Status((error_code())); @@ -110,7 +112,7 @@ TEST(VirtualFileSystemTest, statusQueries) { EXPECT_FALSE(Status->equivalent(*Status2)); } -TEST(VirtualFileSystemTest, baseOnlyOverlay) { +TEST(VirtualFileSystemTest, BaseOnlyOverlay) { IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); ErrorOr<vfs::Status> Status((error_code())); EXPECT_FALSE(Status = D->status("/foo")); @@ -128,17 +130,18 @@ TEST(VirtualFileSystemTest, baseOnlyOverlay) { EXPECT_TRUE(Status->equivalent(*Status2)); } -TEST(VirtualFileSystemTest, overlayFiles) { +TEST(VirtualFileSystemTest, OverlayFiles) { IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(Base)); + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Base)); O->pushOverlay(Middle); O->pushOverlay(Top); ErrorOr<vfs::Status> Status1((error_code())), Status2((error_code())), - Status3((error_code())), StatusB((error_code())), - StatusM((error_code())), StatusT((error_code())); + Status3((error_code())), StatusB((error_code())), StatusM((error_code())), + StatusT((error_code())); Base->addRegularFile("/foo"); StatusB = Base->status("/foo"); @@ -165,11 +168,11 @@ TEST(VirtualFileSystemTest, overlayFiles) { EXPECT_FALSE(Status1->equivalent(*Status3)); } -TEST(VirtualFileSystemTest, overlayDirsNonMerged) { +TEST(VirtualFileSystemTest, OverlayDirsNonMerged) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> - O(new vfs::OverlayFileSystem(Lower)); + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); O->pushOverlay(Upper); Lower->addDirectory("/lower-only"); @@ -189,12 +192,12 @@ TEST(VirtualFileSystemTest, overlayDirsNonMerged) { EXPECT_TRUE(Status1->equivalent(*Status2)); } -TEST(VirtualFileSystemTest, mergedDirPermissions) { +TEST(VirtualFileSystemTest, MergedDirPermissions) { // merged directories get the permissions of the upper dir IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> - O(new vfs::OverlayFileSystem(Lower)); + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); O->pushOverlay(Upper); ErrorOr<vfs::Status> Status((error_code())); @@ -214,3 +217,248 @@ TEST(VirtualFileSystemTest, mergedDirPermissions) { ASSERT_EQ(errc::success, Status.getError()); EXPECT_EQ(0200, Status->getPermissions()); } + +static int NumDiagnostics = 0; +static void CountingDiagHandler(const SMDiagnostic &, void *) { + ++NumDiagnostics; +} + +static IntrusiveRefCntPtr<vfs::FileSystem> +getFromYAMLRawString(StringRef Content, + IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) { + MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Content); + return getVFSFromYAML(Buffer, CountingDiagHandler, ExternalFS); +} + +static IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString( + StringRef Content, + IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) { + std::string VersionPlusContent("{\n 'version':0,\n"); + VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos); + return getFromYAMLRawString(VersionPlusContent, ExternalFS); +} + +TEST(VirtualFileSystemTest, BasicVFSFromYAML) { + NumDiagnostics = 0; + IntrusiveRefCntPtr<vfs::FileSystem> FS; + FS = getFromYAMLString(""); + EXPECT_EQ(NULL, FS.getPtr()); + FS = getFromYAMLString("[]"); + EXPECT_EQ(NULL, FS.getPtr()); + FS = getFromYAMLString("'string'"); + EXPECT_EQ(NULL, FS.getPtr()); + EXPECT_EQ(3, NumDiagnostics); +} + +TEST(VirtualFileSystemTest, MappedFiles) { + NumDiagnostics = 0; + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + Lower->addRegularFile("/foo/bar/a"); + IntrusiveRefCntPtr<vfs::FileSystem> FS = + getFromYAMLString("{ 'roots': [\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '/',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'file1',\n" + " 'external-contents': '/foo/bar/a'\n" + " },\n" + " {\n" + " 'type': 'file',\n" + " 'name': 'file2',\n" + " 'external-contents': '/foo/b'\n" + " }\n" + " ]\n" + "}\n" + "]\n" + "}", + Lower); + ASSERT_TRUE(FS.getPtr()); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(FS); + + // file + ErrorOr<vfs::Status> S = O->status("/file1"); + ASSERT_EQ(errc::success, S.getError()); + EXPECT_EQ("/file1", S->getName()); + EXPECT_EQ("/foo/bar/a", S->getExternalName()); + + ErrorOr<vfs::Status> SLower = O->status("/foo/bar/a"); + EXPECT_EQ("/foo/bar/a", SLower->getName()); + EXPECT_TRUE(S->equivalent(*SLower)); + + // directory + S = O->status("/"); + ASSERT_EQ(errc::success, S.getError()); + EXPECT_TRUE(S->isDirectory()); + EXPECT_TRUE(S->equivalent(*O->status("/"))); // non-volatile UniqueID + + // broken mapping + EXPECT_EQ(errc::no_such_file_or_directory, O->status("/file2").getError()); + EXPECT_EQ(0, NumDiagnostics); +} + +TEST(VirtualFileSystemTest, CaseInsensitive) { + NumDiagnostics = 0; + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + Lower->addRegularFile("/foo/bar/a"); + IntrusiveRefCntPtr<vfs::FileSystem> FS = + getFromYAMLString("{ 'case-sensitive': 'false',\n" + " 'roots': [\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '/',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'XX',\n" + " 'external-contents': '/foo/bar/a'\n" + " }\n" + " ]\n" + "}]}", + Lower); + ASSERT_TRUE(FS.getPtr()); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(FS); + + ErrorOr<vfs::Status> S = O->status("/XX"); + ASSERT_EQ(errc::success, S.getError()); + + ErrorOr<vfs::Status> SS = O->status("/xx"); + ASSERT_EQ(errc::success, SS.getError()); + EXPECT_TRUE(S->equivalent(*SS)); + SS = O->status("/xX"); + EXPECT_TRUE(S->equivalent(*SS)); + SS = O->status("/Xx"); + EXPECT_TRUE(S->equivalent(*SS)); + EXPECT_EQ(0, NumDiagnostics); +} + +TEST(VirtualFileSystemTest, CaseSensitive) { + NumDiagnostics = 0; + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + Lower->addRegularFile("/foo/bar/a"); + IntrusiveRefCntPtr<vfs::FileSystem> FS = + getFromYAMLString("{ 'case-sensitive': 'true',\n" + " 'roots': [\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '/',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'XX',\n" + " 'external-contents': '/foo/bar/a'\n" + " }\n" + " ]\n" + "}]}", + Lower); + ASSERT_TRUE(FS.getPtr()); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(FS); + + ErrorOr<vfs::Status> SS = O->status("/xx"); + EXPECT_EQ(errc::no_such_file_or_directory, SS.getError()); + SS = O->status("/xX"); + EXPECT_EQ(errc::no_such_file_or_directory, SS.getError()); + SS = O->status("/Xx"); + EXPECT_EQ(errc::no_such_file_or_directory, SS.getError()); + EXPECT_EQ(0, NumDiagnostics); +} + +TEST(VirtualFileSystemTest, IllegalVFSFile) { + NumDiagnostics = 0; + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + + // invalid YAML at top-level + IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower); + EXPECT_FALSE(FS.getPtr()); + // invalid YAML in roots + FS = getFromYAMLString("{ 'roots':[}", Lower); + // invalid YAML in directory + FS = getFromYAMLString( + "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}", + Lower); + EXPECT_FALSE(FS.getPtr()); + + // invalid configuration + FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + + // invalid roots + FS = getFromYAMLString("{ 'roots':'' }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString("{ 'roots':{} }", Lower); + EXPECT_FALSE(FS.getPtr()); + + // invalid entries + FS = getFromYAMLString( + "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], " + "'external-contents': 'other' }", + Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }", + Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }", + Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }", + Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }", + Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }", + Lower); + EXPECT_FALSE(FS.getPtr()); + + // missing mandatory fields + FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower); + EXPECT_FALSE(FS.getPtr()); + + // duplicate keys + FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLString( + "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }", + Lower); + EXPECT_FALSE(FS.getPtr()); + FS = + getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', " + "'external-contents':'blah' } ] }", + Lower); + EXPECT_FALSE(FS.getPtr()); + + // missing version + FS = getFromYAMLRawString("{ 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + + // bad version number + FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower); + EXPECT_FALSE(FS.getPtr()); + EXPECT_EQ(24, NumDiagnostics); +} |