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