[Android] Added UMA for search by image context menu.
[chromium-blink-merge.git] / chrome / installer / util / installer_state_unittest.cc
blob45497d56431ef92228beccf4f4cc66798c23b9e5
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/file_util.h"
12 #include "base/files/file_enumerator.h"
13 #include "base/files/file_path.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/test_reg_util_win.h"
19 #include "base/version.h"
20 #include "base/win/registry.h"
21 #include "base/win/scoped_handle.h"
22 #include "chrome/common/chrome_constants.h"
23 #include "chrome/installer/test/alternate_version_generator.h"
24 #include "chrome/installer/util/fake_installation_state.h"
25 #include "chrome/installer/util/fake_product_state.h"
26 #include "chrome/installer/util/google_update_constants.h"
27 #include "chrome/installer/util/helper.h"
28 #include "chrome/installer/util/installation_state.h"
29 #include "chrome/installer/util/installer_state.h"
30 #include "chrome/installer/util/master_preferences.h"
31 #include "chrome/installer/util/product_unittest.h"
32 #include "chrome/installer/util/util_constants.h"
33 #include "chrome/installer/util/work_item.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 #include "installer_util_strings.h" // NOLINT
38 using base::win::RegKey;
39 using installer::InstallationState;
40 using installer::InstallerState;
41 using installer::MasterPreferences;
42 using registry_util::RegistryOverrideManager;
44 class InstallerStateTest : public TestWithTempDirAndDeleteTempOverrideKeys {
45 protected:
48 // An installer state on which we can access otherwise protected members.
49 class MockInstallerState : public InstallerState {
50 public:
51 MockInstallerState() : InstallerState() { }
52 void set_target_path(const base::FilePath& target_path) {
53 target_path_ = target_path;
55 static bool IsFileInUse(const base::FilePath& file) {
56 return InstallerState::IsFileInUse(file);
58 const Version& critical_update_version() const {
59 return critical_update_version_;
61 void GetExistingExeVersions(std::set<std::string>* existing_version_strings) {
62 return InstallerState::GetExistingExeVersions(existing_version_strings);
66 // Simple function to dump some text into a new file.
67 void CreateTextFile(const std::wstring& filename,
68 const std::wstring& contents) {
69 std::ofstream file;
70 file.open(filename.c_str());
71 ASSERT_TRUE(file.is_open());
72 file << contents;
73 file.close();
76 void BuildSingleChromeState(const base::FilePath& target_dir,
77 MockInstallerState* installer_state) {
78 CommandLine cmd_line = CommandLine::FromString(L"setup.exe");
79 MasterPreferences prefs(cmd_line);
80 InstallationState machine_state;
81 machine_state.Initialize();
82 installer_state->Initialize(cmd_line, prefs, machine_state);
83 installer_state->set_target_path(target_dir);
84 EXPECT_TRUE(installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER)
85 != NULL);
86 EXPECT_TRUE(installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)
87 == NULL);
90 wchar_t text_content_1[] = L"delete me";
91 wchar_t text_content_2[] = L"delete me as well";
93 // Delete version directories. Everything lower than the given version
94 // should be deleted.
95 TEST_F(InstallerStateTest, Delete) {
96 // TODO(grt): move common stuff into the test fixture.
97 // Create a Chrome dir
98 base::FilePath chrome_dir(test_dir_.path());
99 chrome_dir = chrome_dir.AppendASCII("chrome");
100 file_util::CreateDirectory(chrome_dir);
101 ASSERT_TRUE(base::PathExists(chrome_dir));
103 base::FilePath chrome_dir_1(chrome_dir);
104 chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
105 file_util::CreateDirectory(chrome_dir_1);
106 ASSERT_TRUE(base::PathExists(chrome_dir_1));
108 base::FilePath chrome_dir_2(chrome_dir);
109 chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
110 file_util::CreateDirectory(chrome_dir_2);
111 ASSERT_TRUE(base::PathExists(chrome_dir_2));
113 base::FilePath chrome_dir_3(chrome_dir);
114 chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
115 file_util::CreateDirectory(chrome_dir_3);
116 ASSERT_TRUE(base::PathExists(chrome_dir_3));
118 base::FilePath chrome_dir_4(chrome_dir);
119 chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
120 file_util::CreateDirectory(chrome_dir_4);
121 ASSERT_TRUE(base::PathExists(chrome_dir_4));
123 base::FilePath chrome_dll_1(chrome_dir_1);
124 chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
125 CreateTextFile(chrome_dll_1.value(), text_content_1);
126 ASSERT_TRUE(base::PathExists(chrome_dll_1));
128 base::FilePath chrome_dll_2(chrome_dir_2);
129 chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
130 CreateTextFile(chrome_dll_2.value(), text_content_1);
131 ASSERT_TRUE(base::PathExists(chrome_dll_2));
133 base::FilePath chrome_dll_3(chrome_dir_3);
134 chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
135 CreateTextFile(chrome_dll_3.value(), text_content_1);
136 ASSERT_TRUE(base::PathExists(chrome_dll_3));
138 base::FilePath chrome_dll_4(chrome_dir_4);
139 chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
140 CreateTextFile(chrome_dll_4.value(), text_content_1);
141 ASSERT_TRUE(base::PathExists(chrome_dll_4));
143 MockInstallerState installer_state;
144 BuildSingleChromeState(chrome_dir, &installer_state);
145 Version latest_version("1.0.4.0");
147 base::ScopedTempDir temp_dir;
148 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
149 installer_state.RemoveOldVersionDirectories(latest_version, NULL,
150 temp_dir.path());
153 // old versions should be gone
154 EXPECT_FALSE(base::PathExists(chrome_dir_1));
155 EXPECT_FALSE(base::PathExists(chrome_dir_2));
156 EXPECT_FALSE(base::PathExists(chrome_dir_3));
157 // the latest version should stay
158 EXPECT_TRUE(base::PathExists(chrome_dll_4));
161 // Delete older version directories, keeping the one in used intact.
162 TEST_F(InstallerStateTest, DeleteInUsed) {
163 // Create a Chrome dir
164 base::FilePath chrome_dir(test_dir_.path());
165 chrome_dir = chrome_dir.AppendASCII("chrome");
166 file_util::CreateDirectory(chrome_dir);
167 ASSERT_TRUE(base::PathExists(chrome_dir));
169 base::FilePath chrome_dir_1(chrome_dir);
170 chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
171 file_util::CreateDirectory(chrome_dir_1);
172 ASSERT_TRUE(base::PathExists(chrome_dir_1));
174 base::FilePath chrome_dir_2(chrome_dir);
175 chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
176 file_util::CreateDirectory(chrome_dir_2);
177 ASSERT_TRUE(base::PathExists(chrome_dir_2));
179 base::FilePath chrome_dir_3(chrome_dir);
180 chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
181 file_util::CreateDirectory(chrome_dir_3);
182 ASSERT_TRUE(base::PathExists(chrome_dir_3));
184 base::FilePath chrome_dir_4(chrome_dir);
185 chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
186 file_util::CreateDirectory(chrome_dir_4);
187 ASSERT_TRUE(base::PathExists(chrome_dir_4));
189 base::FilePath chrome_dll_1(chrome_dir_1);
190 chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
191 CreateTextFile(chrome_dll_1.value(), text_content_1);
192 ASSERT_TRUE(base::PathExists(chrome_dll_1));
194 base::FilePath chrome_dll_2(chrome_dir_2);
195 chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
196 CreateTextFile(chrome_dll_2.value(), text_content_1);
197 ASSERT_TRUE(base::PathExists(chrome_dll_2));
199 // Open the file to make it in use.
200 std::ofstream file;
201 file.open(chrome_dll_2.value().c_str());
203 base::FilePath chrome_othera_2(chrome_dir_2);
204 chrome_othera_2 = chrome_othera_2.AppendASCII("othera.dll");
205 CreateTextFile(chrome_othera_2.value(), text_content_2);
206 ASSERT_TRUE(base::PathExists(chrome_othera_2));
208 base::FilePath chrome_otherb_2(chrome_dir_2);
209 chrome_otherb_2 = chrome_otherb_2.AppendASCII("otherb.dll");
210 CreateTextFile(chrome_otherb_2.value(), text_content_2);
211 ASSERT_TRUE(base::PathExists(chrome_otherb_2));
213 base::FilePath chrome_dll_3(chrome_dir_3);
214 chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
215 CreateTextFile(chrome_dll_3.value(), text_content_1);
216 ASSERT_TRUE(base::PathExists(chrome_dll_3));
218 base::FilePath chrome_dll_4(chrome_dir_4);
219 chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
220 CreateTextFile(chrome_dll_4.value(), text_content_1);
221 ASSERT_TRUE(base::PathExists(chrome_dll_4));
223 MockInstallerState installer_state;
224 BuildSingleChromeState(chrome_dir, &installer_state);
225 Version latest_version("1.0.4.0");
226 Version existing_version("1.0.1.0");
228 base::ScopedTempDir temp_dir;
229 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
230 installer_state.RemoveOldVersionDirectories(latest_version,
231 &existing_version,
232 temp_dir.path());
235 // the version defined as the existing version should stay
236 EXPECT_TRUE(base::PathExists(chrome_dir_1));
237 // old versions not in used should be gone
238 EXPECT_FALSE(base::PathExists(chrome_dir_3));
239 // every thing under in used version should stay
240 EXPECT_TRUE(base::PathExists(chrome_dir_2));
241 EXPECT_TRUE(base::PathExists(chrome_dll_2));
242 EXPECT_TRUE(base::PathExists(chrome_othera_2));
243 EXPECT_TRUE(base::PathExists(chrome_otherb_2));
244 // the latest version should stay
245 EXPECT_TRUE(base::PathExists(chrome_dll_4));
248 // Tests a few basic things of the Package class. Makes sure that the path
249 // operations are correct
250 TEST_F(InstallerStateTest, Basic) {
251 const bool multi_install = false;
252 const bool system_level = true;
253 CommandLine cmd_line = CommandLine::FromString(
254 std::wstring(L"setup.exe") +
255 (multi_install ? L" --multi-install --chrome" : L"") +
256 (system_level ? L" --system-level" : L""));
257 MasterPreferences prefs(cmd_line);
258 InstallationState machine_state;
259 machine_state.Initialize();
260 MockInstallerState installer_state;
261 installer_state.Initialize(cmd_line, prefs, machine_state);
262 installer_state.set_target_path(test_dir_.path());
263 EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
264 EXPECT_EQ(1U, installer_state.products().size());
266 const char kOldVersion[] = "1.2.3.4";
267 const char kNewVersion[] = "2.3.4.5";
269 Version new_version(kNewVersion);
270 Version old_version(kOldVersion);
271 ASSERT_TRUE(new_version.IsValid());
272 ASSERT_TRUE(old_version.IsValid());
274 base::FilePath installer_dir(
275 installer_state.GetInstallerDirectory(new_version));
276 EXPECT_FALSE(installer_dir.empty());
278 base::FilePath new_version_dir(installer_state.target_path().Append(
279 UTF8ToWide(new_version.GetString())));
280 base::FilePath old_version_dir(installer_state.target_path().Append(
281 UTF8ToWide(old_version.GetString())));
283 EXPECT_FALSE(base::PathExists(new_version_dir));
284 EXPECT_FALSE(base::PathExists(old_version_dir));
286 EXPECT_FALSE(base::PathExists(installer_dir));
287 file_util::CreateDirectory(installer_dir);
288 EXPECT_TRUE(base::PathExists(new_version_dir));
290 file_util::CreateDirectory(old_version_dir);
291 EXPECT_TRUE(base::PathExists(old_version_dir));
293 // Create a fake chrome.dll key file in the old version directory. This
294 // should prevent the old version directory from getting deleted.
295 base::FilePath old_chrome_dll(old_version_dir.Append(installer::kChromeDll));
296 EXPECT_FALSE(base::PathExists(old_chrome_dll));
298 // Hold on to the file exclusively to prevent the directory from
299 // being deleted.
300 base::win::ScopedHandle file(
301 ::CreateFile(old_chrome_dll.value().c_str(), GENERIC_READ,
302 0, NULL, OPEN_ALWAYS, 0, NULL));
303 EXPECT_TRUE(file.IsValid());
304 EXPECT_TRUE(base::PathExists(old_chrome_dll));
306 base::ScopedTempDir temp_dir;
307 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
309 // Don't explicitly tell the directory cleanup logic not to delete the
310 // old version, rely on the key files to keep it around.
311 installer_state.RemoveOldVersionDirectories(new_version,
312 NULL,
313 temp_dir.path());
315 // The old directory should still exist.
316 EXPECT_TRUE(base::PathExists(old_version_dir));
317 EXPECT_TRUE(base::PathExists(new_version_dir));
319 // Now close the file handle to make it possible to delete our key file.
320 file.Close();
322 installer_state.RemoveOldVersionDirectories(new_version,
323 NULL,
324 temp_dir.path());
325 // The new directory should still exist.
326 EXPECT_TRUE(base::PathExists(new_version_dir));
328 // Now, the old directory and key file should be gone.
329 EXPECT_FALSE(base::PathExists(old_chrome_dll));
330 EXPECT_FALSE(base::PathExists(old_version_dir));
333 TEST_F(InstallerStateTest, WithProduct) {
334 const bool multi_install = false;
335 const bool system_level = true;
336 CommandLine cmd_line = CommandLine::FromString(
337 std::wstring(L"setup.exe") +
338 (multi_install ? L" --multi-install --chrome" : L"") +
339 (system_level ? L" --system-level" : L""));
340 MasterPreferences prefs(cmd_line);
341 InstallationState machine_state;
342 machine_state.Initialize();
343 MockInstallerState installer_state;
344 installer_state.Initialize(cmd_line, prefs, machine_state);
345 installer_state.set_target_path(test_dir_.path());
346 EXPECT_EQ(1U, installer_state.products().size());
347 EXPECT_EQ(system_level, installer_state.system_install());
349 const char kCurrentVersion[] = "1.2.3.4";
350 Version current_version(kCurrentVersion);
352 HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
353 EXPECT_EQ(root, installer_state.root_key());
356 RegistryOverrideManager override_manager;
357 override_manager.OverrideRegistry(root, L"root_pit");
358 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
359 BrowserDistribution::CHROME_BROWSER);
360 RegKey chrome_key(root, dist->GetVersionKey().c_str(), KEY_ALL_ACCESS);
361 EXPECT_TRUE(chrome_key.Valid());
362 if (chrome_key.Valid()) {
363 chrome_key.WriteValue(google_update::kRegVersionField,
364 UTF8ToWide(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 bool multi_install = false;
378 HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
380 RegKey key;
381 std::wstring launch_cmd = L"hey diddle diddle";
382 std::wstring value;
383 DWORD dw_value;
385 // check results for a fresh install of single Chrome
387 RegistryOverrideManager override_manager;
388 override_manager.OverrideRegistry(root, L"root_inst_res");
389 CommandLine cmd_line = CommandLine::FromString(L"setup.exe --system-level");
390 const MasterPreferences prefs(cmd_line);
391 InstallationState machine_state;
392 machine_state.Initialize();
393 InstallerState state;
394 state.Initialize(cmd_line, prefs, machine_state);
395 state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS,
396 IDS_INSTALL_OS_ERROR_BASE, &launch_cmd);
397 BrowserDistribution* distribution =
398 BrowserDistribution::GetSpecificDistribution(
399 BrowserDistribution::CHROME_BROWSER);
400 EXPECT_EQ(ERROR_SUCCESS,
401 key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
402 EXPECT_EQ(ERROR_SUCCESS,
403 key.ReadValueDW(installer::kInstallerResult, &dw_value));
404 EXPECT_EQ(static_cast<DWORD>(0), dw_value);
405 EXPECT_EQ(ERROR_SUCCESS,
406 key.ReadValueDW(installer::kInstallerError, &dw_value));
407 EXPECT_EQ(static_cast<DWORD>(installer::FIRST_INSTALL_SUCCESS), dw_value);
408 EXPECT_EQ(ERROR_SUCCESS,
409 key.ReadValue(installer::kInstallerResultUIString, &value));
410 EXPECT_FALSE(value.empty());
411 EXPECT_EQ(ERROR_SUCCESS,
412 key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
413 EXPECT_EQ(launch_cmd, value);
416 // check results for a fresh install of multi Chrome
418 RegistryOverrideManager override_manager;
419 override_manager.OverrideRegistry(root, L"root_inst_res");
420 CommandLine cmd_line = CommandLine::FromString(
421 L"setup.exe --system-level --multi-install --chrome");
422 const MasterPreferences prefs(cmd_line);
423 InstallationState machine_state;
424 machine_state.Initialize();
425 InstallerState state;
426 state.Initialize(cmd_line, prefs, machine_state);
427 state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS, 0,
428 &launch_cmd);
429 BrowserDistribution* distribution =
430 BrowserDistribution::GetSpecificDistribution(
431 BrowserDistribution::CHROME_BROWSER);
432 BrowserDistribution* binaries =
433 BrowserDistribution::GetSpecificDistribution(
434 BrowserDistribution::CHROME_BINARIES);
435 EXPECT_EQ(ERROR_SUCCESS,
436 key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
437 EXPECT_EQ(ERROR_SUCCESS,
438 key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
439 EXPECT_EQ(launch_cmd, value);
440 EXPECT_EQ(ERROR_SUCCESS,
441 key.Open(root, binaries->GetStateKey().c_str(), KEY_READ));
442 EXPECT_EQ(ERROR_SUCCESS,
443 key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
444 EXPECT_EQ(launch_cmd, value);
445 key.Close();
449 // Test GetCurrentVersion when migrating single Chrome to multi
450 TEST_F(InstallerStateTest, GetCurrentVersionMigrateChrome) {
451 using installer::FakeInstallationState;
453 const bool system_install = false;
454 FakeInstallationState machine_state;
456 // Pretend that this version of single-install Chrome is already installed.
457 machine_state.AddChrome(system_install, false,
458 new Version(chrome::kChromeVersion));
460 // Now we're invoked to install multi Chrome.
461 CommandLine cmd_line(
462 CommandLine::FromString(L"setup.exe --multi-install --chrome"));
463 MasterPreferences prefs(cmd_line);
464 InstallerState installer_state;
465 installer_state.Initialize(cmd_line, prefs, machine_state);
467 // Is the Chrome version picked up?
468 scoped_ptr<Version> version(installer_state.GetCurrentVersion(machine_state));
469 EXPECT_TRUE(version.get() != NULL);
472 TEST_F(InstallerStateTest, IsFileInUse) {
473 base::ScopedTempDir temp_dir;
474 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
476 base::FilePath temp_file;
477 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
479 EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
482 // Open a handle to the file with the same access mode and sharing options
483 // as the loader.
484 base::win::ScopedHandle temp_handle(
485 CreateFile(temp_file.value().c_str(),
486 SYNCHRONIZE | FILE_EXECUTE,
487 FILE_SHARE_DELETE | FILE_SHARE_READ,
488 NULL, OPEN_EXISTING, 0, 0));
489 ASSERT_TRUE(temp_handle != NULL);
491 // The file should now be in use.
492 EXPECT_TRUE(MockInstallerState::IsFileInUse(temp_file));
495 // And once the handle is gone, it should no longer be in use.
496 EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
499 TEST_F(InstallerStateTest, RemoveOldVersionDirs) {
500 MockInstallerState installer_state;
501 installer_state.set_target_path(test_dir_.path());
502 EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
504 const char kOldVersion[] = "2.0.0.0";
505 const char kNewVersion[] = "3.0.0.0";
506 const char kOldChromeExeVersion[] = "2.1.0.0";
507 const char kChromeExeVersion[] = "2.1.1.1";
508 const char kNewChromeExeVersion[] = "3.0.0.0";
510 Version new_version(kNewVersion);
511 Version old_version(kOldVersion);
512 Version old_chrome_exe_version(kOldChromeExeVersion);
513 Version chrome_exe_version(kChromeExeVersion);
514 Version new_chrome_exe_version(kNewChromeExeVersion);
516 ASSERT_TRUE(new_version.IsValid());
517 ASSERT_TRUE(old_version.IsValid());
518 ASSERT_TRUE(old_chrome_exe_version.IsValid());
519 ASSERT_TRUE(chrome_exe_version.IsValid());
520 ASSERT_TRUE(new_chrome_exe_version.IsValid());
522 // Set up a bunch of version dir paths.
523 base::FilePath version_dirs[] = {
524 installer_state.target_path().Append(L"1.2.3.4"),
525 installer_state.target_path().Append(L"1.2.3.5"),
526 installer_state.target_path().Append(L"1.2.3.6"),
527 installer_state.target_path().Append(ASCIIToWide(kOldVersion)),
528 installer_state.target_path().Append(ASCIIToWide(kOldChromeExeVersion)),
529 installer_state.target_path().Append(L"2.1.1.0"),
530 installer_state.target_path().Append(ASCIIToWide(kChromeExeVersion)),
531 installer_state.target_path().Append(ASCIIToWide(kNewVersion)),
532 installer_state.target_path().Append(L"3.9.1.1"),
535 // Create the version directories.
536 for (int i = 0; i < arraysize(version_dirs); i++) {
537 file_util::CreateDirectory(version_dirs[i]);
538 EXPECT_TRUE(base::PathExists(version_dirs[i]));
541 // Create exes with the appropriate version resource.
542 // Use the current test exe as a baseline.
543 base::FilePath exe_path;
544 ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe_path));
546 struct target_info {
547 base::FilePath target_file;
548 const Version& target_version;
549 } targets[] = {
550 { installer_state.target_path().Append(installer::kChromeOldExe),
551 old_chrome_exe_version },
552 { installer_state.target_path().Append(installer::kChromeExe),
553 chrome_exe_version },
554 { installer_state.target_path().Append(installer::kChromeNewExe),
555 new_chrome_exe_version },
557 for (int i = 0; i < arraysize(targets); ++i) {
558 ASSERT_TRUE(upgrade_test::GenerateSpecificPEFileVersion(
559 exe_path, targets[i].target_file, targets[i].target_version));
562 // Call GetExistingExeVersions, validate that picks up the
563 // exe resources.
564 std::set<std::string> expected_exe_versions;
565 expected_exe_versions.insert(kOldChromeExeVersion);
566 expected_exe_versions.insert(kChromeExeVersion);
567 expected_exe_versions.insert(kNewChromeExeVersion);
569 std::set<std::string> actual_exe_versions;
570 installer_state.GetExistingExeVersions(&actual_exe_versions);
571 EXPECT_EQ(expected_exe_versions, actual_exe_versions);
573 // Call RemoveOldVersionDirectories
574 installer_state.RemoveOldVersionDirectories(new_version,
575 &old_version,
576 installer_state.target_path());
578 // What we expect to have left.
579 std::set<std::string> expected_remaining_dirs;
580 expected_remaining_dirs.insert(kOldVersion);
581 expected_remaining_dirs.insert(kNewVersion);
582 expected_remaining_dirs.insert(kOldChromeExeVersion);
583 expected_remaining_dirs.insert(kChromeExeVersion);
584 expected_remaining_dirs.insert(kNewChromeExeVersion);
586 // Enumerate dirs in target_path(), ensure only desired remain.
587 base::FileEnumerator version_enum(installer_state.target_path(), false,
588 base::FileEnumerator::DIRECTORIES);
589 for (base::FilePath next_version = version_enum.Next(); !next_version.empty();
590 next_version = version_enum.Next()) {
591 base::FilePath dir_name(next_version.BaseName());
592 Version version(WideToASCII(dir_name.value()));
593 if (version.IsValid()) {
594 EXPECT_TRUE(expected_remaining_dirs.erase(version.GetString()))
595 << "Unexpected version dir found: " << version.GetString();
599 std::set<std::string>::const_iterator iter(
600 expected_remaining_dirs.begin());
601 for (; iter != expected_remaining_dirs.end(); ++iter)
602 ADD_FAILURE() << "Expected to find version dir for " << *iter;
606 // A fixture for testing InstallerState::DetermineCriticalVersion. Individual
607 // tests must invoke Initialize() with a critical version.
608 class InstallerStateCriticalVersionTest : public ::testing::Test {
609 protected:
610 InstallerStateCriticalVersionTest() : cmd_line_(CommandLine::NO_PROGRAM) {}
612 // Creates a set of versions for use by all test runs.
613 static void SetUpTestCase() {
614 low_version_ = new Version("15.0.874.106");
615 opv_version_ = new Version("15.0.874.255");
616 middle_version_ = new Version("16.0.912.32");
617 pv_version_ = new Version("16.0.912.255");
618 high_version_ = new Version("17.0.932.0");
621 // Cleans up versions used by all test runs.
622 static void TearDownTestCase() {
623 delete low_version_;
624 delete opv_version_;
625 delete middle_version_;
626 delete pv_version_;
627 delete high_version_;
630 // Initializes the InstallerState to use for a test run. The returned
631 // instance's critical update version is set to |version|. |version| may be
632 // NULL, in which case the critical update version is unset.
633 MockInstallerState& Initialize(const Version* version) {
634 cmd_line_ = version == NULL ?
635 CommandLine::FromString(L"setup.exe") :
636 CommandLine::FromString(
637 L"setup.exe --critical-update-version=" +
638 ASCIIToWide(version->GetString()));
639 prefs_.reset(new MasterPreferences(cmd_line_));
640 machine_state_.Initialize();
641 installer_state_.Initialize(cmd_line_, *prefs_, machine_state_);
642 return installer_state_;
645 static Version* low_version_;
646 static Version* opv_version_;
647 static Version* middle_version_;
648 static Version* pv_version_;
649 static Version* high_version_;
651 CommandLine cmd_line_;
652 scoped_ptr<MasterPreferences> prefs_;
653 InstallationState machine_state_;
654 MockInstallerState installer_state_;
657 Version* InstallerStateCriticalVersionTest::low_version_ = NULL;
658 Version* InstallerStateCriticalVersionTest::opv_version_ = NULL;
659 Version* InstallerStateCriticalVersionTest::middle_version_ = NULL;
660 Version* InstallerStateCriticalVersionTest::pv_version_ = NULL;
661 Version* InstallerStateCriticalVersionTest::high_version_ = NULL;
663 // Test the case where the critical version is less than the currently-running
664 // Chrome. The critical version is ignored since it doesn't apply.
665 TEST_F(InstallerStateCriticalVersionTest, CriticalBeforeOpv) {
666 MockInstallerState& installer_state(Initialize(low_version_));
668 EXPECT_TRUE(installer_state.critical_update_version().Equals(*low_version_));
669 // Unable to determine the installed version, so assume critical update.
670 EXPECT_TRUE(
671 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
672 // Installed version is past the critical update.
673 EXPECT_FALSE(
674 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
675 .IsValid());
676 // Installed version is past the critical update.
677 EXPECT_FALSE(
678 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
679 .IsValid());
682 // Test the case where the critical version is equal to the currently-running
683 // Chrome. The critical version is ignored since it doesn't apply.
684 TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsOpv) {
685 MockInstallerState& installer_state(Initialize(opv_version_));
687 EXPECT_TRUE(installer_state.critical_update_version().Equals(*opv_version_));
688 // Unable to determine the installed version, so assume critical update.
689 EXPECT_TRUE(
690 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
691 // Installed version equals the critical update.
692 EXPECT_FALSE(
693 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
694 .IsValid());
695 // Installed version equals the critical update.
696 EXPECT_FALSE(
697 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
698 .IsValid());
701 // Test the case where the critical version is between the currently-running
702 // Chrome and the to-be-installed Chrome.
703 TEST_F(InstallerStateCriticalVersionTest, CriticalBetweenOpvAndPv) {
704 MockInstallerState& installer_state(Initialize(middle_version_));
706 EXPECT_TRUE(installer_state.critical_update_version().Equals(
707 *middle_version_));
708 // Unable to determine the installed version, so assume critical update.
709 EXPECT_TRUE(
710 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
711 // Installed version before the critical update.
712 EXPECT_TRUE(
713 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
714 .IsValid());
715 // Installed version is past the critical update.
716 EXPECT_FALSE(
717 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
718 .IsValid());
721 // Test the case where the critical version is the same as the to-be-installed
722 // Chrome.
723 TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsPv) {
724 MockInstallerState& installer_state(Initialize(pv_version_));
726 EXPECT_TRUE(installer_state.critical_update_version().Equals(
727 *pv_version_));
728 // Unable to determine the installed version, so assume critical update.
729 EXPECT_TRUE(
730 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
731 // Installed version before the critical update.
732 EXPECT_TRUE(
733 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
734 .IsValid());
735 // Installed version equals the critical update.
736 EXPECT_FALSE(
737 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
738 .IsValid());
741 // Test the case where the critical version is greater than the to-be-installed
742 // Chrome.
743 TEST_F(InstallerStateCriticalVersionTest, CriticalAfterPv) {
744 MockInstallerState& installer_state(Initialize(high_version_));
746 EXPECT_TRUE(installer_state.critical_update_version().Equals(
747 *high_version_));
748 // Critical update newer than the new version.
749 EXPECT_FALSE(
750 installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
751 EXPECT_FALSE(
752 installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
753 .IsValid());
754 EXPECT_FALSE(
755 installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
756 .IsValid());