| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/installer/util/google_update_settings.h" |
| |
| #include <windows.h> |
| #include <shlwapi.h> // For SHDeleteKey. |
| |
| #include "base/base_paths.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/path_service.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/scoped_path_override.h" |
| #include "base/test/test_reg_util_win.h" |
| #include "base/win/registry.h" |
| #include "base/win/win_util.h" |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/installer/util/app_registration_data.h" |
| #include "chrome/installer/util/browser_distribution.h" |
| #include "chrome/installer/util/channel_info.h" |
| #include "chrome/installer/util/fake_installation_state.h" |
| #include "chrome/installer/util/google_update_constants.h" |
| #include "chrome/installer/util/google_update_experiment_util.h" |
| #include "chrome/installer/util/util_constants.h" |
| #include "chrome/installer/util/work_item_list.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using base::win::RegKey; |
| using installer::ChannelInfo; |
| |
| namespace { |
| |
| const wchar_t kTestProductGuid[] = L"{89F1B351-B15D-48D4-8F10-1298721CF13D}"; |
| const wchar_t kTestExperimentLabel[] = L"test_label_value"; |
| |
| // This test fixture redirects the HKLM and HKCU registry hives for |
| // the duration of the test to make it independent of the machine |
| // and user settings. |
| class GoogleUpdateSettingsTest : public testing::Test { |
| protected: |
| enum SystemUserInstall { |
| SYSTEM_INSTALL, |
| USER_INSTALL, |
| }; |
| |
| GoogleUpdateSettingsTest() |
| : program_files_override_(base::DIR_PROGRAM_FILES), |
| program_files_x86_override_(base::DIR_PROGRAM_FILESX86) { |
| registry_overrides_.OverrideRegistry(HKEY_LOCAL_MACHINE); |
| registry_overrides_.OverrideRegistry(HKEY_CURRENT_USER); |
| } |
| |
| void SetApField(SystemUserInstall is_system, const wchar_t* value) { |
| HKEY root = is_system == SYSTEM_INSTALL ? |
| HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| |
| RegKey update_key; |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| base::string16 path = dist->GetStateKey(); |
| ASSERT_EQ(ERROR_SUCCESS, update_key.Create(root, path.c_str(), KEY_WRITE)); |
| ASSERT_EQ(ERROR_SUCCESS, update_key.WriteValue(L"ap", value)); |
| } |
| |
| // Sets the "ap" field for a multi-install product (both the product and |
| // the binaries). |
| void SetMultiApField(SystemUserInstall is_system, const wchar_t* value) { |
| // Caller must specify a multi-install ap value. |
| ASSERT_NE(base::string16::npos, base::string16(value).find(L"-multi")); |
| HKEY root = is_system == SYSTEM_INSTALL ? |
| HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| RegKey update_key; |
| |
| // Write the ap value for both the product and the binaries. |
| BrowserDistribution* const kDists[] = { |
| BrowserDistribution::GetDistribution(), |
| BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BINARIES) |
| }; |
| for (size_t i = 0; i < arraysize(kDists); ++i) { |
| base::string16 path = kDists[i]->GetStateKey(); |
| ASSERT_EQ(ERROR_SUCCESS, update_key.Create(root, path.c_str(), |
| KEY_WRITE)); |
| ASSERT_EQ(ERROR_SUCCESS, update_key.WriteValue(L"ap", value)); |
| } |
| |
| // Make the product technically multi-install. |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| ASSERT_EQ(ERROR_SUCCESS, |
| update_key.Create(root, dist->GetStateKey().c_str(), KEY_WRITE)); |
| ASSERT_EQ(ERROR_SUCCESS, |
| update_key.WriteValue(installer::kUninstallArgumentsField, |
| L"--multi-install")); |
| } |
| |
| // Tests setting the ap= value to various combinations of values with |
| // prefixes and suffixes, while asserting on the correct channel value. |
| // Note that any non-empty ap= value that doesn't match ".*-{dev|beta}.*" |
| // will return the "unknown" channel. |
| void TestCurrentChromeChannelWithVariousApValues(SystemUserInstall install) { |
| static struct Expectations { |
| const wchar_t* ap_value; |
| const wchar_t* channel; |
| } expectations[] = { |
| { L"dev", installer::kChromeChannelDev }, |
| { L"-dev", installer::kChromeChannelDev }, |
| { L"-developer", installer::kChromeChannelDev }, |
| { L"beta", installer::kChromeChannelBeta }, |
| { L"-beta", installer::kChromeChannelBeta }, |
| { L"-betamax", installer::kChromeChannelBeta }, |
| }; |
| bool is_system = install == SYSTEM_INSTALL; |
| const wchar_t* prefixes[] = { |
| L"", |
| L"prefix", |
| L"prefix-with-dash", |
| }; |
| const wchar_t* suffixes[] = { |
| L"", |
| L"suffix", |
| L"suffix-with-dash", |
| }; |
| |
| for (size_t i = 0; i < arraysize(prefixes); ++i) { |
| for (size_t j = 0; j < arraysize(expectations); ++j) { |
| for (size_t k = 0; k < arraysize(suffixes); ++k) { |
| base::string16 ap = prefixes[i]; |
| ap += expectations[j].ap_value; |
| ap += suffixes[k]; |
| const wchar_t* channel = expectations[j].channel; |
| |
| SetApField(install, ap.c_str()); |
| base::string16 ret_channel; |
| |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers( |
| is_system, &ret_channel)); |
| EXPECT_STREQ(channel, ret_channel.c_str()) |
| << "Expecting channel \"" << channel |
| << "\" for ap=\"" << ap << "\""; |
| } |
| } |
| } |
| } |
| |
| // Test the writing and deleting functionality of the experiments label |
| // helper. |
| void TestExperimentsLabelHelper(SystemUserInstall install) { |
| BrowserDistribution* chrome = |
| BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BROWSER); |
| base::string16 value; |
| #if defined(GOOGLE_CHROME_BUILD) |
| EXPECT_TRUE(chrome->ShouldSetExperimentLabels()); |
| |
| // Before anything is set, ReadExperimentLabels should succeed but return |
| // an empty string. |
| EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels( |
| install == SYSTEM_INSTALL, &value)); |
| EXPECT_EQ(base::string16(), value); |
| |
| EXPECT_TRUE(GoogleUpdateSettings::SetExperimentLabels( |
| install == SYSTEM_INSTALL, kTestExperimentLabel)); |
| |
| // Validate that something is written. Only worry about the label itself. |
| RegKey key; |
| HKEY root = install == SYSTEM_INSTALL ? |
| HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| base::string16 state_key = install == SYSTEM_INSTALL ? |
| chrome->GetStateMediumKey() : chrome->GetStateKey(); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.Open(root, state_key.c_str(), KEY_QUERY_VALUE)); |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.ReadValue(google_update::kExperimentLabels, &value)); |
| EXPECT_EQ(kTestExperimentLabel, value); |
| EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels( |
| install == SYSTEM_INSTALL, &value)); |
| EXPECT_EQ(kTestExperimentLabel, value); |
| key.Close(); |
| |
| // Now that the label is set, test the delete functionality. An empty label |
| // should result in deleting the value. |
| EXPECT_TRUE(GoogleUpdateSettings::SetExperimentLabels( |
| install == SYSTEM_INSTALL, base::string16())); |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.Open(root, state_key.c_str(), KEY_QUERY_VALUE)); |
| EXPECT_EQ(ERROR_FILE_NOT_FOUND, |
| key.ReadValue(google_update::kExperimentLabels, &value)); |
| EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels( |
| install == SYSTEM_INSTALL, &value)); |
| EXPECT_EQ(base::string16(), value); |
| key.Close(); |
| #else |
| EXPECT_FALSE(chrome->ShouldSetExperimentLabels()); |
| EXPECT_FALSE(GoogleUpdateSettings::ReadExperimentLabels( |
| install == SYSTEM_INSTALL, &value)); |
| #endif // GOOGLE_CHROME_BUILD |
| } |
| |
| // Creates "ap" key with the value given as parameter. Also adds work |
| // items to work_item_list given so that they can be rolled back later. |
| bool CreateApKey(WorkItemList* work_item_list, const base::string16& value) { |
| HKEY reg_root = HKEY_CURRENT_USER; |
| base::string16 reg_key = GetApKeyPath(); |
| work_item_list->AddCreateRegKeyWorkItem( |
| reg_root, reg_key, WorkItem::kWow64Default); |
| work_item_list->AddSetRegValueWorkItem(reg_root, |
| reg_key, |
| WorkItem::kWow64Default, |
| google_update::kRegApField, |
| value.c_str(), |
| true); |
| if (!work_item_list->Do()) { |
| work_item_list->Rollback(); |
| return false; |
| } |
| return true; |
| } |
| |
| // Returns the key path of "ap" key, e.g.: |
| // Google\Update\ClientState\<kTestProductGuid> |
| base::string16 GetApKeyPath() { |
| base::string16 reg_key(google_update::kRegPathClientState); |
| reg_key.append(L"\\"); |
| reg_key.append(kTestProductGuid); |
| return reg_key; |
| } |
| |
| // Utility method to read "ap" key value |
| base::string16 ReadApKeyValue() { |
| RegKey key; |
| base::string16 ap_key_value; |
| base::string16 reg_key = GetApKeyPath(); |
| if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) == |
| ERROR_SUCCESS) { |
| key.ReadValue(google_update::kRegApField, &ap_key_value); |
| } |
| |
| return ap_key_value; |
| } |
| |
| bool SetUpdatePolicyForAppGuid(const base::string16& app_guid, |
| GoogleUpdateSettings::UpdatePolicy policy) { |
| RegKey policy_key; |
| if (policy_key.Create(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE) == ERROR_SUCCESS) { |
| base::string16 app_update_override( |
| GoogleUpdateSettings::kUpdateOverrideValuePrefix); |
| app_update_override.append(app_guid); |
| return policy_key.WriteValue(app_update_override.c_str(), |
| static_cast<DWORD>(policy)) == ERROR_SUCCESS; |
| } |
| return false; |
| } |
| |
| GoogleUpdateSettings::UpdatePolicy GetUpdatePolicyForAppGuid( |
| const base::string16& app_guid) { |
| RegKey policy_key; |
| if (policy_key.Create(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_QUERY_VALUE) == ERROR_SUCCESS) { |
| base::string16 app_update_override( |
| GoogleUpdateSettings::kUpdateOverrideValuePrefix); |
| app_update_override.append(app_guid); |
| |
| DWORD value; |
| if (policy_key.ReadValueDW(app_update_override.c_str(), |
| &value) == ERROR_SUCCESS) { |
| return static_cast<GoogleUpdateSettings::UpdatePolicy>(value); |
| } |
| } |
| return GoogleUpdateSettings::UPDATE_POLICIES_COUNT; |
| } |
| |
| bool SetGlobalUpdatePolicy(GoogleUpdateSettings::UpdatePolicy policy) { |
| RegKey policy_key; |
| return policy_key.Create(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE) == ERROR_SUCCESS && |
| policy_key.WriteValue(GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(policy)) == ERROR_SUCCESS; |
| } |
| |
| GoogleUpdateSettings::UpdatePolicy GetGlobalUpdatePolicy() { |
| RegKey policy_key; |
| DWORD value; |
| return (policy_key.Create(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_QUERY_VALUE) == ERROR_SUCCESS && |
| policy_key.ReadValueDW(GoogleUpdateSettings::kUpdatePolicyValue, |
| &value) == ERROR_SUCCESS) ? |
| static_cast<GoogleUpdateSettings::UpdatePolicy>(value) : |
| GoogleUpdateSettings::UPDATE_POLICIES_COUNT; |
| } |
| |
| bool SetUpdateTimeoutOverride(DWORD time_in_minutes) { |
| RegKey policy_key; |
| return policy_key.Create(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE) == ERROR_SUCCESS && |
| policy_key.WriteValue( |
| GoogleUpdateSettings::kCheckPeriodOverrideMinutes, |
| time_in_minutes) == ERROR_SUCCESS; |
| } |
| |
| // Path overrides so that SHGetFolderPath isn't needed after the registry |
| // is overridden. |
| base::ScopedPathOverride program_files_override_; |
| base::ScopedPathOverride program_files_x86_override_; |
| registry_util::RegistryOverrideManager registry_overrides_; |
| }; |
| |
| } // namespace |
| |
| // Verify that we return success on no registration (which means stable), |
| // whether per-system or per-user install. |
| TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelAbsent) { |
| // Per-system first. |
| base::string16 channel; |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true, |
| &channel)); |
| EXPECT_STREQ(L"", channel.c_str()); |
| |
| // Then per-user. |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, |
| &channel)); |
| EXPECT_STREQ(L"", channel.c_str()); |
| } |
| |
| // Test an empty Ap key for system and user. |
| TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptySystem) { |
| SetApField(SYSTEM_INSTALL, L""); |
| base::string16 channel; |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true, |
| &channel)); |
| EXPECT_STREQ(L"", channel.c_str()); |
| |
| // Per-user lookups still succeed and return empty string. |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, |
| &channel)); |
| EXPECT_STREQ(L"", channel.c_str()); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptyUser) { |
| SetApField(USER_INSTALL, L""); |
| // Per-system lookups still succeed and return empty string. |
| base::string16 channel; |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true, |
| &channel)); |
| EXPECT_STREQ(L"", channel.c_str()); |
| |
| // Per-user lookup should succeed. |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, |
| &channel)); |
| EXPECT_STREQ(L"", channel.c_str()); |
| } |
| |
| // Test that the channel is pulled from the binaries for multi-install products. |
| TEST_F(GoogleUpdateSettingsTest, MultiInstallChannelFromBinaries) { |
| SetMultiApField(USER_INSTALL, L"2.0-dev-multi-chrome"); |
| base::string16 channel; |
| |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, |
| &channel)); |
| EXPECT_STREQ(L"dev-m", channel.c_str()); |
| |
| // See if the same happens if the product's ap is cleared. |
| SetApField(USER_INSTALL, L""); |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, |
| &channel)); |
| EXPECT_STREQ(L"dev-m", channel.c_str()); |
| |
| // Test the converse (binaries are stable, Chrome is other). |
| SetMultiApField(USER_INSTALL, L"-multi-chrome"); |
| SetApField(USER_INSTALL, L"2.0-dev-multi-chrome"); |
| EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, |
| &channel)); |
| EXPECT_STREQ(L"m", channel.c_str()); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesSystem) { |
| TestCurrentChromeChannelWithVariousApValues(SYSTEM_INSTALL); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesUser) { |
| TestCurrentChromeChannelWithVariousApValues(USER_INSTALL); |
| } |
| |
| // Run through all combinations of diff vs. full install, single vs. multi |
| // install, success and failure results, and a fistful of initial "ap" values |
| // checking that the expected final "ap" value is generated by |
| // GoogleUpdateSettings::UpdateGoogleUpdateApKey. |
| TEST_F(GoogleUpdateSettingsTest, UpdateGoogleUpdateApKey) { |
| const installer::ArchiveType archive_types[] = { |
| installer::UNKNOWN_ARCHIVE_TYPE, |
| installer::FULL_ARCHIVE_TYPE, |
| installer::INCREMENTAL_ARCHIVE_TYPE |
| }; |
| const int results[] = { |
| installer::FIRST_INSTALL_SUCCESS, |
| installer::INSTALL_FAILED |
| }; |
| const wchar_t* const plain[] = { |
| L"", |
| L"1.1", |
| L"1.1-dev" |
| }; |
| const wchar_t* const full[] = { |
| L"-full", |
| L"1.1-full", |
| L"1.1-dev-full" |
| }; |
| COMPILE_ASSERT(arraysize(full) == arraysize(plain), bad_full_array_size); |
| const wchar_t* const multifail[] = { |
| L"-multifail", |
| L"1.1-multifail", |
| L"1.1-dev-multifail" |
| }; |
| COMPILE_ASSERT(arraysize(multifail) == arraysize(plain), |
| bad_multifail_array_size); |
| const wchar_t* const multifail_full[] = { |
| L"-multifail-full", |
| L"1.1-multifail-full", |
| L"1.1-dev-multifail-full" |
| }; |
| COMPILE_ASSERT(arraysize(multifail_full) == arraysize(plain), |
| bad_multifail_full_array_size); |
| const wchar_t* const* input_arrays[] = { |
| plain, |
| full, |
| multifail, |
| multifail_full |
| }; |
| ChannelInfo v; |
| for (int type_idx = 0; type_idx < arraysize(archive_types); ++type_idx) { |
| const installer::ArchiveType archive_type = archive_types[type_idx]; |
| for (int result_idx = 0; result_idx < arraysize(results); ++result_idx) { |
| const int result = results[result_idx]; |
| // The archive type will/must always be known on install success. |
| if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE && |
| result == installer::FIRST_INSTALL_SUCCESS) { |
| continue; |
| } |
| const wchar_t* const* outputs = NULL; |
| if (result == installer::FIRST_INSTALL_SUCCESS || |
| archive_type == installer::FULL_ARCHIVE_TYPE) { |
| outputs = plain; |
| } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) { |
| outputs = full; |
| } // else if (archive_type == UNKNOWN) see below |
| |
| for (int inputs_idx = 0; inputs_idx < arraysize(input_arrays); |
| ++inputs_idx) { |
| const wchar_t* const* inputs = input_arrays[inputs_idx]; |
| if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE) { |
| // "-full" is untouched if the archive type is unknown. |
| // "-multifail" is unconditionally removed. |
| if (inputs == full || inputs == multifail_full) |
| outputs = full; |
| else |
| outputs = plain; |
| } |
| for (int input_idx = 0; input_idx < arraysize(plain); ++input_idx) { |
| const wchar_t* input = inputs[input_idx]; |
| const wchar_t* output = outputs[input_idx]; |
| |
| v.set_value(input); |
| if (output == v.value()) { |
| EXPECT_FALSE(GoogleUpdateSettings::UpdateGoogleUpdateApKey( |
| archive_type, result, &v)) |
| << "archive_type: " << archive_type |
| << ", result: " << result |
| << ", input ap value: " << input; |
| } else { |
| EXPECT_TRUE(GoogleUpdateSettings::UpdateGoogleUpdateApKey( |
| archive_type, result, &v)) |
| << "archive_type: " << archive_type |
| << ", result: " << result |
| << ", input ap value: " << input; |
| } |
| EXPECT_EQ(output, v.value()) |
| << "archive_type: " << archive_type |
| << ", result: " << result |
| << ", input ap value: " << input; |
| } |
| } |
| } |
| } |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) { |
| scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); |
| // Test incremental install failure |
| ASSERT_TRUE(CreateApKey(work_item_list.get(), L"")) |
| << "Failed to create ap key."; |
| GoogleUpdateSettings::UpdateInstallStatus(false, |
| installer::INCREMENTAL_ARCHIVE_TYPE, |
| installer::INSTALL_FAILED, |
| kTestProductGuid); |
| EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full"); |
| work_item_list->Rollback(); |
| |
| work_item_list.reset(WorkItem::CreateWorkItemList()); |
| // Test incremental install success |
| ASSERT_TRUE(CreateApKey(work_item_list.get(), L"")) |
| << "Failed to create ap key."; |
| GoogleUpdateSettings::UpdateInstallStatus(false, |
| installer::INCREMENTAL_ARCHIVE_TYPE, |
| installer::FIRST_INSTALL_SUCCESS, |
| kTestProductGuid); |
| EXPECT_STREQ(ReadApKeyValue().c_str(), L""); |
| work_item_list->Rollback(); |
| |
| work_item_list.reset(WorkItem::CreateWorkItemList()); |
| // Test full install failure |
| ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full")) |
| << "Failed to create ap key."; |
| GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, |
| installer::INSTALL_FAILED, |
| kTestProductGuid); |
| EXPECT_STREQ(ReadApKeyValue().c_str(), L""); |
| work_item_list->Rollback(); |
| |
| work_item_list.reset(WorkItem::CreateWorkItemList()); |
| // Test full install success |
| ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full")) |
| << "Failed to create ap key."; |
| GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, |
| installer::FIRST_INSTALL_SUCCESS, |
| kTestProductGuid); |
| EXPECT_STREQ(ReadApKeyValue().c_str(), L""); |
| work_item_list->Rollback(); |
| |
| work_item_list.reset(WorkItem::CreateWorkItemList()); |
| // Test the case of when "ap" key doesnt exist at all |
| base::string16 ap_key_value = ReadApKeyValue(); |
| base::string16 reg_key = GetApKeyPath(); |
| HKEY reg_root = HKEY_CURRENT_USER; |
| bool ap_key_deleted = false; |
| RegKey key; |
| if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) != |
| ERROR_SUCCESS) { |
| work_item_list->AddCreateRegKeyWorkItem( |
| reg_root, reg_key, WorkItem::kWow64Default); |
| ASSERT_TRUE(work_item_list->Do()) << "Failed to create ClientState key."; |
| } else if (key.DeleteValue(google_update::kRegApField) == ERROR_SUCCESS) { |
| ap_key_deleted = true; |
| } |
| // try differential installer |
| GoogleUpdateSettings::UpdateInstallStatus(false, |
| installer::INCREMENTAL_ARCHIVE_TYPE, |
| installer::INSTALL_FAILED, |
| kTestProductGuid); |
| EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full"); |
| // try full installer now |
| GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, |
| installer::INSTALL_FAILED, |
| kTestProductGuid); |
| EXPECT_STREQ(ReadApKeyValue().c_str(), L""); |
| // Now cleanup to leave the system in unchanged state. |
| // - Diff installer creates an ap key if it didnt exist, so delete this ap key |
| // - If we created any reg key path for ap, roll it back |
| // - Finally restore the original value of ap key. |
| key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS); |
| key.DeleteValue(google_update::kRegApField); |
| work_item_list->Rollback(); |
| if (ap_key_deleted) { |
| work_item_list.reset(WorkItem::CreateWorkItemList()); |
| ASSERT_TRUE(CreateApKey(work_item_list.get(), ap_key_value)) |
| << "Failed to restore ap key."; |
| } |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, SetEULAConsent) { |
| using installer::FakeInstallationState; |
| |
| const bool multi_install = true; |
| const bool system_level = true; |
| FakeInstallationState machine_state; |
| |
| // Chrome is installed. |
| machine_state.AddChrome(system_level, multi_install, |
| new Version(chrome::kChromeVersion)); |
| |
| RegKey key; |
| DWORD value; |
| BrowserDistribution* binaries = |
| BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BINARIES); |
| BrowserDistribution* chrome = |
| BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BROWSER); |
| |
| // eulaconsent is set on both the product and the binaries. |
| EXPECT_TRUE(GoogleUpdateSettings::SetEULAConsent(machine_state, chrome, |
| true)); |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.Open(HKEY_LOCAL_MACHINE, binaries->GetStateMediumKey().c_str(), |
| KEY_QUERY_VALUE)); |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.ReadValueDW(google_update::kRegEULAAceptedField, &value)); |
| EXPECT_EQ(1U, value); |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.Open(HKEY_LOCAL_MACHINE, chrome->GetStateMediumKey().c_str(), |
| KEY_QUERY_VALUE)); |
| EXPECT_EQ(ERROR_SUCCESS, |
| key.ReadValueDW(google_update::kRegEULAAceptedField, &value)); |
| EXPECT_EQ(1U, value); |
| } |
| |
| // Test that the appropriate default is returned if no update override is |
| // present. |
| TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyNoOverride) { |
| // There are no policies at all. |
| EXPECT_EQ(ERROR_FILE_NOT_FOUND, |
| RegKey().Open(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_QUERY_VALUE)); |
| bool is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::kDefaultUpdatePolicy, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| |
| // The policy key exists, but there are no values of interest present. |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey().Create(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE)); |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey().Open(HKEY_LOCAL_MACHINE, |
| GoogleUpdateSettings::kPoliciesKey, |
| KEY_QUERY_VALUE)); |
| is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::kDefaultUpdatePolicy, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, UpdateProfileCountsSystemInstall) { |
| // Override FILE_MODULE and FILE_EXE with a path somewhere in the default |
| // system-level install location so that |
| // GoogleUpdateSettings::IsSystemInstall() returns true. |
| base::FilePath file_exe; |
| ASSERT_TRUE(PathService::Get(base::FILE_EXE, &file_exe)); |
| base::FilePath install_dir(installer::GetChromeInstallPath( |
| true /* system_install */, BrowserDistribution::GetDistribution())); |
| file_exe = install_dir.Append(file_exe.BaseName()); |
| base::ScopedPathOverride file_module_override( |
| base::FILE_MODULE, file_exe, true /* is_absolute */, false /* create */); |
| base::ScopedPathOverride file_exe_override( |
| base::FILE_EXE, file_exe, true /* is_absolute */, false /* create */); |
| |
| // No profile count keys present yet. |
| const base::string16& state_key = BrowserDistribution::GetDistribution()-> |
| GetAppRegistrationData().GetStateMediumKey(); |
| base::string16 num_profiles_path(state_key); |
| num_profiles_path.append(L"\\"); |
| num_profiles_path.append(google_update::kRegProfilesActive); |
| base::string16 num_signed_in_path(state_key); |
| num_signed_in_path.append(L"\\"); |
| num_signed_in_path.append(google_update::kRegProfilesSignedIn); |
| |
| EXPECT_EQ(ERROR_FILE_NOT_FOUND, |
| RegKey().Open(HKEY_LOCAL_MACHINE, |
| num_profiles_path.c_str(), |
| KEY_QUERY_VALUE)); |
| EXPECT_EQ(ERROR_FILE_NOT_FOUND, |
| RegKey().Open(HKEY_LOCAL_MACHINE, |
| num_signed_in_path.c_str(), |
| KEY_QUERY_VALUE)); |
| |
| // Show time! Write the values. |
| GoogleUpdateSettings::UpdateProfileCounts(3, 2); |
| |
| // Verify the keys were created. |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey().Open(HKEY_LOCAL_MACHINE, |
| num_profiles_path.c_str(), |
| KEY_QUERY_VALUE)); |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey().Open(HKEY_LOCAL_MACHINE, |
| num_signed_in_path.c_str(), |
| KEY_QUERY_VALUE)); |
| |
| base::string16 uniquename; |
| EXPECT_TRUE(base::win::GetUserSidString(&uniquename)); |
| |
| // Verify the values are accessible. |
| DWORD num_profiles = 0; |
| DWORD num_signed_in = 0; |
| base::string16 aggregate; |
| EXPECT_EQ( |
| ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, num_profiles_path.c_str(), |
| KEY_QUERY_VALUE).ReadValueDW(uniquename.c_str(), |
| &num_profiles)); |
| EXPECT_EQ( |
| ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, num_signed_in_path.c_str(), |
| KEY_QUERY_VALUE).ReadValueDW(uniquename.c_str(), |
| &num_signed_in)); |
| EXPECT_EQ( |
| ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, num_signed_in_path.c_str(), |
| KEY_QUERY_VALUE).ReadValue(google_update::kRegAggregateMethod, |
| &aggregate)); |
| |
| // Verify the correct values were written. |
| EXPECT_EQ(3, num_profiles); |
| EXPECT_EQ(2, num_signed_in); |
| EXPECT_EQ(L"sum()", aggregate); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, UpdateProfileCountsUserInstall) { |
| // Unit tests never operate as an installed application, so will never |
| // be a system install. |
| |
| // No profile count values present yet. |
| const base::string16& state_key = BrowserDistribution::GetDistribution()-> |
| GetAppRegistrationData().GetStateKey(); |
| |
| EXPECT_EQ(ERROR_FILE_NOT_FOUND, |
| RegKey().Open(HKEY_CURRENT_USER, |
| state_key.c_str(), |
| KEY_QUERY_VALUE)); |
| |
| // Show time! Write the values. |
| GoogleUpdateSettings::UpdateProfileCounts(4, 1); |
| |
| // Verify the key was created. |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey().Open(HKEY_CURRENT_USER, |
| state_key.c_str(), |
| KEY_QUERY_VALUE)); |
| |
| // Verify the values are accessible. |
| base::string16 num_profiles; |
| base::string16 num_signed_in; |
| EXPECT_EQ( |
| ERROR_SUCCESS, |
| RegKey(HKEY_CURRENT_USER, state_key.c_str(), KEY_QUERY_VALUE). |
| ReadValue(google_update::kRegProfilesActive, &num_profiles)); |
| EXPECT_EQ( |
| ERROR_SUCCESS, |
| RegKey(HKEY_CURRENT_USER, state_key.c_str(), KEY_QUERY_VALUE). |
| ReadValue(google_update::kRegProfilesSignedIn, &num_signed_in)); |
| |
| // Verify the correct values were written. |
| EXPECT_EQ(L"4", num_profiles); |
| EXPECT_EQ(L"1", num_signed_in); |
| } |
| |
| #if defined(GOOGLE_CHROME_BUILD) |
| |
| // Test that the default override is returned if no app-specific override is |
| // present. |
| TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyDefaultOverride) { |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(0))); |
| bool is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(1))); |
| is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(2))); |
| is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(3))); |
| is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::AUTO_UPDATES_ONLY, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| |
| // The default policy should be in force for bogus values. |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(4))); |
| is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::kDefaultUpdatePolicy, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| } |
| |
| // Test that an app-specific override is used if present. |
| TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyAppOverride) { |
| base::string16 app_policy_value( |
| GoogleUpdateSettings::kUpdateOverrideValuePrefix); |
| app_policy_value.append(kTestProductGuid); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(1))); |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), |
| static_cast<DWORD>(0))); |
| bool is_overridden = false; |
| EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_TRUE(is_overridden); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue( |
| GoogleUpdateSettings::kUpdatePolicyValue, |
| static_cast<DWORD>(0))); |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), |
| static_cast<DWORD>(1))); |
| is_overridden = false; |
| EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_TRUE(is_overridden); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), |
| static_cast<DWORD>(2))); |
| is_overridden = false; |
| EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_TRUE(is_overridden); |
| |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), |
| static_cast<DWORD>(3))); |
| is_overridden = false; |
| EXPECT_EQ(GoogleUpdateSettings::AUTO_UPDATES_ONLY, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_TRUE(is_overridden); |
| |
| // The default policy should be in force for bogus values. |
| EXPECT_EQ(ERROR_SUCCESS, |
| RegKey(HKEY_LOCAL_MACHINE, GoogleUpdateSettings::kPoliciesKey, |
| KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), |
| static_cast<DWORD>(4))); |
| is_overridden = true; |
| EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, |
| GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, |
| &is_overridden)); |
| EXPECT_FALSE(is_overridden); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, PerAppUpdatesDisabledByPolicy) { |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| EXPECT_TRUE( |
| SetUpdatePolicyForAppGuid(dist->GetAppGuid(), |
| GoogleUpdateSettings::UPDATES_DISABLED)); |
| bool is_overridden = false; |
| GoogleUpdateSettings::UpdatePolicy update_policy = |
| GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(), |
| &is_overridden); |
| EXPECT_TRUE(is_overridden); |
| EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, update_policy); |
| EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| |
| EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates()); |
| update_policy = GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(), |
| &is_overridden); |
| // Should still have a policy but now that policy should explicitly enable |
| // updates. |
| EXPECT_TRUE(is_overridden); |
| EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, update_policy); |
| EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, PerAppUpdatesEnabledWithGlobalDisabled) { |
| // Disable updates globally but enable them for Chrome (the app-specific |
| // setting should take precedence). |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| BrowserDistribution* binaries = BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BINARIES); |
| EXPECT_TRUE( |
| SetUpdatePolicyForAppGuid(dist->GetAppGuid(), |
| GoogleUpdateSettings::AUTOMATIC_UPDATES)); |
| EXPECT_TRUE( |
| SetUpdatePolicyForAppGuid(binaries->GetAppGuid(), |
| GoogleUpdateSettings::AUTOMATIC_UPDATES)); |
| EXPECT_TRUE(SetGlobalUpdatePolicy(GoogleUpdateSettings::UPDATES_DISABLED)); |
| |
| // Make sure we read this as still having updates enabled. |
| EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| |
| // Make sure that the reset action returns true and is a no-op. |
| EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates()); |
| EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, |
| GetUpdatePolicyForAppGuid(dist->GetAppGuid())); |
| EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, |
| GetUpdatePolicyForAppGuid(binaries->GetAppGuid())); |
| EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, GetGlobalUpdatePolicy()); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, GlobalUpdatesDisabledByPolicy) { |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| EXPECT_TRUE(SetGlobalUpdatePolicy(GoogleUpdateSettings::UPDATES_DISABLED)); |
| bool is_overridden = false; |
| |
| // The contract for GetAppUpdatePolicy states that |is_overridden| should be |
| // set to false when updates are disabled on a non-app-specific basis. |
| GoogleUpdateSettings::UpdatePolicy update_policy = |
| GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(), |
| &is_overridden); |
| EXPECT_FALSE(is_overridden); |
| EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, update_policy); |
| EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| |
| EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates()); |
| update_policy = GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(), |
| &is_overridden); |
| // Policy should now be to enable updates, |is_overridden| should still be |
| // false. |
| EXPECT_FALSE(is_overridden); |
| EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, update_policy); |
| EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, UpdatesDisabledByTimeout) { |
| // Disable updates altogether. |
| EXPECT_TRUE(SetUpdateTimeoutOverride(0)); |
| EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates()); |
| EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| |
| // Set the update period to something unreasonable. |
| EXPECT_TRUE(SetUpdateTimeoutOverride( |
| GoogleUpdateSettings::kCheckPeriodOverrideMinutesMax + 1)); |
| EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates()); |
| EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled()); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperSystem) { |
| TestExperimentsLabelHelper(SYSTEM_INSTALL); |
| } |
| |
| TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperUser) { |
| TestExperimentsLabelHelper(USER_INSTALL); |
| } |
| |
| #endif // defined(GOOGLE_CHROME_BUILD) |
| |
| // Test GoogleUpdateSettings::GetUninstallCommandLine at system- or user-level, |
| // according to the param. |
| class GetUninstallCommandLine : public GoogleUpdateSettingsTest, |
| public testing::WithParamInterface<bool> { |
| protected: |
| static const wchar_t kDummyCommand[]; |
| |
| void SetUp() override { |
| GoogleUpdateSettingsTest::SetUp(); |
| system_install_ = GetParam(); |
| root_key_ = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| } |
| |
| HKEY root_key_; |
| bool system_install_; |
| }; |
| |
| const wchar_t GetUninstallCommandLine::kDummyCommand[] = |
| L"\"goopdate.exe\" /spam"; |
| |
| // Tests that GetUninstallCommandLine returns an empty string if there's no |
| // Software\Google\Update key. |
| TEST_P(GetUninstallCommandLine, TestNoKey) { |
| EXPECT_EQ(base::string16(), |
| GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); |
| } |
| |
| // Tests that GetUninstallCommandLine returns an empty string if there's no |
| // UninstallCmdLine value in the Software\Google\Update key. |
| TEST_P(GetUninstallCommandLine, TestNoValue) { |
| RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE); |
| EXPECT_EQ(base::string16(), |
| GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); |
| } |
| |
| // Tests that GetUninstallCommandLine returns an empty string if there's an |
| // empty UninstallCmdLine value in the Software\Google\Update key. |
| TEST_P(GetUninstallCommandLine, TestEmptyValue) { |
| RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) |
| .WriteValue(google_update::kRegUninstallCmdLine, L""); |
| EXPECT_EQ(base::string16(), |
| GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); |
| } |
| |
| // Tests that GetUninstallCommandLine returns the correct string if there's an |
| // UninstallCmdLine value in the Software\Google\Update key. |
| TEST_P(GetUninstallCommandLine, TestRealValue) { |
| RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) |
| .WriteValue(google_update::kRegUninstallCmdLine, kDummyCommand); |
| EXPECT_EQ(base::string16(kDummyCommand), |
| GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); |
| // Make sure that there's no value in the other level (user or system). |
| EXPECT_EQ(base::string16(), |
| GoogleUpdateSettings::GetUninstallCommandLine(!system_install_)); |
| } |
| |
| INSTANTIATE_TEST_CASE_P(GetUninstallCommandLineAtLevel, GetUninstallCommandLine, |
| testing::Bool()); |
| |
| // Test GoogleUpdateSettings::GetGoogleUpdateVersion at system- or user-level, |
| // according to the param. |
| class GetGoogleUpdateVersion : public GoogleUpdateSettingsTest, |
| public testing::WithParamInterface<bool> { |
| protected: |
| static const wchar_t kDummyVersion[]; |
| |
| void SetUp() override { |
| GoogleUpdateSettingsTest::SetUp(); |
| system_install_ = GetParam(); |
| root_key_ = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| } |
| |
| HKEY root_key_; |
| bool system_install_; |
| }; |
| |
| const wchar_t GetGoogleUpdateVersion::kDummyVersion[] = L"1.2.3.4"; |
| |
| // Tests that GetGoogleUpdateVersion returns an empty string if there's no |
| // Software\Google\Update key. |
| TEST_P(GetGoogleUpdateVersion, TestNoKey) { |
| EXPECT_FALSE( |
| GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid()); |
| } |
| |
| // Tests that GetGoogleUpdateVersion returns an empty string if there's no |
| // version value in the Software\Google\Update key. |
| TEST_P(GetGoogleUpdateVersion, TestNoValue) { |
| RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE); |
| EXPECT_FALSE( |
| GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid()); |
| } |
| |
| // Tests that GetGoogleUpdateVersion returns an empty string if there's an |
| // empty version value in the Software\Google\Update key. |
| TEST_P(GetGoogleUpdateVersion, TestEmptyValue) { |
| RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) |
| .WriteValue(google_update::kRegGoogleUpdateVersion, L""); |
| EXPECT_FALSE( |
| GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid()); |
| } |
| |
| // Tests that GetGoogleUpdateVersion returns the correct string if there's a |
| // version value in the Software\Google\Update key. |
| TEST_P(GetGoogleUpdateVersion, TestRealValue) { |
| RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) |
| .WriteValue(google_update::kRegGoogleUpdateVersion, kDummyVersion); |
| Version expected(base::UTF16ToUTF8(kDummyVersion)); |
| EXPECT_TRUE(expected.Equals( |
| GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_))); |
| // Make sure that there's no value in the other level (user or system). |
| EXPECT_FALSE( |
| GoogleUpdateSettings::GetGoogleUpdateVersion(!system_install_) |
| .IsValid()); |
| } |
| |
| INSTANTIATE_TEST_CASE_P(GetGoogleUpdateVersionAtLevel, GetGoogleUpdateVersion, |
| testing::Bool()); |
| |
| // Test values for use by the CollectStatsConsent test fixture. |
| class StatsState { |
| public: |
| enum InstallType { |
| SINGLE_INSTALL, |
| MULTI_INSTALL, |
| }; |
| enum StateSetting { |
| NO_SETTING, |
| FALSE_SETTING, |
| TRUE_SETTING, |
| }; |
| struct UserLevelState {}; |
| struct SystemLevelState {}; |
| static const UserLevelState kUserLevel; |
| static const SystemLevelState kSystemLevel; |
| |
| StatsState(const UserLevelState&, |
| InstallType install_type, |
| StateSetting state_value) |
| : system_level_(false), |
| multi_install_(install_type == MULTI_INSTALL), |
| state_value_(state_value), |
| state_medium_value_(NO_SETTING) { |
| } |
| StatsState(const SystemLevelState&, |
| InstallType install_type, |
| StateSetting state_value, |
| StateSetting state_medium_value) |
| : system_level_(true), |
| multi_install_(install_type == MULTI_INSTALL), |
| state_value_(state_value), |
| state_medium_value_(state_medium_value) { |
| } |
| bool system_level() const { return system_level_; } |
| bool multi_install() const { return multi_install_; } |
| HKEY root_key() const { |
| return system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| } |
| StateSetting state_value() const { return state_value_; } |
| StateSetting state_medium_value() const { |
| return state_medium_value_; |
| } |
| bool is_consent_granted() const { |
| return (system_level_ && state_medium_value_ != NO_SETTING) ? |
| (state_medium_value_ == TRUE_SETTING) : |
| (state_value_ == TRUE_SETTING); |
| } |
| |
| private: |
| bool system_level_; |
| bool multi_install_; |
| StateSetting state_value_; |
| StateSetting state_medium_value_; |
| }; |
| |
| const StatsState::UserLevelState StatsState::kUserLevel = {}; |
| const StatsState::SystemLevelState StatsState::kSystemLevel = {}; |
| |
| // A value parameterized test for testing the stats collection consent setting. |
| class CollectStatsConsent : public ::testing::TestWithParam<StatsState> { |
| public: |
| static void SetUpTestCase(); |
| static void TearDownTestCase(); |
| protected: |
| void SetUp() override; |
| static void MakeChromeMultiInstall(HKEY root_key); |
| static void ApplySetting(StatsState::StateSetting setting, |
| HKEY root_key, |
| const base::string16& reg_key); |
| |
| static base::string16* chrome_version_key_; |
| static base::string16* chrome_state_key_; |
| static base::string16* chrome_state_medium_key_; |
| static base::string16* binaries_state_key_; |
| static base::string16* binaries_state_medium_key_; |
| registry_util::RegistryOverrideManager override_manager_; |
| }; |
| |
| base::string16* CollectStatsConsent::chrome_version_key_; |
| base::string16* CollectStatsConsent::chrome_state_key_; |
| base::string16* CollectStatsConsent::chrome_state_medium_key_; |
| base::string16* CollectStatsConsent::binaries_state_key_; |
| base::string16* CollectStatsConsent::binaries_state_medium_key_; |
| |
| void CollectStatsConsent::SetUpTestCase() { |
| BrowserDistribution* dist = |
| BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BROWSER); |
| chrome_version_key_ = new base::string16(dist->GetVersionKey()); |
| chrome_state_key_ = new base::string16(dist->GetStateKey()); |
| chrome_state_medium_key_ = new base::string16(dist->GetStateMediumKey()); |
| |
| dist = BrowserDistribution::GetSpecificDistribution( |
| BrowserDistribution::CHROME_BINARIES); |
| binaries_state_key_ = new base::string16(dist->GetStateKey()); |
| binaries_state_medium_key_ = new base::string16(dist->GetStateMediumKey()); |
| } |
| |
| void CollectStatsConsent::TearDownTestCase() { |
| delete chrome_version_key_; |
| delete chrome_state_key_; |
| delete chrome_state_medium_key_; |
| delete binaries_state_key_; |
| delete binaries_state_medium_key_; |
| } |
| |
| // Install the registry override and apply the settings to the registry. |
| void CollectStatsConsent::SetUp() { |
| const StatsState& stats_state = GetParam(); |
| const HKEY root_key = stats_state.root_key(); |
| base::string16 reg_temp_name( |
| stats_state.system_level() ? L"HKLM_" : L"HKCU_"); |
| reg_temp_name += L"CollectStatsConsent"; |
| override_manager_.OverrideRegistry(root_key); |
| |
| if (stats_state.multi_install()) { |
| MakeChromeMultiInstall(root_key); |
| ApplySetting(stats_state.state_value(), root_key, *binaries_state_key_); |
| ApplySetting(stats_state.state_medium_value(), root_key, |
| *binaries_state_medium_key_); |
| } else { |
| ApplySetting(stats_state.state_value(), root_key, *chrome_state_key_); |
| ApplySetting(stats_state.state_medium_value(), root_key, |
| *chrome_state_medium_key_); |
| } |
| } |
| |
| // Write values into the registry so that Chrome is considered to be installed |
| // as multi-install. |
| void CollectStatsConsent::MakeChromeMultiInstall(HKEY root_key) { |
| ASSERT_EQ( |
| ERROR_SUCCESS, |
| RegKey(root_key, chrome_version_key_->c_str(), |
| KEY_SET_VALUE).WriteValue(google_update::kRegVersionField, |
| L"1.2.3.4")); |
| ASSERT_EQ( |
| ERROR_SUCCESS, |
| RegKey(root_key, chrome_state_key_->c_str(), |
| KEY_SET_VALUE).WriteValue(installer::kUninstallArgumentsField, |
| L"--multi-install")); |
| } |
| |
| // Write the correct value to represent |setting| in the registry. |
| void CollectStatsConsent::ApplySetting(StatsState::StateSetting setting, |
| HKEY root_key, |
| const base::string16& reg_key) { |
| if (setting != StatsState::NO_SETTING) { |
| DWORD value = setting != StatsState::FALSE_SETTING ? 1 : 0; |
| ASSERT_EQ( |
| ERROR_SUCCESS, |
| RegKey(root_key, reg_key.c_str(), |
| KEY_SET_VALUE).WriteValue(google_update::kRegUsageStatsField, |
| value)); |
| } |
| } |
| |
| // Test that stats consent can be read. |
| TEST_P(CollectStatsConsent, GetCollectStatsConsentAtLevel) { |
| if (GetParam().is_consent_granted()) { |
| EXPECT_TRUE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( |
| GetParam().system_level())); |
| } else { |
| EXPECT_FALSE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( |
| GetParam().system_level())); |
| } |
| } |
| |
| // Test that stats consent can be flipped to the opposite setting, that the new |
| // setting takes affect, and that the correct registry location is modified. |
| TEST_P(CollectStatsConsent, SetCollectStatsConsentAtLevel) { |
| EXPECT_TRUE(GoogleUpdateSettings::SetCollectStatsConsentAtLevel( |
| GetParam().system_level(), |
| !GetParam().is_consent_granted())); |
| const base::string16* const reg_keys[] = { |
| chrome_state_key_, |
| chrome_state_medium_key_, |
| binaries_state_key_, |
| binaries_state_medium_key_, |
| }; |
| int key_index = ((GetParam().system_level() ? 1 : 0) + |
| (GetParam().multi_install() ? 2 : 0)); |
| const base::string16& reg_key = *reg_keys[key_index]; |
| DWORD value = 0; |
| EXPECT_EQ( |
| ERROR_SUCCESS, |
| RegKey(GetParam().root_key(), reg_key.c_str(), |
| KEY_QUERY_VALUE).ReadValueDW(google_update::kRegUsageStatsField, |
| &value)); |
| if (GetParam().is_consent_granted()) { |
| EXPECT_FALSE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( |
| GetParam().system_level())); |
| EXPECT_EQ(0UL, value); |
| } else { |
| EXPECT_TRUE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( |
| GetParam().system_level())); |
| EXPECT_EQ(1UL, value); |
| } |
| } |
| |
| INSTANTIATE_TEST_CASE_P( |
| UserLevelSingleInstall, |
| CollectStatsConsent, |
| ::testing::Values( |
| StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL, |
| StatsState::NO_SETTING), |
| StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL, |
| StatsState::FALSE_SETTING), |
| StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL, |
| StatsState::TRUE_SETTING))); |
| INSTANTIATE_TEST_CASE_P( |
| UserLevelMultiInstall, |
| CollectStatsConsent, |
| ::testing::Values( |
| StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL, |
| StatsState::NO_SETTING), |
| StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL, |
| StatsState::FALSE_SETTING), |
| StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL, |
| StatsState::TRUE_SETTING))); |
| INSTANTIATE_TEST_CASE_P( |
| SystemLevelSingleInstall, |
| CollectStatsConsent, |
| ::testing::Values( |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::NO_SETTING, StatsState::NO_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::NO_SETTING, StatsState::FALSE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::NO_SETTING, StatsState::TRUE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::FALSE_SETTING, StatsState::NO_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::FALSE_SETTING, StatsState::FALSE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::FALSE_SETTING, StatsState::TRUE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::TRUE_SETTING, StatsState::NO_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::TRUE_SETTING, StatsState::FALSE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, |
| StatsState::TRUE_SETTING, StatsState::TRUE_SETTING))); |
| INSTANTIATE_TEST_CASE_P( |
| SystemLevelMultiInstall, |
| CollectStatsConsent, |
| ::testing::Values( |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::NO_SETTING, StatsState::NO_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::NO_SETTING, StatsState::FALSE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::NO_SETTING, StatsState::TRUE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::FALSE_SETTING, StatsState::NO_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::FALSE_SETTING, StatsState::FALSE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::FALSE_SETTING, StatsState::TRUE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::TRUE_SETTING, StatsState::NO_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::TRUE_SETTING, StatsState::FALSE_SETTING), |
| StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, |
| StatsState::TRUE_SETTING, StatsState::TRUE_SETTING))); |