summaryrefslogtreecommitdiffstats
path: root/unittests/Basic/VirtualFileSystemTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Basic/VirtualFileSystemTest.cpp')
-rw-r--r--unittests/Basic/VirtualFileSystemTest.cpp172
1 files changed, 163 insertions, 9 deletions
diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp
index 71d2d2b..ac07035 100644
--- a/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/unittests/Basic/VirtualFileSystemTest.cpp
@@ -14,11 +14,24 @@
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
#include <map>
+
using namespace clang;
using namespace llvm;
using llvm::sys::fs::UniqueID;
namespace {
+struct DummyFile : public vfs::File {
+ vfs::Status S;
+ explicit DummyFile(vfs::Status S) : S(S) {}
+ llvm::ErrorOr<vfs::Status> status() override { return S; }
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
+ bool IsVolatile) override {
+ llvm_unreachable("unimplemented");
+ }
+ virtual std::error_code close() override { return std::error_code(); }
+};
+
class DummyFileSystem : public vfs::FileSystem {
int FSID; // used to produce UniqueIDs
int FileID; // used to produce UniqueIDs
@@ -41,7 +54,16 @@ public:
}
ErrorOr<std::unique_ptr<vfs::File>>
openFileForRead(const Twine &Path) override {
- llvm_unreachable("unimplemented");
+ auto S = status(Path);
+ if (S)
+ return std::unique_ptr<vfs::File>(new DummyFile{*S});
+ return S.getError();
+ }
+ llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
+ return std::string();
+ }
+ std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
+ return std::error_code();
}
struct DirIterImpl : public clang::vfs::detail::DirIterImpl {
@@ -92,20 +114,20 @@ public:
}
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);
+ vfs::Status S(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) {
- vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
- 0, 0, 0, sys::fs::file_type::directory_file, Perms);
+ vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0,
+ 0, sys::fs::file_type::directory_file, Perms);
addEntry(Path, S);
}
void addSymlink(StringRef Path) {
- vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
- 0, 0, 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
+ vfs::Status S(Path, UniqueID(FSID, FileID++), sys::TimeValue::now(), 0, 0,
+ 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
addEntry(Path, S);
}
};
@@ -279,7 +301,7 @@ struct ScopedDir {
}
operator StringRef() { return Path.str(); }
};
-}
+} // end anonymous namespace
TEST(VirtualFileSystemTest, BasicRealFSIteration) {
ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
@@ -515,6 +537,128 @@ TEST(VirtualFileSystemTest, HiddenInIteration) {
}
}
+class InMemoryFileSystemTest : public ::testing::Test {
+protected:
+ clang::vfs::InMemoryFileSystem FS;
+ clang::vfs::InMemoryFileSystem NormalizedFS;
+
+ InMemoryFileSystemTest()
+ : FS(/*UseNormalizedPaths=*/false),
+ NormalizedFS(/*UseNormalizedPaths=*/true) {}
+};
+
+TEST_F(InMemoryFileSystemTest, IsEmpty) {
+ auto Stat = FS.status("/a");
+ ASSERT_EQ(Stat.getError(),errc::no_such_file_or_directory) << FS.toString();
+ Stat = FS.status("/");
+ ASSERT_EQ(Stat.getError(), errc::no_such_file_or_directory) << FS.toString();
+}
+
+TEST_F(InMemoryFileSystemTest, WindowsPath) {
+ FS.addFile("c:/windows/system128/foo.cpp", 0, MemoryBuffer::getMemBuffer(""));
+ auto Stat = FS.status("c:");
+#if !defined(_WIN32)
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+#endif
+ Stat = FS.status("c:/windows/system128/foo.cpp");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+ FS.addFile("d:/windows/foo.cpp", 0, MemoryBuffer::getMemBuffer(""));
+ Stat = FS.status("d:/windows/foo.cpp");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+}
+
+TEST_F(InMemoryFileSystemTest, OverlayFile) {
+ FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+ NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+ auto Stat = FS.status("/");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+ Stat = FS.status("/.");
+ ASSERT_FALSE(Stat);
+ Stat = NormalizedFS.status("/.");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+ Stat = FS.status("/a");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+ ASSERT_EQ("/a", Stat->getName());
+}
+
+TEST_F(InMemoryFileSystemTest, OverlayFileNoOwn) {
+ auto Buf = MemoryBuffer::getMemBuffer("a");
+ FS.addFileNoOwn("/a", 0, Buf.get());
+ auto Stat = FS.status("/a");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+ ASSERT_EQ("/a", Stat->getName());
+}
+
+TEST_F(InMemoryFileSystemTest, OpenFileForRead) {
+ FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+ FS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
+ FS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
+ NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+ NormalizedFS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
+ NormalizedFS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
+ auto File = FS.openFileForRead("/a");
+ ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+ File = FS.openFileForRead("/a"); // Open again.
+ ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+ File = NormalizedFS.openFileForRead("/././a"); // Open again.
+ ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+ File = FS.openFileForRead("/");
+ ASSERT_EQ(File.getError(), errc::invalid_argument) << FS.toString();
+ File = FS.openFileForRead("/b");
+ ASSERT_EQ(File.getError(), errc::no_such_file_or_directory) << FS.toString();
+ File = FS.openFileForRead("./c");
+ ASSERT_FALSE(File);
+ File = FS.openFileForRead("e/../d");
+ ASSERT_FALSE(File);
+ File = NormalizedFS.openFileForRead("./c");
+ ASSERT_EQ("c", (*(*File)->getBuffer("ignored"))->getBuffer());
+ File = NormalizedFS.openFileForRead("e/../d");
+ ASSERT_EQ("d", (*(*File)->getBuffer("ignored"))->getBuffer());
+}
+
+TEST_F(InMemoryFileSystemTest, DuplicatedFile) {
+ ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")));
+ ASSERT_FALSE(FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("a")));
+ ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")));
+ ASSERT_FALSE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("b")));
+}
+
+TEST_F(InMemoryFileSystemTest, DirectoryIteration) {
+ FS.addFile("/a", 0, MemoryBuffer::getMemBuffer(""));
+ FS.addFile("/b/c", 0, MemoryBuffer::getMemBuffer(""));
+
+ std::error_code EC;
+ vfs::directory_iterator I = FS.dir_begin("/", EC);
+ ASSERT_FALSE(EC);
+ ASSERT_EQ("/a", I->getName());
+ I.increment(EC);
+ ASSERT_FALSE(EC);
+ ASSERT_EQ("/b", I->getName());
+ I.increment(EC);
+ ASSERT_FALSE(EC);
+ ASSERT_EQ(vfs::directory_iterator(), I);
+
+ I = FS.dir_begin("/b", EC);
+ ASSERT_FALSE(EC);
+ ASSERT_EQ("/b/c", I->getName());
+ I.increment(EC);
+ ASSERT_FALSE(EC);
+ ASSERT_EQ(vfs::directory_iterator(), I);
+}
+
+TEST_F(InMemoryFileSystemTest, WorkingDirectory) {
+ FS.setCurrentWorkingDirectory("/b");
+ FS.addFile("c", 0, MemoryBuffer::getMemBuffer(""));
+
+ auto Stat = FS.status("/b/c");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+ ASSERT_EQ("c", Stat->getName());
+ ASSERT_EQ("/b", *FS.getCurrentWorkingDirectory());
+
+ Stat = FS.status("c");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+}
+
// NOTE: in the tests below, we use '//root/' as our root directory, since it is
// a legal *absolute* path on Windows as well as *nix.
class VFSFromYAMLTest : public ::testing::Test {
@@ -589,10 +733,20 @@ TEST_F(VFSFromYAMLTest, MappedFiles) {
ErrorOr<vfs::Status> S = O->status("//root/file1");
ASSERT_FALSE(S.getError());
EXPECT_EQ("//root/foo/bar/a", S->getName());
+ EXPECT_TRUE(S->IsVFSMapped);
ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
EXPECT_EQ("//root/foo/bar/a", SLower->getName());
EXPECT_TRUE(S->equivalent(*SLower));
+ EXPECT_FALSE(SLower->IsVFSMapped);
+
+ // file after opening
+ auto OpenedF = O->openFileForRead("//root/file1");
+ ASSERT_FALSE(OpenedF.getError());
+ auto OpenedS = (*OpenedF)->status();
+ ASSERT_FALSE(OpenedS.getError());
+ EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
+ EXPECT_TRUE(OpenedS->IsVFSMapped);
// directory
S = O->status("//root/");
@@ -906,7 +1060,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) {
"]\n"
"}",
Lower);
- ASSERT_TRUE(FS.get() != NULL);
+ ASSERT_TRUE(FS.get() != nullptr);
IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
new vfs::OverlayFileSystem(Lower));
OpenPOWER on IntegriCloud