diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gyp | 1 | ||||
-rw-r--r-- | base/test/test_file_util.cc | 23 | ||||
-rw-r--r-- | base/test/test_file_util.h | 20 | ||||
-rw-r--r-- | base/test/test_file_util_posix.cc | 77 | ||||
-rw-r--r-- | base/test/test_file_util_win.cc | 53 |
5 files changed, 34 insertions, 140 deletions
diff --git a/base/base.gyp b/base/base.gyp index 0cbb086..e362a70 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -864,6 +864,7 @@ 'test/simple_test_tick_clock.h', 'test/task_runner_test_template.cc', 'test/task_runner_test_template.h', + 'test/test_file_util.cc', 'test/test_file_util.h', 'test/test_file_util_linux.cc', 'test/test_file_util_mac.cc', diff --git a/base/test/test_file_util.cc b/base/test/test_file_util.cc new file mode 100644 index 0000000..eef89de --- /dev/null +++ b/base/test/test_file_util.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/test_file_util.h" + +#include "base/test/test_timeouts.h" +#include "base/threading/platform_thread.h" + +namespace base { + +bool EvictFileFromSystemCacheWithRetry(const FilePath& path) { + const int kCycles = 10; + const TimeDelta kDelay = TestTimeouts::action_timeout() / kCycles; + for (int i = 0; i < kCycles; i++) { + if (file_util::EvictFileFromSystemCache(path)) + return true; + PlatformThread::Sleep(kDelay); + } + return false; +} + +} // namespace base diff --git a/base/test/test_file_util.h b/base/test/test_file_util.h index 8d1be1c..418c480 100644 --- a/base/test/test_file_util.h +++ b/base/test/test_file_util.h @@ -13,9 +13,18 @@ #include "base/files/file_path.h" namespace base { + class FilePath; -} +// Clear a specific file from the system cache like EvictFileFromSystemCache, +// but on failure it will sleep and retry. On the Windows buildbots, eviction +// can fail if the file is marked in use, and this will throw off timings that +// rely on uncached files. +bool EvictFileFromSystemCacheWithRetry(const FilePath& file); + +} // namespace base + +// TODO(brettw) move all of this to the base namespace. namespace file_util { // Wrapper over file_util::Delete. On Windows repeatedly invokes Delete in case @@ -27,15 +36,6 @@ bool DieFileDie(const base::FilePath& file, bool recurse); // to access this file will result in a cold load from the hard drive. bool EvictFileFromSystemCache(const base::FilePath& file); -// Like CopyFileNoCache but recursively copies all files and subdirectories -// in the given input directory to the output directory. Any files in the -// destination that already exist will be overwritten. -// -// Returns true on success. False means there was some error copying, so the -// state of the destination is unknown. -bool CopyRecursiveDirNoCache(const base::FilePath& source_dir, - const base::FilePath& dest_dir); - #if defined(OS_WIN) // Returns true if the volume supports Alternate Data Streams. bool VolumeSupportsADS(const base::FilePath& path); diff --git a/base/test/test_file_util_posix.cc b/base/test/test_file_util_posix.cc index 731d976..7c16cb18 100644 --- a/base/test/test_file_util_posix.cc +++ b/base/test/test_file_util_posix.cc @@ -80,83 +80,6 @@ bool DieFileDie(const base::FilePath& file, bool recurse) { return file_util::Delete(file, recurse); } -// Mostly a verbatim copy of CopyDirectory -bool CopyRecursiveDirNoCache(const base::FilePath& source_dir, - const base::FilePath& dest_dir) { - char top_dir[PATH_MAX]; - if (base::strlcpy(top_dir, source_dir.value().c_str(), - arraysize(top_dir)) >= arraysize(top_dir)) { - return false; - } - - // This function does not properly handle destinations within the source - base::FilePath real_to_path = dest_dir; - if (PathExists(real_to_path)) { - real_to_path = MakeAbsoluteFilePath(real_to_path); - if (real_to_path.empty()) - return false; - } else { - real_to_path = MakeAbsoluteFilePath(real_to_path.DirName()); - if (real_to_path.empty()) - return false; - } - if (real_to_path.value().compare(0, source_dir.value().size(), - source_dir.value()) == 0) - return false; - - bool success = true; - int traverse_type = FileEnumerator::FILES | - FileEnumerator::SHOW_SYM_LINKS | FileEnumerator::DIRECTORIES; - FileEnumerator traversal(source_dir, true, traverse_type); - - // dest_dir may not exist yet, start the loop with dest_dir - FileEnumerator::FindInfo info; - base::FilePath current = source_dir; - if (stat(source_dir.value().c_str(), &info.stat) < 0) { - DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't stat source directory: " - << source_dir.value() << " errno = " << errno; - success = false; - } - - while (success && !current.empty()) { - // |current| is the source path, including source_dir, so paste - // the suffix after source_dir onto dest_dir to create the target_path. - std::string suffix(¤t.value().c_str()[source_dir.value().size()]); - // Strip the leading '/' (if any). - if (!suffix.empty()) { - DCHECK_EQ('/', suffix[0]); - suffix.erase(0, 1); - } - const base::FilePath target_path = dest_dir.Append(suffix); - - if (S_ISDIR(info.stat.st_mode)) { - if (mkdir(target_path.value().c_str(), info.stat.st_mode & 01777) != 0 && - errno != EEXIST) { - DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't create directory: " - << target_path.value() << " errno = " << errno; - success = false; - } - } else if (S_ISREG(info.stat.st_mode)) { - if (CopyFile(current, target_path)) { - success = EvictFileFromSystemCache(target_path); - DCHECK(success); - } else { - DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't create file: " - << target_path.value(); - success = false; - } - } else { - DLOG(WARNING) << "CopyRecursiveDirNoCache() skipping non-regular file: " - << current.value(); - } - - current = traversal.Next(); - traversal.GetFindInfo(&info); - } - - return success; -} - #if !defined(OS_LINUX) && !defined(OS_MACOSX) bool EvictFileFromSystemCache(const base::FilePath& file) { // There doesn't seem to be a POSIX way to cool the disk cache. diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc index 8d28aef..8e130d8 100644 --- a/base/test/test_file_util_win.cc +++ b/base/test/test_file_util_win.cc @@ -216,59 +216,6 @@ bool EvictFileFromSystemCache(const base::FilePath& file) { return true; } -// Like CopyFileNoCache but recursively copies all files and subdirectories -// in the given input directory to the output directory. -bool CopyRecursiveDirNoCache(const base::FilePath& source_dir, - const base::FilePath& dest_dir) { - // Try to create the directory if it doesn't already exist. - if (!CreateDirectory(dest_dir)) { - if (GetLastError() != ERROR_ALREADY_EXISTS) - return false; - } - - std::vector<std::wstring> files_copied; - - base::FilePath src(source_dir.AppendASCII("*")); - - WIN32_FIND_DATA fd; - HANDLE fh = FindFirstFile(src.value().c_str(), &fd); - if (fh == INVALID_HANDLE_VALUE) - return false; - - do { - std::wstring cur_file(fd.cFileName); - if (cur_file == L"." || cur_file == L"..") - continue; // Skip these special entries. - - base::FilePath cur_source_path = source_dir.Append(cur_file); - base::FilePath cur_dest_path = dest_dir.Append(cur_file); - - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - // Recursively copy a subdirectory. We stripped "." and ".." already. - if (!CopyRecursiveDirNoCache(cur_source_path, cur_dest_path)) { - FindClose(fh); - return false; - } - } else { - // Copy the file. - if (!::CopyFile(cur_source_path.value().c_str(), - cur_dest_path.value().c_str(), false)) { - FindClose(fh); - return false; - } - - // We don't check for errors from this function, often, we are copying - // files that are in the repository, and they will have read-only set. - // This will prevent us from evicting from the cache, but these don't - // matter anyway. - EvictFileFromSystemCache(cur_dest_path); - } - } while (FindNextFile(fh, &fd)); - - FindClose(fh); - return true; -} - // Checks if the volume supports Alternate Data Streams. This is required for // the Zone Identifier implementation. bool VolumeSupportsADS(const base::FilePath& path) { |