diff options
author | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 19:58:09 +0000 |
---|---|---|
committer | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 19:58:09 +0000 |
commit | 715fe2473792264b86294357d7f783a43c7961f1 (patch) | |
tree | 9bf76ab4e838efbd50480474ed4b0ce382d85814 /base | |
parent | 17c4ce62ff8cff51f81c0cd79622a095754695bb (diff) | |
download | chromium_src-715fe2473792264b86294357d7f783a43c7961f1.zip chromium_src-715fe2473792264b86294357d7f783a43c7961f1.tar.gz chromium_src-715fe2473792264b86294357d7f783a43c7961f1.tar.bz2 |
Revert 194664 "Delete CopyRecursiveDirNoCache from test_file_util."
Broke the results of the startup_benchmark on linux.
BUG=237858
> Delete CopyRecursiveDirNoCache from test_file_util.
>
> This function was used in only one place and that place was wrong.
>
> The implementation was long and complicated on Windows, and long and
> complicated and copied verbatim from elsewhere with 3 lines different on Posix.
>
> The place it was used was in the proxy launcher when copying the profile. It's
> not clear to me why we wouldn't want the profile files in the filesystem cache
> when running tests. Quite the opposite, we want the tests to run as fast as
> possible.
>
> The only place this should matter is in the startup tests. And the startup
> tests do things to the profile after it gets copied that should page some files
> back in! This adds another step to the startup tests to evict the profile files
> for cold startup tests only.
>
> This is a reland of r192940 which crashed on Mac. The previous perf startup
> test used the profile directory before it was initialized. That patch was in
> turn a reland r191854 which broke the startup test. The previous patch
> replaced the CopyRecursive call with CopyDirectory which does something
> slightly different. This new patch implements a CopyDirectoryContents function
> to do what's required here.
TBR=brettw@chromium.org
Review URL: https://codereview.chromium.org/14799003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198175 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/test/test_file_util.h | 9 | ||||
-rw-r--r-- | base/test/test_file_util_posix.cc | 77 | ||||
-rw-r--r-- | base/test/test_file_util_win.cc | 53 |
3 files changed, 139 insertions, 0 deletions
diff --git a/base/test/test_file_util.h b/base/test/test_file_util.h index c41045e..8d1be1c 100644 --- a/base/test/test_file_util.h +++ b/base/test/test_file_util.h @@ -27,6 +27,15 @@ 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 7c16cb18..731d976 100644 --- a/base/test/test_file_util_posix.cc +++ b/base/test/test_file_util_posix.cc @@ -80,6 +80,83 @@ 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 8e130d8..8d28aef 100644 --- a/base/test/test_file_util_win.cc +++ b/base/test/test_file_util_win.cc @@ -216,6 +216,59 @@ 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) { |