[llvm] r367278 - [FileCollector] Add a VFS that records FS accesses using the FileCollector

Alex Lorenz via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 29 16:38:30 PDT 2019


Author: arphaman
Date: Mon Jul 29 16:38:30 2019
New Revision: 367278

URL: http://llvm.org/viewvc/llvm-project?rev=367278&view=rev
Log:
[FileCollector] Add a VFS that records FS accesses using the FileCollector

This patch adds a VFS that can be overlaid on top of another VFS
to record file system accesses using the FileCollector.
This can help to gather files that are needed for reproducers.

Differential Revision: https://reviews.llvm.org/D65411

Modified:
    llvm/trunk/include/llvm/Support/FileCollector.h
    llvm/trunk/lib/Support/FileCollector.cpp
    llvm/trunk/unittests/Support/FileCollectorTest.cpp

Modified: llvm/trunk/include/llvm/Support/FileCollector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileCollector.h?rev=367278&r1=367277&r2=367278&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/FileCollector.h (original)
+++ llvm/trunk/include/llvm/Support/FileCollector.h Mon Jul 29 16:38:30 2019
@@ -37,6 +37,12 @@ public:
   /// removed after it was added to the mapping.
   std::error_code copyFiles(bool StopOnError = true);
 
+  /// Create a VFS that collects all the paths that might be looked at by the
+  /// file system accesses.
+  static IntrusiveRefCntPtr<vfs::FileSystem>
+  createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
+                     std::shared_ptr<FileCollector> Collector);
+
 private:
   void addFileImpl(StringRef SrcPath);
 

Modified: llvm/trunk/lib/Support/FileCollector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FileCollector.cpp?rev=367278&r1=367277&r2=367278&view=diff
==============================================================================
--- llvm/trunk/lib/Support/FileCollector.cpp (original)
+++ llvm/trunk/lib/Support/FileCollector.cpp Mon Jul 29 16:38:30 2019
@@ -187,3 +187,82 @@ std::error_code FileCollector::writeMapp
 
   return {};
 }
+
+namespace {
+
+class FileCollectorFileSystem : public vfs::FileSystem {
+public:
+  explicit FileCollectorFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS,
+                                   std::shared_ptr<FileCollector> Collector)
+      : FS(std::move(FS)), Collector(std::move(Collector)) {}
+
+  llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override {
+    auto Result = FS->status(Path);
+    if (Result && Result->exists())
+      Collector->addFile(Path);
+    return Result;
+  }
+
+  llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
+  openFileForRead(const Twine &Path) override {
+    auto Result = FS->openFileForRead(Path);
+    if (Result && *Result)
+      Collector->addFile(Path);
+    return Result;
+  }
+
+  llvm::vfs::directory_iterator dir_begin(const llvm::Twine &Dir,
+                                          std::error_code &EC) override {
+    auto It = FS->dir_begin(Dir, EC);
+    if (EC)
+      return It;
+    // Collect everything that's listed in case the user needs it.
+    Collector->addFile(Dir);
+    for (; !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
+      if (It->type() == sys::fs::file_type::regular_file ||
+          It->type() == sys::fs::file_type::directory_file ||
+          It->type() == sys::fs::file_type::symlink_file) {
+        Collector->addFile(It->path());
+      }
+    }
+    if (EC)
+      return It;
+    // Return a new iterator.
+    return FS->dir_begin(Dir, EC);
+  }
+
+  std::error_code getRealPath(const Twine &Path,
+                              SmallVectorImpl<char> &Output) const override {
+    auto EC = FS->getRealPath(Path, Output);
+    if (!EC) {
+      Collector->addFile(Path);
+      if (Output.size() > 0)
+        Collector->addFile(Output);
+    }
+    return EC;
+  }
+
+  std::error_code isLocal(const Twine &Path, bool &Result) override {
+    return FS->isLocal(Path, Result);
+  }
+
+  llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
+    return FS->getCurrentWorkingDirectory();
+  }
+
+  std::error_code setCurrentWorkingDirectory(const llvm::Twine &Path) override {
+    return FS->setCurrentWorkingDirectory(Path);
+  }
+
+private:
+  IntrusiveRefCntPtr<vfs::FileSystem> FS;
+  std::shared_ptr<FileCollector> Collector;
+};
+
+} // end anonymous namespace
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+FileCollector::createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
+                                  std::shared_ptr<FileCollector> Collector) {
+  return new FileCollectorFileSystem(std::move(BaseFS), std::move(Collector));
+}

Modified: llvm/trunk/unittests/Support/FileCollectorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/FileCollectorTest.cpp?rev=367278&r1=367277&r2=367278&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/FileCollectorTest.cpp (original)
+++ llvm/trunk/unittests/Support/FileCollectorTest.cpp Mon Jul 29 16:38:30 2019
@@ -179,6 +179,44 @@ TEST(FileCollectorTest, recordAndConstru
   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));
+
+  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));
+}
+
 #ifndef _WIN32
 TEST(FileCollectorTest, Symlinks) {
   // Root where the original files live.
@@ -239,4 +277,21 @@ TEST(FileCollectorTest, Symlinks) {
     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




More information about the llvm-commits mailing list