Allow overlapping sync and async startup requests
[chromium-blink-merge.git] / chrome / test / mini_installer_test / installer_path_provider.cc
blob6602cabce13750b619e625d9dfe9f49c3291c3c0
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/mini_installer_test/installer_path_provider.h"
7 #include <algorithm>
9 #include "base/command_line.h"
10 #include "base/file_util.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/path_service.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "chrome/test/mini_installer_test/installer_test_util.h"
16 #include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace {
21 struct FilePathInfo {
22 base::FileEnumerator::FileInfo info;
23 base::FilePath path;
26 bool CompareDate(const FilePathInfo& a, const FilePathInfo& b) {
27 return a.info.GetLastModifiedTime() > b.info.GetLastModifiedTime();
30 // Get list of file |type| matching |pattern| in |root|.
31 // The list is sorted in last modified date order.
32 // Return true if files/directories are found.
33 bool FindMatchingFiles(const base::FilePath& root,
34 const std::string& pattern,
35 base::FileEnumerator::FileType type,
36 std::vector<base::FilePath>* paths) {
37 base::FileEnumerator files(root, false, type,
38 base::FilePath().AppendASCII(pattern).value());
39 std::vector<FilePathInfo> matches;
40 for (base::FilePath current = files.Next(); !current.empty();
41 current = files.Next()) {
42 FilePathInfo entry;
43 entry.info = files.GetInfo();
44 entry.path = current;
45 matches.push_back(entry);
48 if (matches.empty())
49 return false;
51 std::sort(matches.begin(), matches.end(), CompareDate);
52 std::vector<FilePathInfo>::iterator current;
53 for (current = matches.begin(); current != matches.end(); ++current) {
54 paths->push_back(current->path);
56 return true;
59 bool FindNewestMatchingFile(const base::FilePath& root,
60 const std::string& pattern,
61 base::FileEnumerator::FileType type,
62 base::FilePath* path) {
63 std::vector<base::FilePath> paths;
64 if (FindMatchingFiles(root, pattern, type, &paths)) {
65 *path = paths[0];
66 return true;
68 return false;
71 } // namespace
73 namespace installer_test {
75 InstallerPathProvider::InstallerPathProvider() {
76 base::FilePath full_installer, previous_installer;
77 if (!GetFullInstaller(&full_installer) ||
78 !GetPreviousInstaller(&previous_installer))
79 return;
80 current_build_ =
81 full_installer.DirName().DirName().BaseName().MaybeAsASCII();
82 previous_build_ =
83 previous_installer.DirName().DirName().BaseName().MaybeAsASCII();
86 InstallerPathProvider::InstallerPathProvider(
87 const std::string& build_under_test) : current_build_(build_under_test) {
88 base::FilePath full_installer, previous_installer;
89 if (!GetFullInstaller(&full_installer) ||
90 !GetPreviousInstaller(&previous_installer))
91 return;
92 previous_build_ =
93 previous_installer.DirName().DirName().BaseName().MaybeAsASCII();
96 InstallerPathProvider::~InstallerPathProvider() {}
98 bool InstallerPathProvider::GetFullInstaller(base::FilePath* path) {
99 std::string full_installer_pattern("*_chrome_installer*");
100 return GetInstaller(full_installer_pattern, path);
103 bool InstallerPathProvider::GetDiffInstaller(base::FilePath* path) {
104 std::string diff_installer_pattern("*_from_*");
105 return GetInstaller(diff_installer_pattern, path);
108 bool InstallerPathProvider::GetMiniInstaller(base::FilePath* path) {
109 // Use local copy of installer, else fall back to filer.
110 base::FilePath mini_installer = PathFromExeDir(
111 mini_installer_constants::kChromeMiniInstallerExecutable);
112 if (base::PathExists(mini_installer)) {
113 *path = mini_installer;
114 return true;
116 std::string mini_installer_pattern("mini_installer.exe");
117 return GetInstaller(mini_installer_pattern, path);
120 bool InstallerPathProvider::GetPreviousInstaller(base::FilePath* path) {
121 std::string diff_installer_pattern("*_from_*");
122 std::string full_installer_pattern("*_chrome_installer*");
123 base::FilePath diff_installer;
124 if (!GetInstaller(diff_installer_pattern, &diff_installer))
125 return false;
127 base::FilePath previous_installer;
128 std::vector<std::string> tokenized_name;
129 Tokenize(diff_installer.BaseName().MaybeAsASCII(),
130 "_", &tokenized_name);
131 std::string build_pattern = base::StringPrintf(
132 "*%s", tokenized_name[2].c_str());
133 std::vector<base::FilePath> previous_build;
134 if (FindMatchingFiles(diff_installer.DirName().DirName().DirName(),
135 build_pattern, base::FileEnumerator::DIRECTORIES,
136 &previous_build)) {
137 base::FilePath windir = previous_build.at(0).Append(
138 mini_installer_constants::kWinFolder);
139 FindNewestMatchingFile(windir, full_installer_pattern,
140 base::FileEnumerator::FILES, &previous_installer);
143 if (previous_installer.empty())
144 return false;
145 *path = previous_installer;
146 return true;
149 bool InstallerPathProvider::GetStandaloneInstaller(base::FilePath* path) {
150 // Get standalone installer.
151 base::FilePath standalone_installer(
152 mini_installer_constants::kChromeStandAloneInstallerLocation);
153 // Get the file name.
154 std::vector<std::string> tokenized_build_number;
155 if (current_build_.empty())
156 return false;
157 Tokenize(current_build_, ".", &tokenized_build_number);
158 std::string standalone_installer_filename = base::StringPrintf(
159 "%s%s_%s.exe",
160 base::FilePath(mini_installer_constants::kUntaggedInstallerPattern)
161 .MaybeAsASCII().c_str(),
162 tokenized_build_number[2].c_str(),
163 tokenized_build_number[3].c_str());
164 standalone_installer = standalone_installer.AppendASCII(current_build_)
165 .Append(mini_installer_constants::kWinFolder)
166 .AppendASCII(standalone_installer_filename);
167 *path = standalone_installer;
168 return base::PathExists(standalone_installer);
171 bool InstallerPathProvider::GetSignedStandaloneInstaller(base::FilePath* path) {
172 base::FilePath standalone_installer;
173 if (!GetStandaloneInstaller(&standalone_installer))
174 return false;
175 base::FilePath tagged_installer = PathFromExeDir(
176 mini_installer_constants::kStandaloneInstaller);
177 CommandLine sign_command = CommandLine::FromString(
178 base::StringPrintf(L"%ls %ls %ls %ls",
179 mini_installer_constants::kChromeApplyTagExe,
180 standalone_installer.value().c_str(),
181 tagged_installer.value().c_str(),
182 mini_installer_constants::kChromeApplyTagParameters));
184 if (!installer_test::RunAndWaitForCommandToFinish(sign_command))
185 return false;
187 *path = PathFromExeDir(mini_installer_constants::kStandaloneInstaller);
188 return true;
191 base::FilePath InstallerPathProvider::PathFromExeDir(
192 const base::FilePath::StringType& name) {
193 base::FilePath path;
194 PathService::Get(base::DIR_EXE, &path);
195 path = path.Append(name);
196 return path;
199 bool InstallerPathProvider::GetInstaller(const std::string& pattern,
200 base::FilePath* path) {
201 base::FilePath installer;
202 // Search filer for installer binary.
203 base::FilePath root(mini_installer_constants::kChromeInstallersLocation);
204 std::vector<base::FilePath> paths;
205 if (!FindMatchingFiles(root, current_build_,
206 base::FileEnumerator::DIRECTORIES, &paths)) {
207 return false;
210 std::vector<base::FilePath>::const_iterator dir;
211 for (dir = paths.begin(); dir != paths.end(); ++dir) {
212 base::FilePath windir = dir->Append(
213 mini_installer_constants::kWinFolder);
214 if (FindNewestMatchingFile(windir, pattern, base::FileEnumerator::FILES,
215 &installer)) {
216 break;
220 if (installer.empty()) {
221 LOG(WARNING) << "Failed to find installer with pattern: " << pattern;
222 return false;
225 *path = installer;
226 return true;
229 std::string InstallerPathProvider::GetCurrentBuild() {
230 return current_build_;
233 std::string InstallerPathProvider::GetPreviousBuild() {
234 return previous_build_;
237 } // namespace