summaryrefslogtreecommitdiff
path: root/unittests/Basic/VirtualFileSystemTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Basic/VirtualFileSystemTest.cpp')
-rw-r--r--unittests/Basic/VirtualFileSystemTest.cpp128
1 files changed, 116 insertions, 12 deletions
diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp
index 7abc549292e2b..3b26488a7fd9f 100644
--- a/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/unittests/Basic/VirtualFileSystemTest.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
@@ -29,7 +31,7 @@ struct DummyFile : public vfs::File {
bool IsVolatile) override {
llvm_unreachable("unimplemented");
}
- virtual std::error_code close() override { return std::error_code(); }
+ std::error_code close() override { return std::error_code(); }
};
class DummyFileSystem : public vfs::FileSystem {
@@ -348,7 +350,6 @@ TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
ASSERT_FALSE(EC);
ASSERT_NE(vfs::recursive_directory_iterator(), I);
-
std::vector<std::string> Contents;
for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
I.increment(EC)) {
@@ -371,16 +372,23 @@ TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
}
template <typename DirIter>
-static void checkContents(DirIter I, ArrayRef<StringRef> Expected) {
+static void checkContents(DirIter I, ArrayRef<StringRef> ExpectedOut) {
std::error_code EC;
- auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end();
- for (DirIter E;
- !EC && I != E && ExpectedIter != ExpectedEnd;
- I.increment(EC), ++ExpectedIter)
- EXPECT_EQ(*ExpectedIter, I->getName());
-
- EXPECT_EQ(ExpectedEnd, ExpectedIter);
- EXPECT_EQ(DirIter(), I);
+ SmallVector<StringRef, 4> Expected(ExpectedOut.begin(), ExpectedOut.end());
+ SmallVector<std::string, 4> InputToCheck;
+
+ // Do not rely on iteration order to check for contents, sort both
+ // content vectors before comparison.
+ for (DirIter E; !EC && I != E; I.increment(EC))
+ InputToCheck.push_back(I->getName());
+
+ std::sort(InputToCheck.begin(), InputToCheck.end());
+ std::sort(Expected.begin(), Expected.end());
+ EXPECT_EQ(InputToCheck.size(), Expected.size());
+
+ unsigned LastElt = std::min(InputToCheck.size(), Expected.size());
+ for (unsigned Idx = 0; Idx != LastElt; ++Idx)
+ EXPECT_EQ(StringRef(InputToCheck[Idx]), Expected[Idx]);
}
TEST(VirtualFileSystemTest, OverlayIteration) {
@@ -663,7 +671,7 @@ public:
getFromYAMLRawString(StringRef Content,
IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(Content);
- return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, this,
+ return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, "", this,
ExternalFS);
}
@@ -674,6 +682,12 @@ public:
VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
return getFromYAMLRawString(VersionPlusContent, ExternalFS);
}
+
+ // This is intended as a "XFAIL" for windows hosts.
+ bool supportsSameDirMultipleYAMLEntries() {
+ Triple Host(Triple::normalize(sys::getProcessTriple()));
+ return !Host.isOSWindows();
+ }
};
TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
@@ -1060,3 +1074,93 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) {
checkContents(O->dir_begin("//root/foo/bar", EC),
{"//root/foo/bar/a", "//root/foo/bar/b"});
}
+
+TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) {
+ // https://llvm.org/bugs/show_bug.cgi?id=27725
+ if (!supportsSameDirMultipleYAMLEntries())
+ return;
+
+ IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+ Lower->addDirectory("//root/zab");
+ Lower->addDirectory("//root/baz");
+ Lower->addRegularFile("//root/zab/a");
+ Lower->addRegularFile("//root/zab/b");
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+ "{ 'use-external-names': false,\n"
+ " 'roots': [\n"
+ "{\n"
+ " 'type': 'directory',\n"
+ " 'name': '//root/baz/',\n"
+ " 'contents': [ {\n"
+ " 'type': 'file',\n"
+ " 'name': 'x',\n"
+ " 'external-contents': '//root/zab/a'\n"
+ " }\n"
+ " ]\n"
+ "},\n"
+ "{\n"
+ " 'type': 'directory',\n"
+ " 'name': '//root/baz/',\n"
+ " 'contents': [ {\n"
+ " 'type': 'file',\n"
+ " 'name': 'y',\n"
+ " 'external-contents': '//root/zab/b'\n"
+ " }\n"
+ " ]\n"
+ "}\n"
+ "]\n"
+ "}",
+ Lower);
+ ASSERT_TRUE(FS.get() != nullptr);
+
+ IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+ new vfs::OverlayFileSystem(Lower));
+ O->pushOverlay(FS);
+
+ std::error_code EC;
+
+ checkContents(O->dir_begin("//root/baz/", EC),
+ {"//root/baz/x", "//root/baz/y"});
+}
+
+TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) {
+
+ IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+ Lower->addDirectory("//root/a");
+ Lower->addDirectory("//root/a/b");
+ Lower->addDirectory("//root/a/b/c");
+ Lower->addRegularFile("//root/a/b/c/file");
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+ "{ 'use-external-names': false,\n"
+ " 'roots': [\n"
+ "{\n"
+ " 'type': 'directory',\n"
+ " 'name': '//root/a/b/c/',\n"
+ " 'contents': [ {\n"
+ " 'type': 'file',\n"
+ " 'name': 'file',\n"
+ " 'external-contents': '//root/a/b/c/file'\n"
+ " }\n"
+ " ]\n"
+ "},\n"
+ "]\n"
+ "}",
+ Lower);
+ ASSERT_TRUE(FS.get() != nullptr);
+
+ IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+ new vfs::OverlayFileSystem(Lower));
+ O->pushOverlay(FS);
+
+ std::error_code EC;
+
+ // Test recursive_directory_iterator level()
+ vfs::recursive_directory_iterator I = vfs::recursive_directory_iterator(
+ *O, "//root", EC), E;
+ ASSERT_FALSE(EC);
+ for (int l = 0; I != E; I.increment(EC), ++l) {
+ ASSERT_FALSE(EC);
+ EXPECT_EQ(I.level(), l);
+ }
+ EXPECT_EQ(I, E);
+}