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. 4 5 #include <string> 6 7 #include "base/basictypes.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/time/time.h" 10 #include "base/win/registry.h" 11 #include "chrome/installer/gcapi/gcapi.h" 12 #include "chrome/installer/gcapi/gcapi_omaha_experiment.h" 13 #include "chrome/installer/gcapi/gcapi_reactivation.h" 14 #include "chrome/installer/gcapi/gcapi_test_registry_overrider.h" 15 #include "chrome/installer/util/google_update_constants.h" 16 #include "chrome/installer/util/google_update_experiment_util.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 using base::Time; 20 using base::TimeDelta; 21 using base::win::RegKey; 22 23 class GCAPIReactivationTest : public ::testing::Test { 24 protected: 25 GCAPIReactivationTest() {} 26 27 bool SetChromeInstallMarker(HKEY hive) { 28 // Create the client state keys in the right places. 29 std::wstring reg_path(google_update::kRegPathClients); 30 reg_path += L"\\"; 31 reg_path += google_update::kChromeUpgradeCode; 32 RegKey client_state(hive, 33 reg_path.c_str(), 34 KEY_CREATE_SUB_KEY | KEY_SET_VALUE | KEY_WOW64_32KEY); 35 return (client_state.Valid() && 36 client_state.WriteValue( 37 google_update::kRegVersionField, L"1.2.3.4") == ERROR_SUCCESS); 38 } 39 40 bool SetLastRunTime(HKEY hive, int64 last_run_time) { 41 return SetLastRunTimeString(hive, base::Int64ToString16(last_run_time)); 42 } 43 44 bool SetLastRunTimeString(HKEY hive, 45 const base::string16& last_run_time_string) { 46 const wchar_t* base_path = 47 (hive == HKEY_LOCAL_MACHINE) ? 48 google_update::kRegPathClientStateMedium : 49 google_update::kRegPathClientState; 50 std::wstring path(base_path); 51 path += L"\\"; 52 path += google_update::kChromeUpgradeCode; 53 54 RegKey client_state(hive, path.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY); 55 return (client_state.Valid() && 56 client_state.WriteValue( 57 google_update::kRegLastRunTimeField, 58 last_run_time_string.c_str()) == ERROR_SUCCESS); 59 } 60 61 bool HasExperimentLabels(HKEY hive) { 62 base::string16 client_state_path(google_update::kRegPathClientState); 63 client_state_path.push_back(L'\\'); 64 client_state_path.append(google_update::kChromeUpgradeCode); 65 66 RegKey client_state_key(hive, 67 client_state_path.c_str(), 68 KEY_QUERY_VALUE | KEY_WOW64_32KEY); 69 return client_state_key.Valid() && 70 client_state_key.HasValue(google_update::kExperimentLabels); 71 } 72 73 std::wstring GetReactivationString(HKEY hive) { 74 const wchar_t* base_path = 75 (hive == HKEY_LOCAL_MACHINE) ? 76 google_update::kRegPathClientStateMedium : 77 google_update::kRegPathClientState; 78 std::wstring path(base_path); 79 path += L"\\"; 80 path += google_update::kChromeUpgradeCode; 81 82 RegKey client_state(hive, path.c_str(), KEY_QUERY_VALUE | KEY_WOW64_32KEY); 83 if (client_state.Valid()) { 84 std::wstring actual_brand; 85 if (client_state.ReadValue(google_update::kRegRLZReactivationBrandField, 86 &actual_brand) == ERROR_SUCCESS) { 87 return actual_brand; 88 } 89 } 90 91 return L"ERROR"; 92 } 93 94 const GCAPITestRegistryOverrider gcapi_test_registry_overrider_; 95 }; 96 97 TEST_F(GCAPIReactivationTest, CheckSetReactivationBrandCode) { 98 EXPECT_TRUE(SetReactivationBrandCode(L"GAGA", GCAPI_INVOKED_STANDARD_SHELL)); 99 EXPECT_EQ(L"GAGA", GetReactivationString(HKEY_CURRENT_USER)); 100 101 EXPECT_TRUE(HasBeenReactivated()); 102 } 103 104 TEST_F(GCAPIReactivationTest, CanOfferReactivation_Basic) { 105 DWORD error; 106 107 // We're not installed yet. Make sure CanOfferReactivation fails. 108 EXPECT_FALSE(CanOfferReactivation(L"GAGA", 109 GCAPI_INVOKED_STANDARD_SHELL, 110 &error)); 111 EXPECT_EQ(REACTIVATE_ERROR_NOTINSTALLED, error); 112 113 // Now pretend to be installed. CanOfferReactivation should pass. 114 EXPECT_TRUE(SetChromeInstallMarker(HKEY_CURRENT_USER)); 115 EXPECT_TRUE(CanOfferReactivation(L"GAGA", 116 GCAPI_INVOKED_STANDARD_SHELL, 117 &error)); 118 119 // Now set a recent last_run value. CanOfferReactivation should fail again. 120 Time hkcu_last_run = Time::NowFromSystemTime() - TimeDelta::FromDays(20); 121 EXPECT_TRUE(SetLastRunTime(HKEY_CURRENT_USER, 122 hkcu_last_run.ToInternalValue())); 123 EXPECT_FALSE(CanOfferReactivation(L"GAGA", 124 GCAPI_INVOKED_STANDARD_SHELL, 125 &error)); 126 EXPECT_EQ(REACTIVATE_ERROR_NOTDORMANT, error); 127 128 // Now set a last_run value that exceeds the threshold. 129 hkcu_last_run = Time::NowFromSystemTime() - 130 TimeDelta::FromDays(kReactivationMinDaysDormant); 131 EXPECT_TRUE(SetLastRunTime(HKEY_CURRENT_USER, 132 hkcu_last_run.ToInternalValue())); 133 EXPECT_TRUE(CanOfferReactivation(L"GAGA", 134 GCAPI_INVOKED_STANDARD_SHELL, 135 &error)); 136 137 // Test some invalid inputs 138 EXPECT_FALSE(CanOfferReactivation(NULL, 139 GCAPI_INVOKED_STANDARD_SHELL, 140 &error)); 141 EXPECT_EQ(REACTIVATE_ERROR_INVALID_INPUT, error); 142 143 // One more valid one 144 EXPECT_TRUE(CanOfferReactivation(L"GAGA", 145 GCAPI_INVOKED_STANDARD_SHELL, 146 &error)); 147 148 // Check that the previous brands check works: 149 EXPECT_TRUE(SetReactivationBrandCode(L"GOOGOO", 150 GCAPI_INVOKED_STANDARD_SHELL)); 151 EXPECT_FALSE(CanOfferReactivation(L"GAGA", 152 GCAPI_INVOKED_STANDARD_SHELL, 153 &error)); 154 EXPECT_EQ(REACTIVATE_ERROR_ALREADY_REACTIVATED, error); 155 } 156 157 TEST_F(GCAPIReactivationTest, Reactivation_Flow) { 158 DWORD error; 159 160 // Set us up as a candidate for reactivation. 161 EXPECT_TRUE(SetChromeInstallMarker(HKEY_CURRENT_USER)); 162 163 Time hkcu_last_run = Time::NowFromSystemTime() - 164 TimeDelta::FromDays(kReactivationMinDaysDormant); 165 EXPECT_TRUE(SetLastRunTime(HKEY_CURRENT_USER, 166 hkcu_last_run.ToInternalValue())); 167 168 EXPECT_TRUE(ReactivateChrome(L"GAGA", 169 GCAPI_INVOKED_STANDARD_SHELL, 170 &error)); 171 EXPECT_EQ(L"GAGA", GetReactivationString(HKEY_CURRENT_USER)); 172 173 // Make sure we can't reactivate again: 174 EXPECT_FALSE(ReactivateChrome(L"GAGA", 175 GCAPI_INVOKED_STANDARD_SHELL, 176 &error)); 177 EXPECT_EQ(REACTIVATE_ERROR_ALREADY_REACTIVATED, error); 178 179 // Should not be able to reactivate under other brands: 180 EXPECT_FALSE(ReactivateChrome(L"MAMA", 181 GCAPI_INVOKED_STANDARD_SHELL, 182 &error)); 183 EXPECT_EQ(L"GAGA", GetReactivationString(HKEY_CURRENT_USER)); 184 185 // Validate that previous_brands are rejected: 186 EXPECT_FALSE(ReactivateChrome(L"PFFT", 187 GCAPI_INVOKED_STANDARD_SHELL, 188 &error)); 189 EXPECT_EQ(REACTIVATE_ERROR_ALREADY_REACTIVATED, error); 190 EXPECT_EQ(L"GAGA", GetReactivationString(HKEY_CURRENT_USER)); 191 } 192 193 TEST_F(GCAPIReactivationTest, ExperimentLabelCheck) { 194 DWORD error; 195 196 // Set us up as a candidate for reactivation. 197 EXPECT_TRUE(SetChromeInstallMarker(HKEY_CURRENT_USER)); 198 199 Time hkcu_last_run = Time::NowFromSystemTime() - 200 TimeDelta::FromDays(kReactivationMinDaysDormant); 201 EXPECT_TRUE(SetLastRunTime(HKEY_CURRENT_USER, 202 hkcu_last_run.ToInternalValue())); 203 204 EXPECT_TRUE(ReactivateChrome(L"GAGA", 205 GCAPI_INVOKED_STANDARD_SHELL, 206 &error)); 207 EXPECT_EQ(L"GAGA", GetReactivationString(HKEY_CURRENT_USER)); 208 209 EXPECT_TRUE(HasExperimentLabels(HKEY_CURRENT_USER)); 210 } 211