Home | History | Annotate | Download | only in gcapi
      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