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