| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2017 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 "chrome/installer/setup/user_experiment.h" | 
|  | 6 | 
|  | 7 #include "base/macros.h" | 
|  | 8 #include "base/test/test_reg_util_win.h" | 
|  | 9 #include "base/win/registry.h" | 
|  | 10 #include "chrome/common/chrome_version.h" | 
|  | 11 #include "chrome/install_static/install_details.h" | 
|  | 12 #include "chrome/install_static/install_modes.h" | 
|  | 13 #include "chrome/install_static/install_util.h" | 
|  | 14 #include "chrome/install_static/test/scoped_install_details.h" | 
|  | 15 #include "chrome/installer/util/experiment_metrics.h" | 
|  | 16 #include "chrome/installer/util/experiment_storage.h" | 
|  | 17 #include "chrome/installer/util/google_update_constants.h" | 
|  | 18 #include "testing/gtest/include/gtest/gtest.h" | 
|  | 19 | 
|  | 20 namespace installer { | 
|  | 21 | 
|  | 22 class UserExperimentTest : public ::testing::TestWithParam<bool> { | 
|  | 23  protected: | 
|  | 24   UserExperimentTest() | 
|  | 25       : system_level_(GetParam()), | 
|  | 26         root_(system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), | 
|  | 27         install_details_(system_level_) {} | 
|  | 28 | 
|  | 29   void SetUp() override { | 
|  | 30     ASSERT_NO_FATAL_FAILURE(registry_override_manager_.OverrideRegistry(root_)); | 
|  | 31 | 
|  | 32     // Create the ClientState key. | 
|  | 33     base::win::RegKey key; | 
|  | 34     ASSERT_EQ(key.Create(root_, | 
|  | 35                          install_static::InstallDetails::Get() | 
|  | 36                              .GetClientStateKeyPath() | 
|  | 37                              .c_str(), | 
|  | 38                          KEY_WOW64_64KEY | KEY_SET_VALUE), | 
|  | 39               ERROR_SUCCESS); | 
|  | 40   } | 
|  | 41 | 
|  | 42   void SetProductVersion(const base::char16* version) { | 
|  | 43     SetClientsValue(google_update::kRegVersionField, version); | 
|  | 44   } | 
|  | 45 | 
|  | 46   void SetOldProductVersion(const base::char16* version) { | 
|  | 47     SetClientsValue(google_update::kRegOldVersionField, version); | 
|  | 48   } | 
|  | 49 | 
|  | 50  private: | 
|  | 51   void SetClientsValue(const base::char16* value_name, | 
|  | 52                        const base::char16* value_data) { | 
|  | 53     base::win::RegKey key( | 
|  | 54         root_, | 
|  | 55         install_static::GetClientsKeyPath(install_static::GetAppGuid()).c_str(), | 
|  | 56         KEY_WOW64_64KEY | KEY_SET_VALUE); | 
|  | 57     ASSERT_TRUE(key.Valid()); | 
|  | 58     ASSERT_EQ(key.WriteValue(value_name, value_data), ERROR_SUCCESS); | 
|  | 59   } | 
|  | 60 | 
|  | 61   const bool system_level_; | 
|  | 62   const HKEY root_; | 
|  | 63   registry_util::RegistryOverrideManager registry_override_manager_; | 
|  | 64   install_static::ScopedInstallDetails install_details_; | 
|  | 65   DISALLOW_COPY_AND_ASSIGN(UserExperimentTest); | 
|  | 66 }; | 
|  | 67 | 
|  | 68 TEST_P(UserExperimentTest, WriteInitialStateNoData) { | 
|  | 69   ExperimentStorage storage; | 
|  | 70 | 
|  | 71   // A first call should write the desired state. | 
|  | 72   WriteInitialState(&storage, ExperimentMetrics::kWaitingForUserLogon); | 
|  | 73 | 
|  | 74   ExperimentMetrics metrics = ExperimentMetrics(); | 
|  | 75   EXPECT_TRUE(storage.AcquireLock()->LoadMetrics(&metrics)); | 
|  | 76   EXPECT_EQ(metrics.state, ExperimentMetrics::kWaitingForUserLogon); | 
|  | 77 | 
|  | 78   // A subsequent should update it state. | 
|  | 79   WriteInitialState(&storage, ExperimentMetrics::kSingletonWaitTimeout); | 
|  | 80 | 
|  | 81   metrics = ExperimentMetrics(); | 
|  | 82   EXPECT_TRUE(storage.AcquireLock()->LoadMetrics(&metrics)); | 
|  | 83   EXPECT_EQ(metrics.state, ExperimentMetrics::kSingletonWaitTimeout); | 
|  | 84 } | 
|  | 85 | 
|  | 86 // Nothing should be written if the experiment is underway. | 
|  | 87 TEST_P(UserExperimentTest, WriteInitialStateInExperiment) { | 
|  | 88   ExperimentStorage storage; | 
|  | 89 | 
|  | 90   { | 
|  | 91     ExperimentMetrics metrics = ExperimentMetrics(); | 
|  | 92     metrics.state = ExperimentMetrics::kGroupAssigned; | 
|  | 93     storage.AcquireLock()->StoreMetrics(metrics); | 
|  | 94   } | 
|  | 95 | 
|  | 96   WriteInitialState(&storage, ExperimentMetrics::kSingletonWaitTimeout); | 
|  | 97 | 
|  | 98   ExperimentMetrics metrics = ExperimentMetrics(); | 
|  | 99   EXPECT_TRUE(storage.AcquireLock()->LoadMetrics(&metrics)); | 
|  | 100   EXPECT_EQ(metrics.state, ExperimentMetrics::kGroupAssigned); | 
|  | 101 } | 
|  | 102 | 
|  | 103 TEST_P(UserExperimentTest, IsDomainJoined) { | 
|  | 104   // Just make sure it doesn't crash or leak. | 
|  | 105   IsDomainJoined(); | 
|  | 106 } | 
|  | 107 | 
|  | 108 TEST_P(UserExperimentTest, IsSelectedForStudyFirstCall) { | 
|  | 109   ExperimentStorage storage; | 
|  | 110   auto lock = storage.AcquireLock(); | 
|  | 111 | 
|  | 112   // The first call will pick a study. | 
|  | 113   bool is_selected = | 
|  | 114       IsSelectedForStudy(lock.get(), ExperimentStorage::kStudyOne); | 
|  | 115 | 
|  | 116   // A value must have been written. | 
|  | 117   ExperimentStorage::Study participation = ExperimentStorage::kNoStudySelected; | 
|  | 118   ASSERT_TRUE(lock->ReadParticipation(&participation)); | 
|  | 119   EXPECT_GE(participation, ExperimentStorage::kStudyOne); | 
|  | 120   EXPECT_LE(participation, ExperimentStorage::kStudyTwo); | 
|  | 121 | 
|  | 122   // is_selected should be set based on the value that was written. | 
|  | 123   if (participation == ExperimentStorage::kStudyOne) | 
|  | 124     EXPECT_TRUE(is_selected); | 
|  | 125   else | 
|  | 126     EXPECT_FALSE(is_selected); | 
|  | 127 } | 
|  | 128 | 
|  | 129 // A user selected into study one participates in both studies. | 
|  | 130 TEST_P(UserExperimentTest, IsSelectedForStudyOne) { | 
|  | 131   ExperimentStorage storage; | 
|  | 132   auto lock = storage.AcquireLock(); | 
|  | 133 | 
|  | 134   ASSERT_TRUE(lock->WriteParticipation(ExperimentStorage::kStudyOne)); | 
|  | 135 | 
|  | 136   EXPECT_TRUE(IsSelectedForStudy(lock.get(), ExperimentStorage::kStudyOne)); | 
|  | 137   EXPECT_TRUE(IsSelectedForStudy(lock.get(), ExperimentStorage::kStudyTwo)); | 
|  | 138 } | 
|  | 139 | 
|  | 140 // A user selected into study two only participates in that study. | 
|  | 141 TEST_P(UserExperimentTest, IsSelectedForStudyTwo) { | 
|  | 142   ExperimentStorage storage; | 
|  | 143   auto lock = storage.AcquireLock(); | 
|  | 144 | 
|  | 145   ASSERT_TRUE(lock->WriteParticipation(ExperimentStorage::kStudyTwo)); | 
|  | 146 | 
|  | 147   EXPECT_FALSE(IsSelectedForStudy(lock.get(), ExperimentStorage::kStudyOne)); | 
|  | 148   EXPECT_TRUE(IsSelectedForStudy(lock.get(), ExperimentStorage::kStudyTwo)); | 
|  | 149 } | 
|  | 150 | 
|  | 151 // Ensure that group selection is within bounds. | 
|  | 152 TEST_P(UserExperimentTest, PickGroupStudyOne) { | 
|  | 153   int group = PickGroup(ExperimentStorage::kStudyOne); | 
|  | 154   EXPECT_GE(group, 0); | 
|  | 155   EXPECT_LT(group, ExperimentMetrics::kNumGroups); | 
|  | 156 } | 
|  | 157 | 
|  | 158 // Ensure that group selection is within bounds. | 
|  | 159 TEST_P(UserExperimentTest, PickGroupStudyTwo) { | 
|  | 160   int group = PickGroup(ExperimentStorage::kStudyTwo); | 
|  | 161   EXPECT_GE(group, 0); | 
|  | 162   EXPECT_LT(group, ExperimentMetrics::kNumGroups); | 
|  | 163 } | 
|  | 164 | 
|  | 165 // When there's nothing in the registry, default to false. | 
|  | 166 TEST_P(UserExperimentTest, IsUpdateRenamePendingNoRegistration) { | 
|  | 167   EXPECT_FALSE(IsUpdateRenamePending()); | 
|  | 168 } | 
|  | 169 | 
|  | 170 // No update is pending if "pv" matches the current version. | 
|  | 171 TEST_P(UserExperimentTest, IsUpdateRenamePendingNo) { | 
|  | 172   ASSERT_NO_FATAL_FAILURE(SetProductVersion(TEXT(CHROME_VERSION_STRING))); | 
|  | 173   EXPECT_FALSE(IsUpdateRenamePending()); | 
|  | 174 } | 
|  | 175 | 
|  | 176 // An update is pending if an old version needs to be restarted to be the | 
|  | 177 // current. | 
|  | 178 TEST_P(UserExperimentTest, IsUpdateRenamePendingYes) { | 
|  | 179   static constexpr base::char16 kSillyOldVersion[] = L"47.0.1.0"; | 
|  | 180   ASSERT_STRNE(kSillyOldVersion, TEXT(CHROME_VERSION_STRING)); | 
|  | 181 | 
|  | 182   ASSERT_NO_FATAL_FAILURE(SetProductVersion(TEXT(CHROME_VERSION_STRING))); | 
|  | 183   ASSERT_NO_FATAL_FAILURE(SetOldProductVersion(kSillyOldVersion)); | 
|  | 184   EXPECT_TRUE(IsUpdateRenamePending()); | 
|  | 185 } | 
|  | 186 | 
|  | 187 INSTANTIATE_TEST_CASE_P(UserLevel, | 
|  | 188                         UserExperimentTest, | 
|  | 189                         ::testing::Values(false)); | 
|  | 190 INSTANTIATE_TEST_CASE_P(SystemLevel, | 
|  | 191                         UserExperimentTest, | 
|  | 192                         ::testing::Values(true)); | 
|  | 193 | 
|  | 194 }  // namespace installer | 
| OLD | NEW | 
|---|