123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- //===-- FileCollectorTest.cpp -----------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "gmock/gmock.h"
- #include "gtest/gtest.h"
- #include "llvm/Support/FileCollector.h"
- #include "llvm/Support/FileSystem.h"
- using namespace llvm;
- namespace llvm {
- namespace vfs {
- inline bool operator==(const llvm::vfs::YAMLVFSEntry &LHS,
- const llvm::vfs::YAMLVFSEntry &RHS) {
- return LHS.VPath == RHS.VPath && LHS.RPath == RHS.RPath;
- }
- } // namespace vfs
- } // namespace llvm
- namespace {
- class TestingFileCollector : public FileCollector {
- public:
- using FileCollector::FileCollector;
- using FileCollector::Root;
- using FileCollector::Seen;
- using FileCollector::SymlinkMap;
- using FileCollector::VFSWriter;
- bool hasSeen(StringRef fs) {
- return Seen.find(fs) != Seen.end();
- }
- };
- struct ScopedDir {
- SmallString<128> Path;
- ScopedDir(const Twine &Name, bool Unique = false) {
- std::error_code EC;
- if (Unique) {
- EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
- } else {
- Path = Name.str();
- EC = llvm::sys::fs::create_directory(Twine(Path));
- }
- if (EC)
- Path = "";
- EXPECT_FALSE(EC);
- // Ensure the path is the real path so tests can use it to compare against
- // realpath output.
- SmallString<128> RealPath;
- if (!llvm::sys::fs::real_path(Path, RealPath))
- Path.swap(RealPath);
- }
- ~ScopedDir() {
- if (Path != "") {
- EXPECT_FALSE(llvm::sys::fs::remove_directories(Path.str()));
- }
- }
- operator StringRef() { return Path.str(); }
- };
- struct ScopedLink {
- SmallString<128> Path;
- ScopedLink(const Twine &To, const Twine &From) {
- Path = From.str();
- std::error_code EC = sys::fs::create_link(To, From);
- if (EC)
- Path = "";
- EXPECT_FALSE(EC);
- }
- ~ScopedLink() {
- if (Path != "") {
- EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
- }
- }
- operator StringRef() { return Path.str(); }
- };
- struct ScopedFile {
- SmallString<128> Path;
- ScopedFile(const Twine &Name) {
- std::error_code EC;
- EC = llvm::sys::fs::createUniqueFile(Name, Path);
- if (EC)
- Path = "";
- EXPECT_FALSE(EC);
- }
- ~ScopedFile() {
- if (Path != "") {
- EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
- }
- }
- operator StringRef() { return Path.str(); }
- };
- } // end anonymous namespace
- TEST(FileCollectorTest, addFile) {
- ScopedDir root("add_file_root", true);
- std::string root_fs = root.Path.str();
- TestingFileCollector FileCollector(root_fs, root_fs);
- FileCollector.addFile("/path/to/a");
- FileCollector.addFile("/path/to/b");
- FileCollector.addFile("/path/to/c");
- // Make sure the root is correct.
- EXPECT_EQ(FileCollector.Root, root_fs);
- // Make sure we've seen all the added files.
- EXPECT_TRUE(FileCollector.hasSeen("/path/to/a"));
- EXPECT_TRUE(FileCollector.hasSeen("/path/to/b"));
- EXPECT_TRUE(FileCollector.hasSeen("/path/to/c"));
- // Make sure we've only seen the added files.
- EXPECT_FALSE(FileCollector.hasSeen("/path/to/d"));
- }
- TEST(FileCollectorTest, copyFiles) {
- ScopedDir file_root("file_root", true);
- ScopedFile a(file_root + "/aaa");
- ScopedFile b(file_root + "/bbb");
- ScopedFile c(file_root + "/ccc");
- // Create file collector and add files.
- ScopedDir root("copy_files_root", true);
- std::string root_fs = root.Path.str();
- TestingFileCollector FileCollector(root_fs, root_fs);
- FileCollector.addFile(a.Path);
- FileCollector.addFile(b.Path);
- FileCollector.addFile(c.Path);
- // Make sure we can copy the files.
- std::error_code ec = FileCollector.copyFiles(true);
- EXPECT_FALSE(ec);
- // Now add a bogus file and make sure we error out.
- FileCollector.addFile("/some/bogus/file");
- ec = FileCollector.copyFiles(true);
- EXPECT_TRUE(ec);
- // However, if stop_on_error is true the copy should still succeed.
- ec = FileCollector.copyFiles(false);
- EXPECT_FALSE(ec);
- }
- TEST(FileCollectorTest, recordAndConstructDirectory) {
- ScopedDir file_root("dir_root", true);
- ScopedDir subdir(file_root + "/subdir");
- ScopedDir subdir2(file_root + "/subdir2");
- ScopedFile a(subdir2 + "/a");
- // Create file collector and add files.
- ScopedDir root("copy_files_root", true);
- std::string root_fs = root.Path.str();
- TestingFileCollector FileCollector(root_fs, root_fs);
- FileCollector.addFile(a.Path);
- // The empty directory isn't seen until we add it.
- EXPECT_TRUE(FileCollector.hasSeen(a.Path));
- EXPECT_FALSE(FileCollector.hasSeen(subdir.Path));
- FileCollector.addFile(subdir.Path);
- EXPECT_TRUE(FileCollector.hasSeen(subdir.Path));
- // Make sure we can construct the directory.
- std::error_code ec = FileCollector.copyFiles(true);
- EXPECT_FALSE(ec);
- bool IsDirectory = false;
- llvm::SmallString<128> SubdirInRoot = root.Path;
- llvm::sys::path::append(SubdirInRoot,
- llvm::sys::path::relative_path(subdir.Path));
- ec = sys::fs::is_directory(SubdirInRoot, IsDirectory);
- EXPECT_FALSE(ec);
- ASSERT_TRUE(IsDirectory);
- }
- TEST(FileCollectorTest, recordVFSAccesses) {
- ScopedDir file_root("dir_root", true);
- ScopedDir subdir(file_root + "/subdir");
- ScopedDir subdir2(file_root + "/subdir2");
- ScopedFile a(subdir2 + "/a");
- ScopedFile b(file_root + "/b");
- ScopedDir subdir3(file_root + "/subdir3");
- ScopedFile subdir3a(subdir3 + "/aa");
- ScopedDir subdir3b(subdir3 + "/subdirb");
- {
- ScopedFile subdir3fileremoved(subdir3 + "/removed");
- }
- // Create file collector and add files.
- ScopedDir root("copy_files_root", true);
- std::string root_fs = root.Path.str();
- auto Collector = std::make_shared<TestingFileCollector>(root_fs, root_fs);
- auto VFS =
- FileCollector::createCollectorVFS(vfs::getRealFileSystem(), Collector);
- VFS->status(a.Path);
- EXPECT_TRUE(Collector->hasSeen(a.Path));
- VFS->openFileForRead(b.Path);
- EXPECT_TRUE(Collector->hasSeen(b.Path));
- VFS->status(subdir.Path);
- EXPECT_TRUE(Collector->hasSeen(subdir.Path));
- #ifndef _WIN32
- std::error_code EC;
- auto It = VFS->dir_begin(subdir3.Path, EC);
- EXPECT_FALSE(EC);
- EXPECT_TRUE(Collector->hasSeen(subdir3.Path));
- EXPECT_TRUE(Collector->hasSeen(subdir3a.Path));
- EXPECT_TRUE(Collector->hasSeen(subdir3b.Path));
- std::string RemovedFileName = (Twine(subdir3.Path) + "/removed").str();
- EXPECT_FALSE(Collector->hasSeen(RemovedFileName));
- #endif
- }
- #ifndef _WIN32
- TEST(FileCollectorTest, Symlinks) {
- // Root where the original files live.
- ScopedDir file_root("file_root", true);
- // Create some files in the file root.
- ScopedFile a(file_root + "/aaa");
- ScopedFile b(file_root + "/bbb");
- ScopedFile c(file_root + "/ccc");
- // Create a directory foo with file ddd.
- ScopedDir foo(file_root + "/foo");
- ScopedFile d(foo + "/ddd");
- // Create a file eee in the foo's parent directory.
- ScopedFile e(foo + "/../eee");
- // Create a symlink bar pointing to foo.
- ScopedLink symlink(file_root + "/foo", file_root + "/bar");
- // Root where files are copied to.
- ScopedDir reproducer_root("reproducer_root", true);
- std::string root_fs = reproducer_root.Path.str();
- TestingFileCollector FileCollector(root_fs, root_fs);
- // Add all the files to the collector.
- FileCollector.addFile(a.Path);
- FileCollector.addFile(b.Path);
- FileCollector.addFile(c.Path);
- FileCollector.addFile(d.Path);
- FileCollector.addFile(e.Path);
- FileCollector.addFile(file_root + "/bar/ddd");
- auto mapping = FileCollector.VFSWriter.getMappings();
- {
- // Make sure the common case works.
- std::string vpath = (file_root + "/aaa").str();
- std::string rpath = (reproducer_root.Path + file_root.Path + "/aaa").str();
- printf("%s -> %s\n", vpath.c_str(), rpath.c_str());
- EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath)));
- }
- {
- // Make sure the virtual path points to the real source path.
- std::string vpath = (file_root + "/bar/ddd").str();
- std::string rpath =
- (reproducer_root.Path + file_root.Path + "/foo/ddd").str();
- printf("%s -> %s\n", vpath.c_str(), rpath.c_str());
- EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath)));
- }
- {
- // Make sure that .. is removed from the source path.
- std::string vpath = (file_root + "/eee").str();
- std::string rpath = (reproducer_root.Path + file_root.Path + "/eee").str();
- printf("%s -> %s\n", vpath.c_str(), rpath.c_str());
- EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath)));
- }
- }
- TEST(FileCollectorTest, recordVFSSymlinkAccesses) {
- ScopedDir file_root("dir_root", true);
- ScopedFile a(file_root + "/a");
- ScopedLink symlink(file_root + "/a", file_root + "/b");
- // Create file collector and add files.
- ScopedDir root("copy_files_root", true);
- std::string root_fs = root.Path.str();
- auto Collector = std::make_shared<TestingFileCollector>(root_fs, root_fs);
- auto VFS =
- FileCollector::createCollectorVFS(vfs::getRealFileSystem(), Collector);
- SmallString<256> Output;
- VFS->getRealPath(symlink.Path, Output);
- EXPECT_TRUE(Collector->hasSeen(a.Path));
- EXPECT_TRUE(Collector->hasSeen(symlink.Path));
- }
- #endif
|