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