test_file_util.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright (c) 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/test/test_file_util.h"
  5. #include <vector>
  6. #include "base/files/file_path.h"
  7. #include "base/files/file_util.h"
  8. #include "base/test/test_timeouts.h"
  9. #include "base/threading/platform_thread.h"
  10. #include "base/threading/thread_restrictions.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace base {
  13. namespace {
  14. constexpr FilePath::CharType kDirPrefix[] =
  15. FILE_PATH_LITERAL("test_scoped_temp_dir");
  16. // Deletes all registered file paths upon test completion. There can only be
  17. // one instance at a time.
  18. class PathDeleterOnTestEnd : public testing::EmptyTestEventListener {
  19. public:
  20. PathDeleterOnTestEnd() {
  21. DCHECK(!instance_);
  22. instance_ = this;
  23. }
  24. ~PathDeleterOnTestEnd() override {
  25. DCHECK_EQ(instance_, this);
  26. instance_ = nullptr;
  27. }
  28. PathDeleterOnTestEnd(const PathDeleterOnTestEnd&) = delete;
  29. PathDeleterOnTestEnd& operator=(const PathDeleterOnTestEnd&) = delete;
  30. static PathDeleterOnTestEnd* GetInstance() { return instance_; }
  31. void DeletePathRecursivelyUponTestEnd(const FilePath& path) {
  32. file_paths_to_delete_.push_back(path);
  33. }
  34. // EmptyTestEventListener overrides.
  35. void OnTestEnd(const testing::TestInfo& test_info) override {
  36. if (file_paths_to_delete_.empty()) {
  37. // Nothing to delete since the last test ended.
  38. return;
  39. }
  40. ScopedAllowBlockingForTesting allow_blocking;
  41. for (const FilePath& file_path : file_paths_to_delete_) {
  42. if (!DieFileDie(file_path, /*recurse=*/true)) {
  43. ADD_FAILURE() << "Failed to delete temporary directory for testing: "
  44. << file_path;
  45. }
  46. }
  47. file_paths_to_delete_.clear();
  48. }
  49. private:
  50. static PathDeleterOnTestEnd* instance_;
  51. std::vector<FilePath> file_paths_to_delete_;
  52. };
  53. // static
  54. PathDeleterOnTestEnd* PathDeleterOnTestEnd::instance_ = nullptr;
  55. } // namespace
  56. bool EvictFileFromSystemCacheWithRetry(const FilePath& path) {
  57. const int kCycles = 10;
  58. const TimeDelta kDelay = TestTimeouts::action_timeout() / kCycles;
  59. for (int i = 0; i < kCycles; i++) {
  60. if (EvictFileFromSystemCache(path))
  61. return true;
  62. PlatformThread::Sleep(kDelay);
  63. }
  64. return false;
  65. }
  66. FilePath CreateUniqueTempDirectoryScopedToTest() {
  67. ScopedAllowBlockingForTesting allow_blocking;
  68. FilePath path;
  69. if (!CreateNewTempDirectory(kDirPrefix, &path)) {
  70. ADD_FAILURE() << "Failed to create unique temporary directory for testing.";
  71. return FilePath();
  72. }
  73. if (!PathDeleterOnTestEnd::GetInstance()) {
  74. // Append() transfers ownership of the listener. This means
  75. // PathDeleterOnTestEnd::GetInstance() will return non-null until all tests
  76. // are run and the test suite destroyed.
  77. testing::UnitTest::GetInstance()->listeners().Append(
  78. new PathDeleterOnTestEnd());
  79. DCHECK(PathDeleterOnTestEnd::GetInstance());
  80. }
  81. PathDeleterOnTestEnd::GetInstance()->DeletePathRecursivelyUponTestEnd(path);
  82. return path;
  83. }
  84. } // namespace base