blob: 8d9391800e66908f38bb9257a9c3b53e7f2914b0 [file] [log] [blame]
// Copyright (c) 2012 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 "chrome/test/mini_installer_test/installer_path_provider.h"
#include <algorithm>
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
#include "chrome/test/mini_installer_test/installer_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
struct FilePathInfo {
file_util::FileEnumerator::FindInfo info;
FilePath path;
};
bool CompareDate(const FilePathInfo& a,
const FilePathInfo& b) {
#if defined(OS_POSIX)
return a.info.stat.st_mtime > b.info.stat.st_mtime;
#elif defined(OS_WIN)
if (a.info.ftLastWriteTime.dwHighDateTime ==
b.info.ftLastWriteTime.dwHighDateTime) {
return a.info.ftLastWriteTime.dwLowDateTime >
b.info.ftLastWriteTime.dwLowDateTime;
} else {
return a.info.ftLastWriteTime.dwHighDateTime >
b.info.ftLastWriteTime.dwHighDateTime;
}
#endif
}
// Get list of file |type| matching |pattern| in |root|.
// The list is sorted in last modified date order.
// Return true if files/directories are found.
bool FindMatchingFiles(const FilePath& root,
const std::string& pattern,
file_util::FileEnumerator::FileType type,
std::vector<FilePath>* paths) {
file_util::FileEnumerator files(root, false, type,
FilePath().AppendASCII(pattern).value());
std::vector<FilePathInfo> matches;
for (FilePath current = files.Next(); !current.empty();
current = files.Next()) {
FilePathInfo entry;
files.GetFindInfo(&entry.info);
entry.path = current;
matches.push_back(entry);
}
if (matches.empty())
return false;
std::sort(matches.begin(), matches.end(), CompareDate);
std::vector<FilePathInfo>::iterator current;
for (current = matches.begin(); current != matches.end(); ++current) {
paths->push_back(current->path);
}
return true;
}
bool FindNewestMatchingFile(const FilePath& root,
const std::string& pattern,
file_util::FileEnumerator::FileType type,
FilePath* path) {
std::vector<FilePath> paths;
if (FindMatchingFiles(root, pattern, type, &paths)) {
*path = paths[0];
return true;
}
return false;
}
} // namespace
namespace installer_test {
InstallerPathProvider::InstallerPathProvider() {
FilePath full_installer, previous_installer;
if (!GetFullInstaller(&full_installer) ||
!GetPreviousInstaller(&previous_installer))
return;
current_build_ =
full_installer.DirName().DirName().BaseName().MaybeAsASCII();
previous_build_ =
previous_installer.DirName().DirName().BaseName().MaybeAsASCII();
}
InstallerPathProvider::InstallerPathProvider(
const std::string& build_under_test) : current_build_(build_under_test) {
FilePath full_installer, previous_installer;
if (!GetFullInstaller(&full_installer) ||
!GetPreviousInstaller(&previous_installer))
return;
previous_build_ =
previous_installer.DirName().DirName().BaseName().MaybeAsASCII();
}
InstallerPathProvider::~InstallerPathProvider() {}
bool InstallerPathProvider::GetFullInstaller(FilePath* path) {
std::string full_installer_pattern("*_chrome_installer*");
return GetInstaller(full_installer_pattern, path);
}
bool InstallerPathProvider::GetDiffInstaller(FilePath* path) {
std::string diff_installer_pattern("*_from_*");
return GetInstaller(diff_installer_pattern, path);
}
bool InstallerPathProvider::GetMiniInstaller(FilePath* path) {
// Use local copy of installer, else fall back to filer.
FilePath mini_installer = PathFromExeDir(
mini_installer_constants::kChromeMiniInstallerExecutable);
if (file_util::PathExists(mini_installer)) {
*path = mini_installer;
return true;
}
std::string mini_installer_pattern("mini_installer.exe");
return GetInstaller(mini_installer_pattern, path);
}
bool InstallerPathProvider::GetPreviousInstaller(FilePath* path) {
std::string diff_installer_pattern("*_from_*");
std::string full_installer_pattern("*_chrome_installer*");
FilePath diff_installer;
if (!GetInstaller(diff_installer_pattern, &diff_installer))
return false;
FilePath previous_installer;
std::vector<std::string> tokenized_name;
Tokenize(diff_installer.BaseName().MaybeAsASCII(),
"_", &tokenized_name);
std::string build_pattern = base::StringPrintf(
"*%s", tokenized_name[2].c_str());
std::vector<FilePath> previous_build;
if (FindMatchingFiles(diff_installer.DirName().DirName().DirName(),
build_pattern, file_util::FileEnumerator::DIRECTORIES,
&previous_build)) {
FilePath windir = previous_build.at(0).Append(
mini_installer_constants::kWinFolder);
FindNewestMatchingFile(windir, full_installer_pattern,
file_util::FileEnumerator::FILES, &previous_installer);
}
if (previous_installer.empty())
return false;
*path = previous_installer;
return true;
}
bool InstallerPathProvider::GetStandaloneInstaller(FilePath* path) {
// Get standalone installer.
FilePath standalone_installer(
mini_installer_constants::kChromeStandAloneInstallerLocation);
// Get the file name.
std::vector<std::string> tokenized_build_number;
if (current_build_.empty())
return false;
Tokenize(current_build_, ".", &tokenized_build_number);
std::string standalone_installer_filename = base::StringPrintf(
"%s%s_%s.exe",
FilePath(mini_installer_constants::kUntaggedInstallerPattern)
.MaybeAsASCII().c_str(),
tokenized_build_number[2].c_str(),
tokenized_build_number[3].c_str());
standalone_installer = standalone_installer.AppendASCII(current_build_)
.Append(mini_installer_constants::kWinFolder)
.AppendASCII(standalone_installer_filename);
*path = standalone_installer;
return file_util::PathExists(standalone_installer);
}
bool InstallerPathProvider::GetSignedStandaloneInstaller(FilePath* path) {
FilePath standalone_installer;
if (!GetStandaloneInstaller(&standalone_installer))
return false;
FilePath tagged_installer = PathFromExeDir(
mini_installer_constants::kStandaloneInstaller);
CommandLine sign_command = CommandLine::FromString(
base::StringPrintf(L"%ls %ls %ls %ls",
mini_installer_constants::kChromeApplyTagExe,
standalone_installer.value().c_str(),
tagged_installer.value().c_str(),
mini_installer_constants::kChromeApplyTagParameters));
if (!installer_test::RunAndWaitForCommandToFinish(sign_command))
return false;
*path = PathFromExeDir(mini_installer_constants::kStandaloneInstaller);
return true;
}
FilePath InstallerPathProvider::PathFromExeDir(
const FilePath::StringType& name) {
FilePath path;
PathService::Get(base::DIR_EXE, &path);
path = path.Append(name);
return path;
}
bool InstallerPathProvider::GetInstaller(const std::string& pattern,
FilePath* path) {
FilePath installer;
// Search filer for installer binary.
FilePath root(mini_installer_constants::kChromeInstallersLocation);
std::vector<FilePath> paths;
if (!FindMatchingFiles(root, current_build_,
file_util::FileEnumerator::DIRECTORIES, &paths)) {
return false;
}
std::vector<FilePath>::const_iterator dir;
for (dir = paths.begin(); dir != paths.end(); ++dir) {
FilePath windir = dir->Append(
mini_installer_constants::kWinFolder);
if (FindNewestMatchingFile(windir, pattern,
file_util::FileEnumerator::FILES, &installer)) {
break;
}
}
if (installer.empty()) {
LOG(WARNING) << "Failed to find installer with pattern: " << pattern;
return false;
}
*path = installer;
return true;
}
std::string InstallerPathProvider::GetCurrentBuild() {
return current_build_;
}
std::string InstallerPathProvider::GetPreviousBuild() {
return previous_build_;
}
} // namespace