Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / installer / util / installer_state_unittest.cc
blobb40817071d6fd6cf228f965bda2ef6e43071a495
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/installer/util/installer_state.h"
7 #include <windows.h>
9 #include <fstream>
11 #include "base/base_paths.h"
12 #include "base/command_line.h"
13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/macros.h"
18 #include "base/path_service.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/scoped_path_override.h"
22 #include "base/test/test_reg_util_win.h"
23 #include "base/version.h"
24 #include "base/win/registry.h"
25 #include "base/win/scoped_handle.h"
26 #include "chrome/common/chrome_constants.h"
27 #include "chrome/installer/test/alternate_version_generator.h"
28 #include "chrome/installer/util/fake_installation_state.h"
29 #include "chrome/installer/util/fake_product_state.h"
30 #include "chrome/installer/util/google_update_constants.h"
31 #include "chrome/installer/util/helper.h"
32 #include "chrome/installer/util/installation_state.h"
33 #include "chrome/installer/util/installer_util_strings.h"
34 #include "chrome/installer/util/master_preferences.h"
35 #include "chrome/installer/util/util_constants.h"
36 #include "chrome/installer/util/work_item.h"
37 #include "testing/gtest/include/gtest/gtest.h"
39 using base::win::RegKey;
40 using installer::InstallationState;
41 using installer::InstallerState;
42 using installer::MasterPreferences;
43 using registry_util::RegistryOverrideManager;
45 class InstallerStateTest : public testing::Test {
46 protected:
47 InstallerStateTest() {}
49 void SetUp() override {
50 ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
53 base::ScopedTempDir test_dir_;
55 private:
56 DISALLOW_COPY_AND_ASSIGN(InstallerStateTest);
59 // An installer state on which we can access otherwise protected members.
60 class MockInstallerState : public InstallerState {
61 public:
62 MockInstallerState() : InstallerState() { }
63 void set_target_path(const base::FilePath& target_path) {
64 target_path_ = target_path;
66 static bool IsFileInUse(const base::FilePath& file) {
67 return InstallerState::IsFileInUse(file);
69 const Version& critical_update_version() const {
70 return critical_update_version_;
72 void GetExistingExeVersions(std::set<std::string>* existing_version_strings) {
73 return InstallerState::GetExistingExeVersions(existing_version_strings);
77 // Simple function to dump some text into a new file.
78 void CreateTextFile(const std::wstring& filename,
79 const std::wstring& contents) {
80 std::ofstream file;
81 file.open(filename.c_str());
82 ASSERT_TRUE(file.is_open());
83 file << contents;
84 file.close();
87 void BuildSingleChromeState(const base::FilePath& target_dir,
88 MockInstallerState* installer_state) {
89 base::CommandLine cmd_line = base::CommandLine::FromString(L"setup.exe");
90 MasterPreferences prefs(cmd_line);
91 InstallationState machine_state;
92 machine_state.Initialize();
93 installer_state->Initialize(cmd_line, prefs, machine_state);
94 installer_state->set_target_path(target_dir);
95 EXPECT_TRUE(installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER)
96 != NULL);
99 wchar_t text_content_1[] = L"delete me";
100 wchar_t text_content_2[] = L"delete me as well";
102 // Delete version directories. Everything lower than the given version
103 // should be deleted.
104 TEST_F(InstallerStateTest, Delete) {
105 // TODO(grt): move common stuff into the test fixture.
106 // Create a Chrome dir
107 base::FilePath chrome_dir(test_dir_.path());
108 chrome_dir = chrome_dir.AppendASCII("chrome");
109 base::CreateDirectory(chrome_dir);
110 ASSERT_TRUE(base::PathExists(chrome_dir));
112 base::FilePath chrome_dir_1(chrome_dir);
113 chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
114 base::CreateDirectory(chrome_dir_1);
115 ASSERT_TRUE(base::PathExists(chrome_dir_1));
117 base::FilePath chrome_dir_2(chrome_dir);
118 chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
119 base::CreateDirectory(chrome_dir_2);
120 ASSERT_TRUE(base::PathExists(chrome_dir_2));
122 base::FilePath chrome_dir_3(chrome_dir);
123 chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
124 base::CreateDirectory(chrome_dir_3);
125 ASSERT_TRUE(base::PathExists(chrome_dir_3));
127 base::FilePath chrome_dir_4(chrome_dir);
128 chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
129 base::CreateDirectory(chrome_dir_4);
130 ASSERT_TRUE(base::PathExists(chrome_dir_4));
132 base::FilePath chrome_dll_1(chrome_dir_1);
133 chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
134 CreateTextFile(chrome_dll_1.value(), text_content_1);
135 ASSERT_TRUE(base::PathExists(chrome_dll_1));
137 base::FilePath chrome_dll_2(chrome_dir_2);
138 chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
139 CreateTextFile(chrome_dll_2.value(), text_content_1);
140 ASSERT_TRUE(base::PathExists(chrome_dll_2));
142 base::FilePath chrome_dll_3(chrome_dir_3);
143 chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
144 CreateTextFile(chrome_dll_3.value(), text_content_1);
145 ASSERT_TRUE(base::PathExists(chrome_dll_3));
147 base::FilePath chrome_dll_4(chrome_dir_4);
148 chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
149 CreateTextFile(chrome_dll_4.value(), text_content_1);
150 ASSERT_TRUE(base::PathExists(chrome_dll_4));
152 MockInstallerState installer_state;
153 BuildSingleChromeState(chrome_dir, &installer_state);
154 Version latest_version("1.0.4.0");
156 base::ScopedTempDir temp_dir;
157 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
158 installer_state.RemoveOldVersionDirectories(latest_version, NULL,
159 temp_dir.path());
162 // old versions should be gone
163 EXPECT_FALSE(base::PathExists(chrome_dir_1));
164 EXPECT_FALSE(base::PathExists(chrome_dir_2));
165 EXPECT_FALSE(base::PathExists(chrome_dir_3));
166 // the latest version should stay
167 EXPECT_TRUE(base::PathExists(chrome_dll_4));
170 // Delete older version directories, keeping the one in used intact.
171 TEST_F(InstallerStateTest, DeleteInUsed) {
172 // Create a Chrome dir
173 base::FilePath chrome_dir(test_dir_.path());
174 chrome_dir = chrome_dir.AppendASCII("chrome");
175 base::CreateDirectory(chrome_dir);
176 ASSERT_TRUE(base::PathExists(chrome_dir));
178 base::FilePath chrome_dir_1(chrome_dir);
179 chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
180 base::CreateDirectory(chrome_dir_1);
181 ASSERT_TRUE(base::PathExists(chrome_dir_1));
183 base::FilePath chrome_dir_2(chrome_dir);
184 chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
185 base::CreateDirectory(chrome_dir_2);
186 ASSERT_TRUE(base::PathExists(chrome_dir_2));
188 base::FilePath chrome_dir_3(chrome_dir);
189 chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
190 base::CreateDirectory(chrome_dir_3);
191 ASSERT_TRUE(base::PathExists(chrome_dir_3));
193 base::FilePath chrome_dir_4(chrome_dir);
194 chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
195 base::CreateDirectory(chrome_dir_4);
196 ASSERT_TRUE(base::PathExists(chrome_dir_4));
198 base::FilePath chrome_dll_1(chrome_dir_1);
199 chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
200 CreateTextFile(chrome_dll_1.value(), text_content_1);
201 ASSERT_TRUE(base::PathExists(chrome_dll_1));
203 base::FilePath chrome_dll_2(chrome_dir_2);
204 chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
205 CreateTextFile(chrome_dll_2.value(), text_content_1);
206 ASSERT_TRUE(base::PathExists(chrome_dll_2));
208 // Open the file to make it in use.
209 std::ofstream file;
210 file.open(chrome_dll_2.value().c_str());
212 base::FilePath chrome_othera_2(chrome_dir_2);
213 chrome_othera_2 = chrome_othera_2.AppendASCII("othera.dll");
214 CreateTextFile(chrome_othera_2.value(), text_content_2);
215 ASSERT_TRUE(base::PathExists(chrome_othera_2));
217 base::FilePath chrome_otherb_2(chrome_dir_2);
218 chrome_otherb_2 = chrome_otherb_2.AppendASCII("otherb.dll");
219 CreateTextFile(chrome_otherb_2.value(), text_content_2);
220 ASSERT_TRUE(base::PathExists(chrome_otherb_2));
222 base::FilePath chrome_dll_3(chrome_dir_3);
223 chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
224 CreateTextFile(chrome_dll_3.value(), text_content_1);
225 ASSERT_TRUE(base::PathExists(chrome_dll_3));
227 base::FilePath chrome_dll_4(chrome_dir_4);
228 chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
229 CreateTextFile(chrome_dll_4.value(), text_content_1);
230 ASSERT_TRUE(base::PathExists(chrome_dll_4));
232 MockInstallerState installer_state;
233 BuildSingleChromeState(chrome_dir, &installer_state);
234 Version latest_version("1.0.4.0");
235 Version existing_version("1.0.1.0");
237 base::ScopedTempDir temp_dir;
238 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
239 installer_state.RemoveOldVersionDirectories(latest_version,
240 &existing_version,
241 temp_dir.path());
244 // the version defined as the existing version should stay
245 EXPECT_TRUE(base::PathExists(chrome_dir_1));
246 // old versions not in used should be gone
247 EXPECT_FALSE(base::PathExists(chrome_dir_3));
248 // every thing under in used version should stay
249 EXPECT_TRUE(base::PathExists(chrome_dir_2));
250 EXPECT_TRUE(base::PathExists(chrome_dll_2));
251 EXPECT_TRUE(base::PathExists(chrome_othera_2));
252 EXPECT_TRUE(base::PathExists(chrome_otherb_2));
253 // the latest version should stay
254 EXPECT_TRUE(base::PathExists(chrome_dll_4));
257 // Tests a few basic things of the Package class. Makes sure that the path
258 // operations are correct
259 TEST_F(InstallerStateTest, Basic) {
260 const bool multi_install = false;
261 const bool system_level = true;
262 base::CommandLine cmd_line = base::CommandLine::FromString(
263 std::wstring(L"setup.exe") +
264 (multi_install ? L" --multi-install --chrome" : L"") +
265 (system_level ? L" --system-level" : L""));
266 MasterPreferences prefs(cmd_line);
267 InstallationState machine_state;
268 machine_state.Initialize();
269 MockInstallerState installer_state;
270 installer_state.Initialize(cmd_line, prefs, machine_state);
271 installer_state.set_target_path(test_dir_.path());
272 EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
273 EXPECT_EQ(1U, installer_state.products().size());
275 const char kOldVersion[] = "1.2.3.4";
276 const char kNewVersion[] = "2.3.4.5";
278 Version new_version(kNewVersion);
279 Version old_version(kOldVersion);
280 ASSERT_TRUE(new_version.IsValid());
281 ASSERT_TRUE(old_version.IsValid());
283 base::FilePath installer_dir(
284 installer_state.GetInstallerDirectory(new_version));
285 EXPECT_FALSE(installer_dir.empty());
287 base::FilePath new_version_dir(installer_state.target_path().Append(
288 base::UTF8ToWide(new_version.GetString())));
289 base::FilePath old_version_dir(installer_state.target_path().Append(
290 base::UTF8ToWide(old_version.GetString())));
292 EXPECT_FALSE(base::PathExists(new_version_dir));
293 EXPECT_FALSE(base::PathExists(old_version_dir));
295 EXPECT_FALSE(base::PathExists(installer_dir));
296 base::CreateDirectory(installer_dir);
297 EXPECT_TRUE(base::PathExists(new_version_dir));
299 base::CreateDirectory(old_version_dir);
300 EXPECT_TRUE(base::PathExists(old_version_dir));
302 // Create a fake chrome.dll key file in the old version directory. This
303 // should prevent the old version directory from getting deleted.
304 base::FilePath old_chrome_dll(old_version_dir.Append(installer::kChromeDll));
305 EXPECT_FALSE(base::PathExists(old_chrome_dll));
307 // Hold on to the file exclusively to prevent the directory from
308 // being deleted.
309 base::win::ScopedHandle file(
310 ::CreateFile(old_chrome_dll.value().c_str(), GENERIC_READ,
311 0, NULL, OPEN_ALWAYS, 0, NULL));
312 EXPECT_TRUE(file.IsValid());
313 EXPECT_TRUE(base::PathExists(old_chrome_dll));
315 base::ScopedTempDir temp_dir;
316 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
318 // Don't explicitly tell the directory cleanup logic not to delete the
319 // old version, rely on the key files to keep it around.
320 installer_state.RemoveOldVersionDirectories(new_version,
321 NULL,
322 temp_dir.path());
324 // The old directory should still exist.
325 EXPECT_TRUE(base::PathExists(old_version_dir));
326 EXPECT_TRUE(base::PathExists(new_version_dir));
328 // Now close the file handle to make it possible to delete our key file.
329 file.Close();
331 installer_state.RemoveOldVersionDirectories(new_version,
332 NULL,
333 temp_dir.path());
334 // The new directory should still exist.
335 EXPECT_TRUE(base::PathExists(new_version_dir));
337 // Now, the old directory and key file should be gone.
338 EXPECT_FALSE(base::PathExists(old_chrome_dll));
339 EXPECT_FALSE(base::PathExists(old_version_dir));
342 TEST_F(InstallerStateTest, WithProduct) {
343 const bool multi_install = false;
344 const bool system_level = true;
345 base::CommandLine cmd_line = base::CommandLine::FromString(
346 std::wstring(L"setup.exe") +
347 (multi_install ? L" --multi-install --chrome" : L"") +
348 (system_level ? L" --system-level" : L""));
349 MasterPreferences prefs(cmd_line);
350 InstallationState machine_state;
351 machine_state.Initialize();
352 MockInstallerState installer_state;
353 installer_state.Initialize(cmd_line, prefs, machine_state);
354 installer_state.set_target_path(test_dir_.path());
355 EXPECT_EQ(1U, installer_state.products().size());
356 EXPECT_EQ(system_level, installer_state.system_install());
358 const char kCurrentVersion[] = "1.2.3.4";
359 Version current_version(kCurrentVersion);
361 HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
362 EXPECT_EQ(root, installer_state.root_key());
365 RegistryOverrideManager override_manager;
366 override_manager.OverrideRegistry(root);
367 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
368 BrowserDistribution::CHROME_BROWSER);
369 RegKey chrome_key(root, dist->GetVersionKey().c_str(), KEY_ALL_ACCESS);
370 EXPECT_TRUE(chrome_key.Valid());
371 if (chrome_key.Valid()) {
372 chrome_key.WriteValue(google_update::kRegVersionField,
373 base::UTF8ToWide(
374 current_version.GetString()).c_str());
375 machine_state.Initialize();
376 // TODO(tommi): Also test for when there exists a new_chrome.exe.
377 Version found_version(*installer_state.GetCurrentVersion(machine_state));
378 EXPECT_TRUE(found_version.IsValid());
379 if (found_version.IsValid())
380 EXPECT_TRUE(current_version.Equals(found_version));
385 TEST_F(InstallerStateTest, InstallerResult) {
386 const bool system_level = true;
387 HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
389 RegKey key;
390 std::wstring launch_cmd = L"hey diddle diddle";
391 std::wstring value;
392 DWORD dw_value;
394 // check results for a fresh install of single Chrome
396 RegistryOverrideManager override_manager;
397 override_manager.OverrideRegistry(root);
398 base::CommandLine cmd_line =
399 base::CommandLine::FromString(L"setup.exe --system-level");
400 const MasterPreferences prefs(cmd_line);
401 InstallationState machine_state;
402 machine_state.Initialize();
403 InstallerState state;
404 state.Initialize(cmd_line, prefs, machine_state);
405 state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS,
406 IDS_INSTALL_OS_ERROR_BASE, &launch_cmd);
407 BrowserDistribution* distribution =
408 BrowserDistribution::GetSpecificDistribution(
409 BrowserDistribution::CHROME_BROWSER);
410 EXPECT_EQ(ERROR_SUCCESS,
411 key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
412 EXPECT_EQ(ERROR_SUCCESS,
413 key.ReadValueDW(installer::kInstallerResult, &dw_value));
414 EXPECT_EQ(static_cast<DWORD>(0), dw_value);
415 EXPECT_EQ(ERROR_SUCCESS,
416 key.ReadValueDW(installer::kInstallerError, &dw_value));
417 EXPECT_EQ(static_cast<DWORD>(installer::FIRST_INSTALL_SUCCESS), dw_value);
418 EXPECT_EQ(ERROR_SUCCESS,
419 key.ReadValue(installer::kInstallerResultUIString, &value));
420 EXPECT_FALSE(value.empty());
421 EXPECT_EQ(ERROR_SUCCESS,
422 key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
423 EXPECT_EQ(launch_cmd, value);
426 // check results for a fresh install of multi Chrome
428 RegistryOverrideManager override_manager;
429 override_manager.OverrideRegistry(root);
430 base::CommandLine cmd_line = base::CommandLine::FromString(
431 L"setup.exe --system-level --multi-install --chrome");
432 const MasterPreferences prefs(cmd_line);
433 InstallationState machine_state;
434 machine_state.Initialize();
435 InstallerState state;
436 state.Initialize(cmd_line, prefs, machine_state);
437 state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS, 0,
438 &launch_cmd);
439 BrowserDistribution* distribution =
440 BrowserDistribution::GetSpecificDistribution(
441 BrowserDistribution::CHROME_BROWSER);
442 BrowserDistribution* binaries =
443 BrowserDistribution::GetSpecificDistribution(
444 BrowserDistribution::CHROME_BINARIES);
445 EXPECT_EQ(ERROR_SUCCESS,
446 key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
447 EXPECT_EQ(ERROR_SUCCESS,
448 key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
449 EXPECT_EQ(launch_cmd, value);
450 EXPECT_EQ(ERROR_SUCCESS,
451 key.Open(root, binaries->GetStateKey().c_str(), KEY_READ));
452 EXPECT_EQ(ERROR_SUCCESS,
453 key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
454 EXPECT_EQ(launch_cmd, value);
455 key.Close();
459 // Test GetCurrentVersion when migrating single Chrome to multi
460 TEST_F(InstallerStateTest, GetCurrentVersionMigrateChrome) {
461 using installer::FakeInstallationState;
463 const bool system_install = false;
464 FakeInstallationState machine_state;
466 // Pretend that this version of single-install Chrome is already installed.
467 machine_state.AddChrome(system_install, false,
468 new Version(chrome::kChromeVersion));
470 // Now we're invoked to install multi Chrome.
471 base::CommandLine cmd_line(
472 base::CommandLine::FromString(L"setup.exe --multi-install --chrome"));
473 MasterPreferences prefs(cmd_line);
474 InstallerState installer_state;
475 installer_state.Initialize(cmd_line, prefs, machine_state);
477 // Is the Chrome version picked up?
478 scoped_ptr<Version> version(installer_state.GetCurrentVersion(machine_state));
479 EXPECT_TRUE(version.get() != NULL);
482 TEST_F(InstallerStateTest, IsFileInUse) {
483 base::ScopedTempDir temp_dir;
484 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
486 base::FilePath temp_file;
487 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
489 EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
492 // Open a handle to the file with the same access mode and sharing options
493 // as the loader.
494 base::win::ScopedHandle temp_handle(
495 CreateFile(temp_file.value().c_str(),
496 SYNCHRONIZE | FILE_EXECUTE,
497 FILE_SHARE_DELETE | FILE_SHARE_READ,
498 NULL, OPEN_EXISTING, 0, 0));
499 ASSERT_TRUE(temp_handle.IsValid());
501 // The file should now be in use.
502 EXPECT_TRUE(MockInstallerState::IsFileInUse(temp_file));
505 // And once the handle is gone, it should no longer be in use.
506 EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
509 TEST_F(InstallerStateTest, RemoveOldVersionDirs) {
510 MockInstallerState installer_state;
511 installer_state.set_target_path(test_dir_.path());
512 EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
514 const char kOldVersion[] = "2.0.0.0";
515 const char kNewVersion[] = "3.0.0.0";
516 const char kOldChromeExeVersion[] = "2.1.0.0";
517 const char kChromeExeVersion[] = "2.1.1.1";
518 const char kNewChromeExeVersion[] = "3.0.0.0";
520 Version new_version(kNewVersion);
521 Version old_version(kOldVersion);
522 Version old_chrome_exe_version(kOldChromeExeVersion);
523 Version chrome_exe_version(kChromeExeVersion);
524 Version new_chrome_exe_version(kNewChromeExeVersion);
526 ASSERT_TRUE(new_version.IsValid());
527 ASSERT_TRUE(old_version.IsValid());
528 ASSERT_TRUE(old_chrome_exe_version.IsValid());
529 ASSERT_TRUE(chrome_exe_version.IsValid());
530 ASSERT_TRUE(new_chrome_exe_version.IsValid());
532 // Set up a bunch of version dir paths.
533 base::FilePath version_dirs[] = {
534 installer_state.target_path().Append(L"1.2.3.4"),
535 installer_state.target_path().Append(L"1.2.3.5"),
536 installer_state.target_path().Append(L"1.2.3.6"),
537 installer_state.target_path().AppendASCII(kOldVersion),
538 installer_state.target_path().AppendASCII(kOldChromeExeVersion),
539 installer_state.target_path().Append(L"2.1.1.0"),
540 installer_state.target_path().AppendASCII(kChromeExeVersion),
541 installer_state.target_path().AppendASCII(kNewVersion),
542 installer_state.target_path().Append(L"3.9.1.1"),
545 // Create the version directories.
546 for (int i = 0; i < arraysize(version_dirs); i++) {
547 base::CreateDirectory(version_dirs[i]);
548 EXPECT_TRUE(base::PathExists(version_dirs[i]));
551 // Create exes with the appropriate version resource.
552 // Use the current test exe as a baseline.
553 base::FilePath exe_path;
554 ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe_path));
556 struct target_info {
557 base::FilePath target_file;
558 const Version& target_version;
559 } targets[] = {
560 { installer_state.target_path().Append(installer::kChromeOldExe),
561 old_chrome_exe_version },
562 { installer_state.target_path().Append(installer::kChromeExe),
563 chrome_exe_version },
564 { installer_state.target_path().Append(installer::kChromeNewExe),
565 new_chrome_exe_version },
567 for (int i = 0; i < arraysize(targets); ++i) {
568 ASSERT_TRUE(upgrade_test::GenerateSpecificPEFileVersion(
569 exe_path, targets[i].target_file, targets[i].target_version));
572 // Call GetExistingExeVersions, validate that picks up the
573 // exe resources.
574 std::set<std::string> expected_exe_versions;
575 expected_exe_versions.insert(kOldChromeExeVersion);
576 expected_exe_versions.insert(kChromeExeVersion);
577 expected_exe_versions.insert(kNewChromeExeVersion);
579 std::set<std::string> actual_exe_versions;
580 installer_state.GetExistingExeVersions(&actual_exe_versions);
581 EXPECT_EQ(expected_exe_versions, actual_exe_versions);
583 // Call RemoveOldVersionDirectories
584 installer_state.RemoveOldVersionDirectories(new_version,
585 &old_version,
586 installer_state.target_path());
588 // What we expect to have left.
589 std::set<std::string> expected_remaining_dirs;
590 expected_remaining_dirs.insert(kOldVersion);
591 expected_remaining_dirs.insert(kNewVersion);
592 expected_remaining_dirs.insert(kOldChromeExeVersion);
593 expected_remaining_dirs.insert(kChromeExeVersion);
594 expected_remaining_dirs.insert(kNewChromeExeVersion);
596 // Enumerate dirs in target_path(), ensure only desired remain.
597 base::FileEnumerator version_enum(installer_state.target_path(), false,
598 base::FileEnumerator::DIRECTORIES);
599 for (base::FilePath next_version = version_enum.Next(); !next_version.empty();
600 next_version = version_enum.Next()) {
601 base::FilePath dir_name(next_version.BaseName());
602 Version version(base::UTF16ToASCII(dir_name.value()));
603 if (version.IsValid()) {
604 EXPECT_TRUE(expected_remaining_dirs.erase(version.GetString()))
605 << "Unexpected version dir found: " << version.GetString();
609 std::set<std::string>::const_iterator iter(
610 expected_remaining_dirs.begin());
611 for (; iter != expected_remaining_dirs.end(); ++iter)
612 ADD_FAILURE() << "Expected to find version dir for " << *iter;
615 TEST_F(InstallerStateTest, InitializeTwice) {
616 // Override these paths so that they can be found after the registry override
617 // manager is in place.
618 base::FilePath temp;
619 PathService::Get(base::DIR_PROGRAM_FILES, &temp);
620 base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES,
621 temp);
622 PathService::Get(base::DIR_PROGRAM_FILESX86, &temp);
623 base::ScopedPathOverride program_filesx86_override(base::DIR_PROGRAM_FILESX86,
624 temp);
625 PathService::Get(base::DIR_LOCAL_APP_DATA, &temp);
626 base::ScopedPathOverride local_app_data_override(base::DIR_LOCAL_APP_DATA,
627 temp);
628 registry_util::RegistryOverrideManager override_manager;
629 override_manager.OverrideRegistry(HKEY_CURRENT_USER);
630 override_manager.OverrideRegistry(HKEY_LOCAL_MACHINE);
632 InstallationState machine_state;
633 machine_state.Initialize();
635 InstallerState installer_state;
637 // Initialize the instance to install multi Chrome.
639 base::CommandLine cmd_line(
640 base::CommandLine::FromString(L"setup.exe --multi-install --chrome"));
641 MasterPreferences prefs(cmd_line);
642 installer_state.Initialize(cmd_line, prefs, machine_state);
644 // Confirm the expected state.
645 EXPECT_EQ(InstallerState::USER_LEVEL, installer_state.level());
646 EXPECT_EQ(InstallerState::MULTI_PACKAGE, installer_state.package_type());
647 EXPECT_EQ(InstallerState::MULTI_INSTALL, installer_state.operation());
648 EXPECT_TRUE(wcsstr(installer_state.target_path().value().c_str(),
649 BrowserDistribution::GetSpecificDistribution(
650 BrowserDistribution::CHROME_BINARIES)->
651 GetInstallSubDir().c_str()));
652 EXPECT_FALSE(installer_state.verbose_logging());
653 EXPECT_EQ(installer_state.state_key(),
654 BrowserDistribution::GetSpecificDistribution(
655 BrowserDistribution::CHROME_BROWSER)->GetStateKey());
656 EXPECT_EQ(installer_state.state_type(), BrowserDistribution::CHROME_BROWSER);
657 EXPECT_TRUE(installer_state.multi_package_binaries_distribution());
658 EXPECT_TRUE(installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER));
660 // Now initialize it to install system-level single Chrome.
662 base::CommandLine cmd_line(base::CommandLine::FromString(
663 L"setup.exe --system-level --verbose-logging"));
664 MasterPreferences prefs(cmd_line);
665 installer_state.Initialize(cmd_line, prefs, machine_state);
668 // Confirm that the old state is gone.
669 EXPECT_EQ(InstallerState::SYSTEM_LEVEL, installer_state.level());
670 EXPECT_EQ(InstallerState::SINGLE_PACKAGE, installer_state.package_type());
671 EXPECT_EQ(InstallerState::SINGLE_INSTALL_OR_UPDATE,
672 installer_state.operation());
673 EXPECT_TRUE(wcsstr(installer_state.target_path().value().c_str(),
674 BrowserDistribution::GetSpecificDistribution(
675 BrowserDistribution::CHROME_BROWSER)->
676 GetInstallSubDir().c_str()));
677 EXPECT_TRUE(installer_state.verbose_logging());
678 EXPECT_EQ(installer_state.state_key(),
679 BrowserDistribution::GetSpecificDistribution(
680 BrowserDistribution::CHROME_BROWSER)->GetStateKey());
681 EXPECT_EQ(installer_state.state_type(), BrowserDistribution::CHROME_BROWSER);
682 EXPECT_TRUE(installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER));
685 // A fixture for testing InstallerState::DetermineCriticalVersion. Individual
686 // tests must invoke Initialize() with a critical version.
687 class InstallerStateCriticalVersionTest : public ::testing::Test {
688 protected:
689 InstallerStateCriticalVersionTest()
690 : cmd_line_(base::CommandLine::NO_PROGRAM) {}
692 // Creates a set of versions for use by all test runs.
693 static void SetUpTestCase() {
694 low_version_ = new Version("15.0.874.106");
695 opv_version_ = new Version("15.0.874.255");
696 middle_version_ = new Version("16.0.912.32");
697 pv_version_ = new Version("16.0.912.255");
698 high_version_ = new Version("17.0.932.0");
701 // Cleans up versions used by all test runs.
702 static void TearDownTestCase() {
703 delete low_version_;
704 delete opv_version_;
705 delete middle_version_;
706 delete pv_version_;
707 delete high_version_;
710 // Initializes the InstallerState to use for a test run. The returned
711 // instance's critical update version is set to |version|. |version| may be
712 // NULL, in which case the critical update version is unset.
713 MockInstallerState& Initialize(const Version* version) {
714 cmd_line_ = version == NULL ? base::CommandLine::FromString(L"setup.exe")
715 : base::CommandLine::FromString(
716 L"setup.exe --critical-update-version=" +
717 base::ASCIIToUTF16(version->GetString()));
718 prefs_.reset(new MasterPreferences(cmd_line_));
719 machine_state_.Initialize();
720 installer_state_.Initialize(cmd_line_, *prefs_, machine_state_);
721 return installer_state_;
724 static Version* low_version_;
725 static Version* opv_version_;
726 static Version* middle_version_;
727 static Version* pv_version_;
728 static Version* high_version_;
730 base::CommandLine cmd_line_;
731 scoped_ptr<MasterPreferences> prefs_;
732 InstallationState machine_state_;
733 MockInstallerState installer_state_;
736 Version* InstallerStateCriticalVersionTest::low_version_ = NULL;
737 Version* InstallerStateCriticalVersionTest::opv_version_ = NULL;
738 Version* InstallerStateCriticalVersionTest::middle_version_ = NULL;
739 Version* InstallerStateCriticalVersionTest::pv_version_ = NULL;
740 Version* InstallerStateCriticalVersionTest::high_version_ = NULL;
742 // Test the case where the critical version is less than the currently-running
743 // Chrome. The critical version is ignored since it doesn't apply.
744 TEST_F(InstallerStateCriticalVersionTest, CriticalBeforeOpv) {
745 MockInstallerState& installer_state(Initialize(low_version_));
747 EXPECT_TRUE(installer_state.critical_update_version().Equals(*low_version_));
748 // Unable to determine the installed version, so assume critical update.
749 EXPECT_TRUE(
750 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
751 // Installed version is past the critical update.
752 EXPECT_FALSE(
753 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
754 .IsValid());
755 // Installed version is past the critical update.
756 EXPECT_FALSE(
757 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
758 .IsValid());
761 // Test the case where the critical version is equal to the currently-running
762 // Chrome. The critical version is ignored since it doesn't apply.
763 TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsOpv) {
764 MockInstallerState& installer_state(Initialize(opv_version_));
766 EXPECT_TRUE(installer_state.critical_update_version().Equals(*opv_version_));
767 // Unable to determine the installed version, so assume critical update.
768 EXPECT_TRUE(
769 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
770 // Installed version equals the critical update.
771 EXPECT_FALSE(
772 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
773 .IsValid());
774 // Installed version equals the critical update.
775 EXPECT_FALSE(
776 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
777 .IsValid());
780 // Test the case where the critical version is between the currently-running
781 // Chrome and the to-be-installed Chrome.
782 TEST_F(InstallerStateCriticalVersionTest, CriticalBetweenOpvAndPv) {
783 MockInstallerState& installer_state(Initialize(middle_version_));
785 EXPECT_TRUE(installer_state.critical_update_version().Equals(
786 *middle_version_));
787 // Unable to determine the installed version, so assume critical update.
788 EXPECT_TRUE(
789 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
790 // Installed version before the critical update.
791 EXPECT_TRUE(
792 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
793 .IsValid());
794 // Installed version is past the critical update.
795 EXPECT_FALSE(
796 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
797 .IsValid());
800 // Test the case where the critical version is the same as the to-be-installed
801 // Chrome.
802 TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsPv) {
803 MockInstallerState& installer_state(Initialize(pv_version_));
805 EXPECT_TRUE(installer_state.critical_update_version().Equals(
806 *pv_version_));
807 // Unable to determine the installed version, so assume critical update.
808 EXPECT_TRUE(
809 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
810 // Installed version before the critical update.
811 EXPECT_TRUE(
812 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
813 .IsValid());
814 // Installed version equals the critical update.
815 EXPECT_FALSE(
816 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
817 .IsValid());
820 // Test the case where the critical version is greater than the to-be-installed
821 // Chrome.
822 TEST_F(InstallerStateCriticalVersionTest, CriticalAfterPv) {
823 MockInstallerState& installer_state(Initialize(high_version_));
825 EXPECT_TRUE(installer_state.critical_update_version().Equals(
826 *high_version_));
827 // Critical update newer than the new version.
828 EXPECT_FALSE(
829 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
830 EXPECT_FALSE(
831 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
832 .IsValid());
833 EXPECT_FALSE(
834 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
835 .IsValid());