OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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/browser/google/google_update_win.h" |
| 6 |
| 7 #include <windows.h> |
| 8 #include <atlbase.h> |
| 9 #include <atlcom.h> |
| 10 |
| 11 #include <queue> |
| 12 |
| 13 #include "base/base_paths.h" |
| 14 #include "base/memory/ref_counted.h" |
| 15 #include "base/path_service.h" |
| 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/stringprintf.h" |
| 18 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/test/scoped_path_override.h" |
| 20 #include "base/test/test_reg_util_win.h" |
| 21 #include "base/test/test_simple_task_runner.h" |
| 22 #include "base/thread_task_runner_handle.h" |
| 23 #include "base/version.h" |
| 24 #include "base/win/registry.h" |
| 25 #include "chrome/installer/util/browser_distribution.h" |
| 26 #include "chrome/installer/util/google_update_settings.h" |
| 27 #include "chrome/installer/util/helper.h" |
| 28 #include "google_update/google_update_idl.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" |
| 31 #include "ui/base/win/atl_module.h" |
| 32 #include "version.h" |
| 33 |
| 34 using ::testing::DoAll; |
| 35 using ::testing::Invoke; |
| 36 using ::testing::IsEmpty; |
| 37 using ::testing::Return; |
| 38 using ::testing::SetArgPointee; |
| 39 using ::testing::StrEq; |
| 40 using ::testing::Unused; |
| 41 using ::testing::Values; |
| 42 using ::testing::_; |
| 43 |
| 44 namespace { |
| 45 |
| 46 class UpdateCheckCallbackReceiver { |
| 47 public: |
| 48 UpdateCheckCallbackReceiver() {} |
| 49 virtual ~UpdateCheckCallbackReceiver() {} |
| 50 virtual void OnUpdateCheckCallback(GoogleUpdateUpgradeResult result, |
| 51 GoogleUpdateErrorCode error_code, |
| 52 const base::string16& error_message, |
| 53 const base::string16& version) = 0; |
| 54 UpdateCheckCallback GetCallback() { |
| 55 return base::Bind(&UpdateCheckCallbackReceiver::UpdateCheckCallback, |
| 56 base::Unretained(this)); |
| 57 } |
| 58 |
| 59 private: |
| 60 void UpdateCheckCallback(GoogleUpdateUpgradeResult result, |
| 61 GoogleUpdateErrorCode error_code, |
| 62 const base::string16& error_message, |
| 63 const base::string16& version) { |
| 64 OnUpdateCheckCallback(result, error_code, error_message, version); |
| 65 } |
| 66 |
| 67 DISALLOW_COPY_AND_ASSIGN(UpdateCheckCallbackReceiver); |
| 68 }; |
| 69 |
| 70 class MockUpdateCheckCallbackReceiver : public UpdateCheckCallbackReceiver { |
| 71 public: |
| 72 MockUpdateCheckCallbackReceiver() {} |
| 73 MOCK_METHOD4(OnUpdateCheckCallback, |
| 74 void(GoogleUpdateUpgradeResult, |
| 75 GoogleUpdateErrorCode, |
| 76 const base::string16&, |
| 77 const base::string16&)); |
| 78 |
| 79 private: |
| 80 DISALLOW_COPY_AND_ASSIGN(MockUpdateCheckCallbackReceiver); |
| 81 }; |
| 82 |
| 83 class GoogleUpdateFactory { |
| 84 public: |
| 85 virtual ~GoogleUpdateFactory() {} |
| 86 virtual HRESULT Create(base::win::ScopedComPtr<IGoogleUpdate>* on_demand) = 0; |
| 87 }; |
| 88 |
| 89 class MockGoogleUpdateFactory : public GoogleUpdateFactory { |
| 90 public: |
| 91 MockGoogleUpdateFactory() {} |
| 92 MOCK_METHOD1(Create, HRESULT(base::win::ScopedComPtr<IGoogleUpdate>*)); |
| 93 |
| 94 private: |
| 95 DISALLOW_COPY_AND_ASSIGN(MockGoogleUpdateFactory); |
| 96 }; |
| 97 |
| 98 // A mock IGoogleUpdate on-demand update class that can run an IJobObserver |
| 99 // through a set of states. |
| 100 class MockOnDemand : public CComObjectRootEx<CComSingleThreadModel>, |
| 101 public IGoogleUpdate { |
| 102 public: |
| 103 BEGIN_COM_MAP(MockOnDemand) |
| 104 COM_INTERFACE_ENTRY(IGoogleUpdate) |
| 105 END_COM_MAP() |
| 106 |
| 107 MockOnDemand() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {} |
| 108 |
| 109 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, |
| 110 CheckForUpdate, |
| 111 HRESULT(const wchar_t*, IJobObserver*)); |
| 112 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, |
| 113 Update, |
| 114 HRESULT(const wchar_t*, IJobObserver*)); |
| 115 |
| 116 void OnCheckRunUpToDateSequence(const base::char16* app_guid) { |
| 117 EXPECT_CALL(*this, CheckForUpdate(StrEq(app_guid), _)) |
| 118 .WillOnce(DoAll(Invoke(this, &MockOnDemand::BeginUpToDateSequence), |
| 119 Return(S_OK))); |
| 120 } |
| 121 |
| 122 void OnCheckRunUpdateAvailableSequence(const base::char16* app_guid, |
| 123 const base::string16& new_version) { |
| 124 new_version_ = new_version; |
| 125 EXPECT_CALL(*this, CheckForUpdate(StrEq(app_guid), _)) |
| 126 .WillOnce( |
| 127 DoAll(Invoke(this, &MockOnDemand::BeginUpdateAvailableSequence), |
| 128 Return(S_OK))); |
| 129 } |
| 130 |
| 131 void OnUpdateRunInstallUpdateSequence(const base::char16* app_guid, |
| 132 const base::string16& new_version) { |
| 133 new_version_ = new_version; |
| 134 EXPECT_CALL(*this, Update(StrEq(app_guid), _)) |
| 135 .WillOnce(DoAll(Invoke(this, &MockOnDemand::BeginInstallUpdateSequence), |
| 136 Return(S_OK))); |
| 137 } |
| 138 |
| 139 void OnUpdateRunUpdateErrorSequence(const base::char16* app_guid, |
| 140 const base::char16* error_text) { |
| 141 error_text_ = error_text; |
| 142 EXPECT_CALL(*this, Update(StrEq(app_guid), _)) |
| 143 .WillOnce(DoAll(Invoke(this, &MockOnDemand::BeginUpdateErrorSequence), |
| 144 Return(S_OK))); |
| 145 } |
| 146 |
| 147 private: |
| 148 enum State { |
| 149 STATE_CHECKING, |
| 150 STATE_COMPLETE_SUCCESS, |
| 151 STATE_UPDATE_AVAILABLE, |
| 152 STATE_WAITING_TO_DOWNLOAD, |
| 153 STATE_DOWNLOADING_25, |
| 154 STATE_DOWNLOADING_100, |
| 155 STATE_WAITING_TO_INSTALL, |
| 156 STATE_INSTALLING, |
| 157 STATE_COMPLETE_ERROR, |
| 158 }; |
| 159 |
| 160 void BeginUpToDateSequence(Unused, IJobObserver* job_observer_ptr) { |
| 161 job_observer_ = job_observer_ptr; |
| 162 states_.push(STATE_CHECKING); |
| 163 states_.push(STATE_COMPLETE_SUCCESS); |
| 164 task_runner_->PostTask( |
| 165 FROM_HERE, base::Bind(&MockOnDemand::Advance, base::Unretained(this))); |
| 166 } |
| 167 |
| 168 void BeginUpdateAvailableSequence(Unused, IJobObserver* job_observer_ptr) { |
| 169 job_observer_ = job_observer_ptr; |
| 170 states_.push(STATE_CHECKING); |
| 171 states_.push(STATE_UPDATE_AVAILABLE); |
| 172 states_.push(STATE_COMPLETE_SUCCESS); |
| 173 task_runner_->PostTask( |
| 174 FROM_HERE, base::Bind(&MockOnDemand::Advance, base::Unretained(this))); |
| 175 } |
| 176 |
| 177 void BeginInstallUpdateSequence(Unused, IJobObserver* job_observer_ptr) { |
| 178 job_observer_ = job_observer_ptr; |
| 179 states_.push(STATE_CHECKING); |
| 180 states_.push(STATE_UPDATE_AVAILABLE); |
| 181 states_.push(STATE_WAITING_TO_DOWNLOAD); |
| 182 states_.push(STATE_DOWNLOADING_25); |
| 183 states_.push(STATE_DOWNLOADING_100); |
| 184 states_.push(STATE_WAITING_TO_INSTALL); |
| 185 states_.push(STATE_INSTALLING); |
| 186 states_.push(STATE_COMPLETE_SUCCESS); |
| 187 task_runner_->PostTask( |
| 188 FROM_HERE, base::Bind(&MockOnDemand::Advance, base::Unretained(this))); |
| 189 } |
| 190 |
| 191 void BeginUpdateErrorSequence(Unused, IJobObserver* job_observer_ptr) { |
| 192 job_observer_ = job_observer_ptr; |
| 193 states_.push(STATE_CHECKING); |
| 194 states_.push(STATE_UPDATE_AVAILABLE); |
| 195 states_.push(STATE_WAITING_TO_DOWNLOAD); |
| 196 states_.push(STATE_DOWNLOADING_25); |
| 197 states_.push(STATE_DOWNLOADING_100); |
| 198 states_.push(STATE_WAITING_TO_INSTALL); |
| 199 states_.push(STATE_INSTALLING); |
| 200 states_.push(STATE_COMPLETE_ERROR); |
| 201 task_runner_->PostTask( |
| 202 FROM_HERE, base::Bind(&MockOnDemand::Advance, base::Unretained(this))); |
| 203 } |
| 204 |
| 205 // Advance to the next state. If this state is non-terminal, a task is posted |
| 206 // to advance to the next state a bit later. |
| 207 void Advance() { |
| 208 ASSERT_FALSE(states_.empty()); |
| 209 switch (states_.front()) { |
| 210 case STATE_CHECKING: |
| 211 EXPECT_EQ(S_OK, job_observer_->OnCheckingForUpdate()); |
| 212 break; |
| 213 case STATE_COMPLETE_SUCCESS: |
| 214 EXPECT_EQ(S_OK, |
| 215 job_observer_->OnComplete(COMPLETION_CODE_SUCCESS, nullptr)); |
| 216 break; |
| 217 case STATE_UPDATE_AVAILABLE: |
| 218 EXPECT_EQ(S_OK, job_observer_->OnUpdateAvailable(new_version_.c_str())); |
| 219 break; |
| 220 case STATE_WAITING_TO_DOWNLOAD: |
| 221 EXPECT_EQ(S_OK, job_observer_->OnWaitingToDownload()); |
| 222 break; |
| 223 case STATE_DOWNLOADING_25: |
| 224 EXPECT_EQ(S_OK, job_observer_->OnDownloading(47, 25)); |
| 225 break; |
| 226 case STATE_DOWNLOADING_100: |
| 227 EXPECT_EQ(S_OK, job_observer_->OnDownloading(42, 100)); |
| 228 break; |
| 229 case STATE_WAITING_TO_INSTALL: |
| 230 EXPECT_EQ(S_OK, job_observer_->OnWaitingToInstall()); |
| 231 break; |
| 232 case STATE_INSTALLING: |
| 233 EXPECT_EQ(S_OK, job_observer_->OnInstalling()); |
| 234 break; |
| 235 case STATE_COMPLETE_ERROR: |
| 236 EXPECT_EQ(S_OK, job_observer_->OnComplete(COMPLETION_CODE_ERROR, |
| 237 error_text_.c_str())); |
| 238 break; |
| 239 } |
| 240 states_.pop(); |
| 241 if (states_.empty()) { |
| 242 // Drop the reference to the observer when the terminal state is reached. |
| 243 job_observer_ = nullptr; |
| 244 } else { |
| 245 task_runner_->PostTask(FROM_HERE, base::Bind(&MockOnDemand::Advance, |
| 246 base::Unretained(this))); |
| 247 } |
| 248 } |
| 249 |
| 250 // The task runner on which the state machine runs. |
| 251 scoped_refptr<base::TaskRunner> task_runner_; |
| 252 |
| 253 // The new version for a successful update check or update. |
| 254 base::string16 new_version_; |
| 255 |
| 256 // Error text to be supplied for an unsuccessful update check or update. |
| 257 base::string16 error_text_; |
| 258 |
| 259 // The set of states to be run on an IJobObserver. |
| 260 std::queue<State> states_; |
| 261 |
| 262 // The IJobObserver given to either CheckForUpdate() or Update() that is being |
| 263 // driven through the desired state transitions. |
| 264 base::win::ScopedComPtr<IJobObserver> job_observer_; |
| 265 |
| 266 DISALLOW_COPY_AND_ASSIGN(MockOnDemand); |
| 267 }; |
| 268 |
| 269 } // namespace |
| 270 |
| 271 class GoogleUpdateWinTest : public ::testing::TestWithParam<bool> { |
| 272 public: |
| 273 static void SetUpTestCase() { ui::win::CreateATLModuleIfNeeded(); } |
| 274 |
| 275 protected: |
| 276 GoogleUpdateWinTest() |
| 277 : task_runner_(new base::TestSimpleTaskRunner()), |
| 278 task_runner_handle_(task_runner_), |
| 279 system_level_(GetParam()), |
| 280 mock_on_demand_(nullptr) {} |
| 281 |
| 282 void SetUp() override { |
| 283 ::testing::TestWithParam<bool>::SetUp(); |
| 284 |
| 285 // Override FILE_EXE so that it looks like the test is running from the |
| 286 // standard install location for this mode (system-level or user-level). |
| 287 base::FilePath file_exe; |
| 288 ASSERT_TRUE(PathService::Get(base::FILE_EXE, &file_exe)); |
| 289 base::FilePath install_dir(installer::GetChromeInstallPath( |
| 290 system_level_, BrowserDistribution::GetDistribution())); |
| 291 file_exe_override_.reset(new base::ScopedPathOverride( |
| 292 base::FILE_EXE, install_dir.Append(file_exe.BaseName()), |
| 293 true /* is_absolute */, false /* create */)); |
| 294 |
| 295 // Override the registry so that tests can freely push state to it. |
| 296 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER); |
| 297 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE); |
| 298 |
| 299 // Chrome is installed as multi-install. |
| 300 const HKEY root = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| 301 base::win::RegKey key(root, kClients, KEY_WRITE | KEY_WOW64_32KEY); |
| 302 ASSERT_EQ(ERROR_SUCCESS, |
| 303 key.CreateKey(kChromeGuid, KEY_WRITE | KEY_WOW64_32KEY)); |
| 304 ASSERT_EQ(ERROR_SUCCESS, |
| 305 key.WriteValue( |
| 306 L"pv", base::ASCIIToUTF16(CHROME_VERSION_STRING).c_str())); |
| 307 ASSERT_EQ(ERROR_SUCCESS, |
| 308 key.Create(root, kClientState, KEY_WRITE | KEY_WOW64_32KEY)); |
| 309 ASSERT_EQ(ERROR_SUCCESS, |
| 310 key.CreateKey(kChromeGuid, KEY_WRITE | KEY_WOW64_32KEY)); |
| 311 ASSERT_EQ(ERROR_SUCCESS, |
| 312 key.WriteValue(L"UninstallArguments", |
| 313 L"--uninstall --multi-install --chrome")); |
| 314 |
| 315 // Provide an IGoogleUpdate on-demand update class factory so that this test |
| 316 // can provide a mocked-out instance. |
| 317 internal::SetGoogleUpdateFactory( |
| 318 base::Bind(&GoogleUpdateFactory::Create, |
| 319 base::Unretained(&mock_google_update_factory_))); |
| 320 // Configure the factory to return a generic failure by default. |
| 321 ON_CALL(mock_google_update_factory_, Create(_)) |
| 322 .WillByDefault(Return(E_FAIL)); |
| 323 |
| 324 // Create a mock IGoogleUpdate on-demand update class |
| 325 ASSERT_EQ(S_OK, CComObject<MockOnDemand>::CreateInstance(&mock_on_demand_)); |
| 326 on_demand_holder_ = mock_on_demand_; |
| 327 // Configure the mock to return a generic failure by default. |
| 328 ON_CALL(*mock_on_demand_, CheckForUpdate(_, _)) |
| 329 .WillByDefault(Return(E_FAIL)); |
| 330 ON_CALL(*mock_on_demand_, Update(_, _)).WillByDefault(Return(E_FAIL)); |
| 331 |
| 332 // Compute a newer version. |
| 333 base::Version current_version(CHROME_VERSION_STRING); |
| 334 new_version_ = base::StringPrintf(L"%hu.%hu.%hu.%hu", |
| 335 current_version.components()[0], |
| 336 current_version.components()[1], |
| 337 current_version.components()[2] + 1, |
| 338 current_version.components()[3]); |
| 339 } |
| 340 |
| 341 void TearDown() override { |
| 342 // Remove the test's IGoogleUpdate on-demand update class factory. |
| 343 internal::SetGoogleUpdateFactory(internal::OnDemandAppsClassFactory()); |
| 344 } |
| 345 |
| 346 // Set the default update policy in the registry. |
| 347 void SetDefaultUpdatePolicy(GoogleUpdateSettings::UpdatePolicy policy) const { |
| 348 base::win::RegKey policy_key(HKEY_LOCAL_MACHINE, kPoliciesKey, |
| 349 KEY_SET_VALUE); |
| 350 ASSERT_EQ(ERROR_SUCCESS, policy_key.WriteValue(kUpdateDefault, policy)); |
| 351 } |
| 352 |
| 353 // Stuffs |policy| in the registry for the app identified by |app_guid|. |
| 354 void SetAppUpdatePolicy(const base::char16* app_guid, |
| 355 GoogleUpdateSettings::UpdatePolicy policy) const { |
| 356 base::string16 value_name(L"Update"); |
| 357 value_name += app_guid; |
| 358 base::win::RegKey policy_key(HKEY_LOCAL_MACHINE, kPoliciesKey, |
| 359 KEY_SET_VALUE); |
| 360 ASSERT_EQ(ERROR_SUCCESS, policy_key.WriteValue(value_name.c_str(), policy)); |
| 361 } |
| 362 |
| 363 static const base::char16 kPoliciesKey[]; |
| 364 static const base::char16 kUpdateDefault[]; |
| 365 static const base::char16 kClients[]; |
| 366 static const base::char16 kClientState[]; |
| 367 static const base::char16 kChromeGuid[]; |
| 368 static const base::char16 kChromeBinariesGuid[]; |
| 369 |
| 370 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 371 base::ThreadTaskRunnerHandle task_runner_handle_; |
| 372 bool system_level_; |
| 373 scoped_ptr<base::ScopedPathOverride> file_exe_override_; |
| 374 registry_util::RegistryOverrideManager registry_override_manager_; |
| 375 MockUpdateCheckCallbackReceiver callback_receiver_; |
| 376 MockGoogleUpdateFactory mock_google_update_factory_; |
| 377 CComObject<MockOnDemand>* mock_on_demand_; |
| 378 base::win::ScopedComPtr<IGoogleUpdate> on_demand_holder_; |
| 379 base::string16 new_version_; |
| 380 |
| 381 DISALLOW_COPY_AND_ASSIGN(GoogleUpdateWinTest); |
| 382 }; |
| 383 |
| 384 // static |
| 385 const base::char16 GoogleUpdateWinTest::kPoliciesKey[] = |
| 386 L"SOFTWARE\\Policies\\Google\\Update"; |
| 387 const base::char16 GoogleUpdateWinTest::kUpdateDefault[] = L"UpdateDefault"; |
| 388 const base::char16 GoogleUpdateWinTest::kClients[] = |
| 389 L"Software\\Google\\Update\\Clients"; |
| 390 const base::char16 GoogleUpdateWinTest::kClientState[] = |
| 391 L"Software\\Google\\Update\\ClientState"; |
| 392 const base::char16 GoogleUpdateWinTest::kChromeGuid[] = |
| 393 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
| 394 const base::char16 GoogleUpdateWinTest::kChromeBinariesGuid[] = |
| 395 L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"; |
| 396 |
| 397 // Test that an update check fails with the proper error code if Chrome isn't in |
| 398 // one of the expected install directories. |
| 399 TEST_P(GoogleUpdateWinTest, InvalidInstallDirectory) { |
| 400 // Override FILE_EXE so that it looks like the test is running from a |
| 401 // non-standard location. |
| 402 base::FilePath file_exe; |
| 403 base::FilePath dir_temp; |
| 404 ASSERT_TRUE(PathService::Get(base::FILE_EXE, &file_exe)); |
| 405 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &dir_temp)); |
| 406 file_exe_override_.reset(); |
| 407 file_exe_override_.reset(new base::ScopedPathOverride( |
| 408 base::FILE_EXE, dir_temp.Append(file_exe.BaseName()), |
| 409 true /* is_absolute */, false /* create */)); |
| 410 |
| 411 EXPECT_CALL( |
| 412 callback_receiver_, |
| 413 OnUpdateCheckCallback(UPGRADE_ERROR, |
| 414 CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY, _, _)); |
| 415 internal::CheckForUpdate(task_runner_, false, 0, |
| 416 callback_receiver_.GetCallback()); |
| 417 task_runner_->RunUntilIdle(); |
| 418 } |
| 419 |
| 420 #if defined(GOOGLE_CHROME_BUILD) |
| 421 |
| 422 TEST_P(GoogleUpdateWinTest, AllUpdatesDisabledByPolicy) { |
| 423 // Disable updates altogether. |
| 424 SetDefaultUpdatePolicy(GoogleUpdateSettings::UPDATES_DISABLED); |
| 425 |
| 426 EXPECT_CALL(callback_receiver_, |
| 427 OnUpdateCheckCallback(UPGRADE_ERROR, |
| 428 GOOGLE_UPDATE_DISABLED_BY_POLICY, _, _)); |
| 429 internal::CheckForUpdate(task_runner_, false, 0, |
| 430 callback_receiver_.GetCallback()); |
| 431 task_runner_->RunUntilIdle(); |
| 432 } |
| 433 |
| 434 TEST_P(GoogleUpdateWinTest, MultiUpdatesDisabledByPolicy) { |
| 435 // Disable updates altogether. |
| 436 SetAppUpdatePolicy(kChromeBinariesGuid, |
| 437 GoogleUpdateSettings::UPDATES_DISABLED); |
| 438 |
| 439 EXPECT_CALL(callback_receiver_, |
| 440 OnUpdateCheckCallback(UPGRADE_ERROR, |
| 441 GOOGLE_UPDATE_DISABLED_BY_POLICY, _, _)); |
| 442 internal::CheckForUpdate(task_runner_, false, 0, |
| 443 callback_receiver_.GetCallback()); |
| 444 task_runner_->RunUntilIdle(); |
| 445 } |
| 446 |
| 447 TEST_P(GoogleUpdateWinTest, AllManualUpdatesDisabledByPolicy) { |
| 448 // Disable updates altogether. |
| 449 SetDefaultUpdatePolicy(GoogleUpdateSettings::AUTO_UPDATES_ONLY); |
| 450 |
| 451 EXPECT_CALL( |
| 452 callback_receiver_, |
| 453 OnUpdateCheckCallback(UPGRADE_ERROR, |
| 454 GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY, _, _)); |
| 455 internal::CheckForUpdate(task_runner_, false, 0, |
| 456 callback_receiver_.GetCallback()); |
| 457 task_runner_->RunUntilIdle(); |
| 458 } |
| 459 |
| 460 TEST_P(GoogleUpdateWinTest, MultiManualUpdatesDisabledByPolicy) { |
| 461 // Disable updates altogether. |
| 462 SetAppUpdatePolicy(kChromeBinariesGuid, |
| 463 GoogleUpdateSettings::AUTO_UPDATES_ONLY); |
| 464 |
| 465 EXPECT_CALL( |
| 466 callback_receiver_, |
| 467 OnUpdateCheckCallback(UPGRADE_ERROR, |
| 468 GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY, _, _)); |
| 469 internal::CheckForUpdate(task_runner_, false, 0, |
| 470 callback_receiver_.GetCallback()); |
| 471 task_runner_->RunUntilIdle(); |
| 472 } |
| 473 |
| 474 TEST_P(GoogleUpdateWinTest, NoGoogleUpdateForCheck) { |
| 475 // The factory should be called upon: let it fail. |
| 476 EXPECT_CALL(mock_google_update_factory_, Create(_)); |
| 477 |
| 478 // Expect the appropriate error when the on-demand class cannot be created. |
| 479 EXPECT_CALL(callback_receiver_, |
| 480 OnUpdateCheckCallback( |
| 481 UPGRADE_ERROR, GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND, _, _)); |
| 482 internal::CheckForUpdate(task_runner_, false, 0, |
| 483 callback_receiver_.GetCallback()); |
| 484 task_runner_->RunUntilIdle(); |
| 485 } |
| 486 |
| 487 TEST_P(GoogleUpdateWinTest, NoGoogleUpdateForUpgrade) { |
| 488 // The factory should be called upon: let it fail. |
| 489 EXPECT_CALL(mock_google_update_factory_, Create(_)); |
| 490 |
| 491 // Expect the appropriate error when the on-demand class cannot be created. |
| 492 EXPECT_CALL(callback_receiver_, |
| 493 OnUpdateCheckCallback( |
| 494 UPGRADE_ERROR, GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND, _, _)); |
| 495 internal::CheckForUpdate(task_runner_, true, 0, |
| 496 callback_receiver_.GetCallback()); |
| 497 task_runner_->RunUntilIdle(); |
| 498 } |
| 499 |
| 500 TEST_P(GoogleUpdateWinTest, FailUpdateCheck) { |
| 501 // The factory should be called upon: let it return the mock on-demand class. |
| 502 EXPECT_CALL(mock_google_update_factory_, Create(_)) |
| 503 .WillOnce(DoAll(SetArgPointee<0>(mock_on_demand_), Return(S_OK))); |
| 504 // The mock on-demand class should be called. |
| 505 EXPECT_CALL(*mock_on_demand_, CheckForUpdate(StrEq(kChromeBinariesGuid), _)); |
| 506 |
| 507 EXPECT_CALL( |
| 508 callback_receiver_, |
| 509 OnUpdateCheckCallback(UPGRADE_ERROR, |
| 510 GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR, _, _)); |
| 511 internal::CheckForUpdate(task_runner_, false, 0, |
| 512 callback_receiver_.GetCallback()); |
| 513 task_runner_->RunUntilIdle(); |
| 514 } |
| 515 |
| 516 TEST_P(GoogleUpdateWinTest, UpdateCheckNoUpdate) { |
| 517 EXPECT_CALL(mock_google_update_factory_, Create(_)) |
| 518 .WillOnce(DoAll(SetArgPointee<0>(mock_on_demand_), Return(S_OK))); |
| 519 mock_on_demand_->OnCheckRunUpToDateSequence(kChromeBinariesGuid); |
| 520 |
| 521 EXPECT_CALL(callback_receiver_, |
| 522 OnUpdateCheckCallback(UPGRADE_ALREADY_UP_TO_DATE, |
| 523 GOOGLE_UPDATE_NO_ERROR, IsEmpty(), _)); |
| 524 internal::CheckForUpdate(task_runner_, false, 0, |
| 525 callback_receiver_.GetCallback()); |
| 526 task_runner_->RunUntilIdle(); |
| 527 } |
| 528 |
| 529 TEST_P(GoogleUpdateWinTest, UpdateCheckUpdateAvailable) { |
| 530 EXPECT_CALL(mock_google_update_factory_, Create(_)) |
| 531 .WillOnce(DoAll(SetArgPointee<0>(mock_on_demand_), Return(S_OK))); |
| 532 mock_on_demand_->OnCheckRunUpdateAvailableSequence(kChromeBinariesGuid, |
| 533 new_version_); |
| 534 |
| 535 EXPECT_CALL( |
| 536 callback_receiver_, |
| 537 OnUpdateCheckCallback(UPGRADE_IS_AVAILABLE, GOOGLE_UPDATE_NO_ERROR, |
| 538 IsEmpty(), StrEq(new_version_))); |
| 539 internal::CheckForUpdate(task_runner_, false, 0, |
| 540 callback_receiver_.GetCallback()); |
| 541 task_runner_->RunUntilIdle(); |
| 542 } |
| 543 |
| 544 TEST_P(GoogleUpdateWinTest, UpdateInstalled) { |
| 545 EXPECT_CALL(mock_google_update_factory_, Create(_)) |
| 546 .WillOnce(DoAll(SetArgPointee<0>(mock_on_demand_), Return(S_OK))); |
| 547 mock_on_demand_->OnUpdateRunInstallUpdateSequence(kChromeBinariesGuid, |
| 548 new_version_); |
| 549 |
| 550 EXPECT_CALL(callback_receiver_, |
| 551 OnUpdateCheckCallback(UPGRADE_SUCCESSFUL, GOOGLE_UPDATE_NO_ERROR, |
| 552 IsEmpty(), StrEq(new_version_))); |
| 553 internal::CheckForUpdate(task_runner_, true, 0, |
| 554 callback_receiver_.GetCallback()); |
| 555 task_runner_->RunUntilIdle(); |
| 556 } |
| 557 |
| 558 TEST_P(GoogleUpdateWinTest, UpdateFailed) { |
| 559 static const base::char16 kError[] = L"It didn't work."; |
| 560 EXPECT_CALL(mock_google_update_factory_, Create(_)) |
| 561 .WillOnce(DoAll(SetArgPointee<0>(mock_on_demand_), Return(S_OK))); |
| 562 mock_on_demand_->OnUpdateRunUpdateErrorSequence(kChromeBinariesGuid, kError); |
| 563 |
| 564 EXPECT_CALL(callback_receiver_, |
| 565 OnUpdateCheckCallback(UPGRADE_ERROR, GOOGLE_UPDATE_ERROR_UPDATING, |
| 566 StrEq(kError), IsEmpty())); |
| 567 internal::CheckForUpdate(task_runner_, true, 0, |
| 568 callback_receiver_.GetCallback()); |
| 569 task_runner_->RunUntilIdle(); |
| 570 } |
| 571 |
| 572 #endif // defined(GOOGLE_CHROME_BUILD) |
| 573 |
| 574 INSTANTIATE_TEST_CASE_P(UserLevel, GoogleUpdateWinTest, Values(false)); |
| 575 |
| 576 INSTANTIATE_TEST_CASE_P(SystemLevel, GoogleUpdateWinTest, Values(true)); |
OLD | NEW |