OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/installer/setup/install_worker.h" | 5 #include "chrome/installer/setup/install_worker.h" |
6 | 6 |
| 7 #include <iostream> |
| 8 |
| 9 #include "base/test/test_reg_util_win.h" |
| 10 #include "base/version.h" |
7 #include "base/win/registry.h" | 11 #include "base/win/registry.h" |
8 #include "base/version.h" | |
9 #include "chrome/common/chrome_constants.h" | 12 #include "chrome/common/chrome_constants.h" |
10 #include "chrome/installer/setup/setup_util.h" | 13 #include "chrome/installer/setup/setup_util.h" |
| 14 #include "chrome/installer/util/create_reg_key_work_item.h" |
11 #include "chrome/installer/util/delete_reg_key_work_item.h" | 15 #include "chrome/installer/util/delete_reg_key_work_item.h" |
12 #include "chrome/installer/util/create_reg_key_work_item.h" | 16 #include "chrome/installer/util/google_update_constants.h" |
13 #include "chrome/installer/util/helper.h" | 17 #include "chrome/installer/util/helper.h" |
14 #include "chrome/installer/util/google_update_constants.h" | 18 #include "chrome/installer/util/install_util.h" |
15 #include "chrome/installer/util/installation_state.h" | 19 #include "chrome/installer/util/installation_state.h" |
16 #include "chrome/installer/util/installer_state.h" | 20 #include "chrome/installer/util/installer_state.h" |
17 #include "chrome/installer/util/set_reg_value_work_item.h" | 21 #include "chrome/installer/util/set_reg_value_work_item.h" |
18 #include "chrome/installer/util/util_constants.h" | 22 #include "chrome/installer/util/util_constants.h" |
| 23 #include "chrome/installer/util/work_item.h" |
19 #include "chrome/installer/util/work_item_list.h" | 24 #include "chrome/installer/util/work_item_list.h" |
20 | 25 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | |
23 | 27 |
24 using base::win::RegKey; | 28 using base::win::RegKey; |
25 using installer::InstallationState; | 29 using installer::InstallationState; |
26 using installer::InstallerState; | 30 using installer::InstallerState; |
27 using installer::Product; | 31 using installer::Product; |
28 using installer::ProductState; | 32 using installer::ProductState; |
29 | 33 |
30 using ::testing::_; | 34 using ::testing::_; |
31 using ::testing::AtLeast; | 35 using ::testing::AtLeast; |
32 using ::testing::AtMost; | 36 using ::testing::AtMost; |
33 using ::testing::Bool; | 37 using ::testing::Bool; |
34 using ::testing::Combine; | 38 using ::testing::Combine; |
35 using ::testing::HasSubstr; | 39 using ::testing::HasSubstr; |
36 using ::testing::Eq; | 40 using ::testing::Eq; |
37 using ::testing::Return; | 41 using ::testing::Return; |
38 using ::testing::StrCaseEq; | 42 using ::testing::StrCaseEq; |
39 using ::testing::StrEq; | 43 using ::testing::StrEq; |
40 using ::testing::StrictMock; | 44 using ::testing::StrictMock; |
41 using ::testing::Values; | 45 using ::testing::ValuesIn; |
42 | 46 |
43 // Mock classes to help with testing | 47 // Mock classes to help with testing |
44 //------------------------------------------------------------------------------ | 48 //------------------------------------------------------------------------------ |
45 | 49 |
46 class MockWorkItemList : public WorkItemList { | 50 class MockWorkItemList : public WorkItemList { |
47 public: | 51 public: |
48 MockWorkItemList() {} | 52 MockWorkItemList() {} |
49 | 53 |
50 MOCK_METHOD4(AddCopyRegKeyWorkItem, WorkItem* (HKEY, | 54 MOCK_METHOD4(AddCopyRegKeyWorkItem, WorkItem* (HKEY, |
51 const std::wstring&, | 55 const std::wstring&, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 void set_package_type(PackageType type) { | 163 void set_package_type(PackageType type) { |
160 InstallerState::set_package_type(type); | 164 InstallerState::set_package_type(type); |
161 } | 165 } |
162 }; | 166 }; |
163 | 167 |
164 // The test fixture | 168 // The test fixture |
165 //------------------------------------------------------------------------------ | 169 //------------------------------------------------------------------------------ |
166 | 170 |
167 class InstallWorkerTest : public testing::Test { | 171 class InstallWorkerTest : public testing::Test { |
168 public: | 172 public: |
| 173 InstallWorkerTest() {} |
| 174 |
169 void SetUp() override { | 175 void SetUp() override { |
| 176 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER); |
| 177 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE); |
| 178 |
170 current_version_.reset(new Version("1.0.0.0")); | 179 current_version_.reset(new Version("1.0.0.0")); |
171 new_version_.reset(new Version("42.0.0.0")); | 180 new_version_.reset(new Version("42.0.0.0")); |
172 | 181 |
173 // Don't bother ensuring that these paths exist. Since we're just | 182 // Don't bother ensuring that these paths exist. Since we're just |
174 // building the work item lists and not running them, they shouldn't | 183 // building the work item lists and not running them, they shouldn't |
175 // actually be touched. | 184 // actually be touched. |
176 archive_path_ = | 185 archive_path_ = |
177 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z"); | 186 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z"); |
178 // TODO(robertshield): Take this from the BrowserDistribution once that | 187 // TODO(robertshield): Take this from the BrowserDistribution once that |
179 // no longer depends on MasterPreferences. | 188 // no longer depends on MasterPreferences. |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 } | 426 } |
418 | 427 |
419 protected: | 428 protected: |
420 scoped_ptr<Version> current_version_; | 429 scoped_ptr<Version> current_version_; |
421 scoped_ptr<Version> new_version_; | 430 scoped_ptr<Version> new_version_; |
422 base::FilePath archive_path_; | 431 base::FilePath archive_path_; |
423 base::FilePath installation_path_; | 432 base::FilePath installation_path_; |
424 base::FilePath setup_path_; | 433 base::FilePath setup_path_; |
425 base::FilePath src_path_; | 434 base::FilePath src_path_; |
426 base::FilePath temp_dir_; | 435 base::FilePath temp_dir_; |
| 436 |
| 437 private: |
| 438 registry_util::RegistryOverrideManager registry_override_manager_; |
| 439 |
| 440 DISALLOW_COPY_AND_ASSIGN(InstallWorkerTest); |
427 }; | 441 }; |
428 | 442 |
429 // Tests | 443 // Tests |
430 //------------------------------------------------------------------------------ | 444 //------------------------------------------------------------------------------ |
431 | 445 |
432 TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) { | 446 TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) { |
433 const bool system_level = true; | 447 const bool system_level = true; |
434 const bool multi_install = false; | 448 const bool multi_install = false; |
435 MockWorkItemList work_item_list; | 449 MockWorkItemList work_item_list; |
436 | 450 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 AddDeleteRegValueWorkItem( | 678 AddDeleteRegValueWorkItem( |
665 Eq(installer_state->root_key()), | 679 Eq(installer_state->root_key()), |
666 StrEq(chrome_dist->GetStateKey()), | 680 StrEq(chrome_dist->GetStateKey()), |
667 StrEq(google_update::kRegUsageStatsField))).Times(1); | 681 StrEq(google_update::kRegUsageStatsField))).Times(1); |
668 | 682 |
669 AddUsageStatsWorkItems(*installation_state.get(), | 683 AddUsageStatsWorkItems(*installation_state.get(), |
670 *installer_state.get(), | 684 *installer_state.get(), |
671 &work_item_list); | 685 &work_item_list); |
672 } | 686 } |
673 | 687 |
| 688 struct ActiveSetupWorkerTestCase { |
| 689 // The initial value to be set in the registry prior to simulating the update. |
| 690 // No value will be set if this null. |
| 691 const wchar_t* initial_value; |
| 692 |
| 693 // The expected value after simulating the update. |
| 694 const wchar_t* expected_result; |
| 695 }; |
| 696 |
| 697 // Implements PrintTo in order for gtest to be able to print the problematic |
| 698 // ActiveSetupWorkerTestCase on failure. |
| 699 void PrintTo(const ActiveSetupWorkerTestCase& test_case, ::std::ostream* os) { |
| 700 *os << "Initial value: " |
| 701 << (test_case.initial_value ? test_case.initial_value : L"(empty)") |
| 702 << ", expected result: " << test_case.expected_result; |
| 703 } |
| 704 |
| 705 class ActiveSetupWorkerTest |
| 706 : public InstallWorkerTest, |
| 707 public ::testing::WithParamInterface<ActiveSetupWorkerTestCase> {}; |
| 708 |
| 709 // Test that active setup version installing/updating is handled properly. |
| 710 TEST_P(ActiveSetupWorkerTest, AddAndRunActiveSetupWorkItems) { |
| 711 // Active Setup only makes sense at system-level. |
| 712 const bool system_level = true; |
| 713 const bool multi_install = false; |
| 714 |
| 715 scoped_ptr<MockInstallationState> installation_state( |
| 716 BuildChromeInstallationState(system_level, multi_install)); |
| 717 |
| 718 MockProductState chrome_state; |
| 719 chrome_state.set_version(new Version(*current_version_)); |
| 720 chrome_state.set_multi_install(multi_install); |
| 721 |
| 722 installation_state->SetProductState( |
| 723 system_level, BrowserDistribution::CHROME_BROWSER, chrome_state); |
| 724 |
| 725 scoped_ptr<MockInstallerState> installer_state( |
| 726 BuildChromeInstallerState(system_level, multi_install, |
| 727 *installation_state, |
| 728 InstallerState::MULTI_INSTALL)); |
| 729 |
| 730 |
| 731 const HKEY kRoot = HKEY_LOCAL_MACHINE; |
| 732 const std::wstring active_setup_path(InstallUtil::GetActiveSetupPath( |
| 733 BrowserDistribution::GetSpecificDistribution( |
| 734 BrowserDistribution::CHROME_BROWSER))); |
| 735 RegKey test_key; |
| 736 |
| 737 EXPECT_NE(ERROR_SUCCESS, |
| 738 test_key.Open(kRoot, active_setup_path.c_str(), KEY_READ)); |
| 739 |
| 740 // Get the |test_case| which defines 3 steps: |
| 741 // 1) Maybe set an initial Active Setup version. |
| 742 // 2) Unconditionally execute the Active Setup work items. |
| 743 // 3) Verify that the updated Active Setup version is as expected. |
| 744 const ActiveSetupWorkerTestCase& test_case = GetParam(); |
| 745 |
| 746 if (test_case.initial_value) { |
| 747 EXPECT_EQ(ERROR_SUCCESS, |
| 748 test_key.Create(kRoot, active_setup_path.c_str(), KEY_SET_VALUE)); |
| 749 EXPECT_EQ(ERROR_SUCCESS, |
| 750 test_key.WriteValue(L"Version", test_case.initial_value)); |
| 751 } |
| 752 |
| 753 // Note: This performs real operations, it's *not* a MockWorkItemList like in |
| 754 // the other tests (the registry itself is mocked in the fixture however so |
| 755 // this is okay). |
| 756 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); |
| 757 AddActiveSetupWorkItems( |
| 758 *installer_state, *current_version_, |
| 759 *installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER), |
| 760 work_item_list.get()); |
| 761 work_item_list->Do(); |
| 762 |
| 763 std::wstring version_out; |
| 764 EXPECT_EQ(ERROR_SUCCESS, |
| 765 test_key.Open(kRoot, active_setup_path.c_str(), KEY_QUERY_VALUE)); |
| 766 EXPECT_EQ(ERROR_SUCCESS, test_key.ReadValue(L"Version", &version_out)); |
| 767 EXPECT_EQ(test_case.expected_result, version_out); |
| 768 } |
| 769 |
| 770 const ActiveSetupWorkerTestCase kActiveSetupTestCases[] = { |
| 771 // Initial install. |
| 772 {nullptr, L"43,0,0,0"}, |
| 773 // No-op update. |
| 774 {L"43.0.0.0", L"43,0,0,0"}, |
| 775 // Update only major component. |
| 776 {L"24,1,2,3", L"43,1,2,3"}, |
| 777 // Reset from bogus value. |
| 778 {L"zzz", L"43,0,0,0"}, |
| 779 // Reset from invalid version (too few components). |
| 780 {L"1,2", L"43,0,0,0"}, |
| 781 // Reset from invalid version (too many components). |
| 782 {L"43,1,2,3,10", L"43,0,0,0"}, |
| 783 // Reset from empty string. |
| 784 {L"", L"43,0,0,0"}, |
| 785 }; |
| 786 |
| 787 INSTANTIATE_TEST_CASE_P(ActiveSetupWorkerTestInstance, |
| 788 ActiveSetupWorkerTest, |
| 789 ValuesIn(kActiveSetupTestCases)); |
| 790 |
674 // The Quick Enable tests only make sense for the Google Chrome build as it | 791 // The Quick Enable tests only make sense for the Google Chrome build as it |
675 // interacts with registry values that are specific to Google Update. | 792 // interacts with registry values that are specific to Google Update. |
676 #if defined(GOOGLE_CHROME_BUILD) | 793 #if defined(GOOGLE_CHROME_BUILD) |
677 | 794 |
678 // Test scenarios under which the quick-enable-cf command should not exist after | 795 // Test scenarios under which the quick-enable-cf command should not exist after |
679 // the run. We're permissive in that we allow the DeleteRegKeyWorkItem even if | 796 // the run. We're permissive in that we allow the DeleteRegKeyWorkItem even if |
680 // it isn't strictly needed. | 797 // it isn't strictly needed. |
681 class QuickEnableAbsentTest : public InstallWorkerTest { | 798 class QuickEnableAbsentTest : public InstallWorkerTest { |
682 public: | 799 public: |
683 virtual void SetUp() { | 800 virtual void SetUp() { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 prod_type_list[i_type_check]); | 914 prod_type_list[i_type_check]); |
798 bool prod_expect = (mach_after & (1 << i_type_check)) != 0; | 915 bool prod_expect = (mach_after & (1 << i_type_check)) != 0; |
799 EXPECT_EQ(prod_expect, prod_res); | 916 EXPECT_EQ(prod_expect, prod_res); |
800 } | 917 } |
801 } | 918 } |
802 } | 919 } |
803 } | 920 } |
804 } | 921 } |
805 | 922 |
806 #endif // defined(GOOGLE_CHROME_BUILD) | 923 #endif // defined(GOOGLE_CHROME_BUILD) |
OLD | NEW |