diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-06 21:24:20 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-06 21:24:20 +0000 |
commit | 6a48fb51b8f5f627781177ec8af1cf1c56a03abe (patch) | |
tree | de891e2d1189c58be61101dd74a05d49b147c5f4 /base | |
parent | 7c056098ec8854a56ad774e1e54b6b40923e5e8b (diff) | |
download | chromium_src-6a48fb51b8f5f627781177ec8af1cf1c56a03abe.zip chromium_src-6a48fb51b8f5f627781177ec8af1cf1c56a03abe.tar.gz chromium_src-6a48fb51b8f5f627781177ec8af1cf1c56a03abe.tar.bz2 |
Delete CopyRecursiveDirNoCache from test_file_util.
This function was used in only one place and the implementation was
copy-and-pasted. This replaces the call with a cross-platform implementation in
the one file that needs it.
This is a reland of r194664 which was a reland of r192940. This version does
not attempt to fix the startup test caching bugs I discovered when rewriting
the function. I filed bug 237904 for this.
BUG=
Review URL: https://codereview.chromium.org/14577009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198539 0039d316-1c4b-4281-b951-d872f2087c98
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) { |