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 Workerbool 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 WorkerFilePath 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 WorkerFilePath 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