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"
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"
22 base::FileEnumerator::FileInfo info
;
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()) {
43 entry
.info
= files
.GetInfo();
45 matches
.push_back(entry
);
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
);
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
)) {
73 namespace installer_test
{
75 InstallerPathProvider::InstallerPathProvider() {
76 base::FilePath full_installer
, previous_installer
;
77 if (!GetFullInstaller(&full_installer
) ||
78 !GetPreviousInstaller(&previous_installer
))
81 full_installer
.DirName().DirName().BaseName().MaybeAsASCII();
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
))
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
;
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
))
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
,
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())
145 *path
= previous_installer
;
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())
157 Tokenize(current_build_
, ".", &tokenized_build_number
);
158 std::string standalone_installer_filename
= base::StringPrintf(
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
))
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
))
187 *path
= PathFromExeDir(mini_installer_constants::kStandaloneInstaller
);
191 base::FilePath
InstallerPathProvider::PathFromExeDir(
192 const base::FilePath::StringType
& name
) {
194 PathService::Get(base::DIR_EXE
, &path
);
195 path
= path
.Append(name
);
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
)) {
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
,
220 if (installer
.empty()) {
221 LOG(WARNING
) << "Failed to find installer with pattern: " << pattern
;
229 std::string
InstallerPathProvider::GetCurrentBuild() {
230 return current_build_
;
233 std::string
InstallerPathProvider::GetPreviousBuild() {
234 return previous_build_
;