TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) { IntrusiveRefCntPtr<vfs::FileSystem> FS; FS = getFromYAMLString(""); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("[]"); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("'string'"); EXPECT_EQ(nullptr, FS.getPtr()); EXPECT_EQ(3, NumDiagnostics); }
TEST_F(VFSFromYAMLTest, UseExternalName) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); Lower->addRegularFile("//root/external/file"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( "{ 'roots': [\n" " { 'type': 'file', 'name': '//root/A',\n" " 'external-contents': '//root/external/file'\n" " },\n" " { 'type': 'file', 'name': '//root/B',\n" " 'use-external-name': true,\n" " 'external-contents': '//root/external/file'\n" " },\n" " { 'type': 'file', 'name': '//root/C',\n" " 'use-external-name': false,\n" " 'external-contents': '//root/external/file'\n" " }\n" "] }", Lower); ASSERT_TRUE(nullptr != FS.getPtr()); // default true EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName()); // explicit EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName()); EXPECT_EQ("//root/C", FS->status("//root/C")->getName()); // global configuration FS = getFromYAMLString( "{ 'use-external-names': false,\n" " 'roots': [\n" " { 'type': 'file', 'name': '//root/A',\n" " 'external-contents': '//root/external/file'\n" " },\n" " { 'type': 'file', 'name': '//root/B',\n" " 'use-external-name': true,\n" " 'external-contents': '//root/external/file'\n" " },\n" " { 'type': 'file', 'name': '//root/C',\n" " 'use-external-name': false,\n" " 'external-contents': '//root/external/file'\n" " }\n" "] }", Lower); ASSERT_TRUE(nullptr != FS.getPtr()); // default EXPECT_EQ("//root/A", FS->status("//root/A")->getName()); // explicit EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName()); EXPECT_EQ("//root/C", FS->status("//root/C")->getName()); }
TEST_F(VFSFromYAMLTest, CaseSensitive) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{ 'case-sensitive': 'true',\n" " 'roots': [\n" "{\n" " 'type': 'directory',\n" " 'name': '//root/',\n" " 'contents': [ {\n" " 'type': 'file',\n" " 'name': 'XX',\n" " 'external-contents': '//root/foo/bar/a'\n" " }\n" " ]\n" "}]}", Lower); ASSERT_TRUE(FS.getPtr() != nullptr); IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( new vfs::OverlayFileSystem(Lower)); O->pushOverlay(FS); ErrorOr<vfs::Status> SS = O->status("//root/xx"); EXPECT_EQ(std::errc::no_such_file_or_directory, SS.getError()); SS = O->status("//root/xX"); EXPECT_EQ(std::errc::no_such_file_or_directory, SS.getError()); SS = O->status("//root/Xx"); EXPECT_EQ(std::errc::no_such_file_or_directory, SS.getError()); EXPECT_EQ(0, NumDiagnostics); }
TEST_F(VFSFromYAMLTest, MultiComponentPath) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); Lower->addRegularFile("//root/other"); // file in roots IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( "{ 'roots': [\n" " { 'type': 'file', 'name': '//root/path/to/file',\n" " 'external-contents': '//root/other' }]\n" "}", Lower); ASSERT_TRUE(nullptr != FS.getPtr()); EXPECT_FALSE(FS->status("//root/path/to/file").getError()); EXPECT_FALSE(FS->status("//root/path/to").getError()); EXPECT_FALSE(FS->status("//root/path").getError()); EXPECT_FALSE(FS->status("//root/").getError()); // at the start FS = getFromYAMLString( "{ 'roots': [\n" " { 'type': 'directory', 'name': '//root/path/to',\n" " 'contents': [ { 'type': 'file', 'name': 'file',\n" " 'external-contents': '//root/other' }]}]\n" "}", Lower); ASSERT_TRUE(nullptr != FS.getPtr()); EXPECT_FALSE(FS->status("//root/path/to/file").getError()); EXPECT_FALSE(FS->status("//root/path/to").getError()); EXPECT_FALSE(FS->status("//root/path").getError()); EXPECT_FALSE(FS->status("//root/").getError()); // at the end FS = getFromYAMLString( "{ 'roots': [\n" " { 'type': 'directory', 'name': '//root/',\n" " 'contents': [ { 'type': 'file', 'name': 'path/to/file',\n" " 'external-contents': '//root/other' }]}]\n" "}", Lower); ASSERT_TRUE(nullptr != FS.getPtr()); EXPECT_FALSE(FS->status("//root/path/to/file").getError()); EXPECT_FALSE(FS->status("//root/path/to").getError()); EXPECT_FALSE(FS->status("//root/path").getError()); EXPECT_FALSE(FS->status("//root/").getError()); }
TEST_F(VFSFromYAMLTest, MappedFiles) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{ 'roots': [\n" "{\n" " 'type': 'directory',\n" " 'name': '//root/',\n" " 'contents': [ {\n" " 'type': 'file',\n" " 'name': 'file1',\n" " 'external-contents': '//root/foo/bar/a'\n" " },\n" " {\n" " 'type': 'file',\n" " 'name': 'file2',\n" " 'external-contents': '//root/foo/b'\n" " }\n" " ]\n" "}\n" "]\n" "}", Lower); ASSERT_TRUE(FS.getPtr() != nullptr); IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( new vfs::OverlayFileSystem(Lower)); O->pushOverlay(FS); // file ErrorOr<vfs::Status> S = O->status("//root/file1"); ASSERT_FALSE(S.getError()); EXPECT_EQ("//root/foo/bar/a", S->getName()); ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a"); EXPECT_EQ("//root/foo/bar/a", SLower->getName()); EXPECT_TRUE(S->equivalent(*SLower)); // directory S = O->status("//root/"); ASSERT_FALSE(S.getError()); EXPECT_TRUE(S->isDirectory()); EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID // broken mapping EXPECT_EQ(std::errc::no_such_file_or_directory, O->status("//root/file2").getError()); EXPECT_EQ(0, NumDiagnostics); }
TEST_F(VFSFromYAMLTest, IllegalVFSFile) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); // invalid YAML at top-level IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // invalid YAML in roots FS = getFromYAMLString("{ 'roots':[}", Lower); // invalid YAML in directory FS = getFromYAMLString( "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // invalid configuration FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // invalid roots FS = getFromYAMLString("{ 'roots':'' }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("{ 'roots':{} }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // invalid entries FS = getFromYAMLString( "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], " "'external-contents': 'other' }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // missing mandatory fields FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // duplicate keys FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString( "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', " "'external-contents':'blah' } ] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // missing version FS = getFromYAMLRawString("{ 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); // bad version number FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower); EXPECT_EQ(nullptr, FS.getPtr()); EXPECT_EQ(24, NumDiagnostics); }