LibclangTest: remove libclang-test-* tmp dir reliably
authorIgor Kushnir <igorkuo@gmail.com>
Wed, 1 Mar 2023 14:44:43 +0000 (09:44 -0500)
committerAaron Ballman <aaron@aaronballman.com>
Wed, 1 Mar 2023 14:45:24 +0000 (09:45 -0500)
Temporary directories created by two LibclangReparseTest tests -
ReparseWithModule and clang_parseTranslationUnit2FullArgv - remained in
the system temporary directory after running libclangTests, because not
all files and subdirectories created in TestDir were added to set
LibclangParseTest::Files.

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

clang/unittests/libclang/LibclangTest.cpp
clang/unittests/libclang/TestUtils.h

index 809426a..11a729f 100644 (file)
@@ -515,6 +515,8 @@ TEST_F(LibclangReparseTest, ReparseWithModule) {
   WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
   WriteFile(ModName, ModFile);
 
+  // Removing recursively is necessary to delete the module cache.
+  RemoveTestDirRecursivelyDuringTeardown = true;
   std::string ModulesCache = std::string("-fmodules-cache-path=") + TestDir;
   const char *Args[] = { "-fmodules", ModulesCache.c_str(),
                          "-I", TestDir.c_str() };
index 8900d79..c69746c 100644 (file)
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
+#include "gtest/gtest.h"
 #include <fstream>
+#include <functional>
 #include <memory>
 #include <string>
 #include <vector>
-#include "gtest/gtest.h"
 
 class LibclangParseTest : public ::testing::Test {
-  std::set<std::string> Files;
+  // std::greater<> to remove files before their parent dirs in TearDown().
+  std::set<std::string, std::greater<>> Files;
   typedef std::unique_ptr<std::string> fixed_addr_string;
   std::map<fixed_addr_string, fixed_addr_string> UnsavedFileContents;
 public:
   std::string TestDir;
+  bool RemoveTestDirRecursivelyDuringTeardown = false;
   CXIndex Index;
   CXTranslationUnit ClangTU;
   unsigned TUFlags;
@@ -43,16 +46,26 @@ public:
   void TearDown() override {
     clang_disposeTranslationUnit(ClangTU);
     clang_disposeIndex(Index);
+
+    namespace fs = llvm::sys::fs;
     for (const std::string &Path : Files)
-      llvm::sys::fs::remove(Path);
-    llvm::sys::fs::remove(TestDir);
+      EXPECT_FALSE(fs::remove(Path, /*IgnoreNonExisting=*/false));
+    if (RemoveTestDirRecursivelyDuringTeardown)
+      EXPECT_FALSE(fs::remove_directories(TestDir, /*IgnoreErrors=*/false));
+    else
+      EXPECT_FALSE(fs::remove(TestDir, /*IgnoreNonExisting=*/false));
   }
   void WriteFile(std::string &Filename, const std::string &Contents) {
     if (!llvm::sys::path::is_absolute(Filename)) {
       llvm::SmallString<256> Path(TestDir);
-      llvm::sys::path::append(Path, Filename);
+      namespace path = llvm::sys::path;
+      for (auto FileI = path::begin(Filename), FileEnd = path::end(Filename);
+           FileI != FileEnd; ++FileI) {
+        ASSERT_NE(*FileI, ".");
+        path::append(Path, *FileI);
+        Files.emplace(Path.str());
+      }
       Filename = std::string(Path.str());
-      Files.insert(Filename);
     }
     llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename));
     std::ofstream OS(Filename);