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.
5 #include "chrome/browser/google/google_update_win.h"
13 #include "base/base_paths.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/path_service.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/test/scoped_path_override.h"
19 #include "base/test/test_reg_util_win.h"
20 #include "base/test/test_simple_task_runner.h"
21 #include "base/thread_task_runner_handle.h"
22 #include "base/version.h"
23 #include "base/win/registry.h"
24 #include "base/win/scoped_comptr.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"
34 using ::testing::Assign
;
35 using ::testing::DoAll
;
36 using ::testing::DoubleEq
;
37 using ::testing::HasSubstr
;
38 using ::testing::InSequence
;
39 using ::testing::Invoke
;
40 using ::testing::IsEmpty
;
41 using ::testing::Return
;
42 using ::testing::Sequence
;
43 using ::testing::SetArgPointee
;
44 using ::testing::StrEq
;
45 using ::testing::StrictMock
;
46 using ::testing::Values
;
51 class MockUpdateCheckDelegate
: public UpdateCheckDelegate
{
53 MockUpdateCheckDelegate() : weak_ptr_factory_(this) {}
55 base::WeakPtr
<UpdateCheckDelegate
> AsWeakPtr() {
56 return weak_ptr_factory_
.GetWeakPtr();
59 MOCK_METHOD1(OnUpdateCheckComplete
, void(const base::string16
&));
60 MOCK_METHOD2(OnUpgradeProgress
, void(int, const base::string16
&));
61 MOCK_METHOD1(OnUpgradeComplete
, void(const base::string16
&));
62 MOCK_METHOD3(OnError
, void(GoogleUpdateErrorCode
,
63 const base::string16
&,
64 const base::string16
&));
67 base::WeakPtrFactory
<UpdateCheckDelegate
> weak_ptr_factory_
;
69 DISALLOW_COPY_AND_ASSIGN(MockUpdateCheckDelegate
);
72 // An interface that exposes a factory method for creating an IGoogleUpdate3Web
74 class GoogleUpdateFactory
{
76 virtual ~GoogleUpdateFactory() {}
77 virtual HRESULT
Create(
78 base::win::ScopedComPtr
<IGoogleUpdate3Web
>* google_update
) = 0;
81 // A mock factory for creating an IGoogleUpdate3Web instance.
82 class MockGoogleUpdateFactory
: public GoogleUpdateFactory
{
84 MockGoogleUpdateFactory() {}
85 MOCK_METHOD1(Create
, HRESULT(base::win::ScopedComPtr
<IGoogleUpdate3Web
>*));
88 DISALLOW_COPY_AND_ASSIGN(MockGoogleUpdateFactory
);
91 class MockCurrentState
: public CComObjectRootEx
<CComSingleThreadModel
>,
92 public ICurrentState
{
94 BEGIN_COM_MAP(MockCurrentState
)
95 COM_INTERFACE_ENTRY(ICurrentState
)
100 // Adds an expectation for get_completionMessage that will return the given
101 // message any number of times.
102 void ExpectCompletionMessage(const base::string16
& completion_message
) {
103 completion_message_
= completion_message
;
104 EXPECT_CALL(*this, get_completionMessage(_
))
106 ::testing::Invoke(this, &MockCurrentState::GetCompletionMessage
));
109 HRESULT
GetCompletionMessage(BSTR
* completion_message
) {
110 *completion_message
= SysAllocString(completion_message_
.c_str());
114 // Adds an expectation for get_availableVersion that will return the given
115 // version any number of times.
116 void ExpectAvailableVersion(const base::string16
& available_version
) {
117 available_version_
= available_version
;
118 EXPECT_CALL(*this, get_availableVersion(_
))
120 ::testing::Invoke(this, &MockCurrentState::GetAvailableVersion
));
123 HRESULT
GetAvailableVersion(BSTR
* available_version
) {
124 *available_version
= SysAllocString(available_version_
.c_str());
129 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
132 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
133 get_availableVersion
,
135 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
138 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
139 get_totalBytesToDownload
,
141 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
142 get_downloadTimeRemainingMs
,
144 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
146 HRESULT(ULONGLONG
*));
147 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
150 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
151 get_installTimeRemainingMs
,
153 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
155 HRESULT(VARIANT_BOOL
*));
156 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
159 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
162 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
163 get_completionMessage
,
165 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
166 get_installerResultCode
,
168 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
169 get_installerResultExtraCode1
,
171 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
172 get_postInstallLaunchCommandLine
,
174 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
177 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
178 get_postInstallAction
,
182 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
185 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE
,
187 HRESULT(UINT
, LCID
, ITypeInfo
**));
188 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE
,
190 HRESULT(REFIID
, LPOLESTR
*, UINT
, LCID
, DISPID
*));
191 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE
,
193 HRESULT(DISPID
, REFIID
, LCID
, WORD
, DISPPARAMS
*,
194 VARIANT
*, EXCEPINFO
*, UINT
*));
197 base::string16 completion_message_
;
198 base::string16 available_version_
;
200 DISALLOW_COPY_AND_ASSIGN(MockCurrentState
);
203 class MockApp
: public CComObjectRootEx
<CComSingleThreadModel
>, public IAppWeb
{
205 BEGIN_COM_MAP(MockApp
)
206 COM_INTERFACE_ENTRY(IAppWeb
)
212 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
215 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
216 get_currentVersionWeb
,
217 HRESULT(IDispatch
**));
218 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
220 HRESULT(IDispatch
**));
221 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
223 HRESULT(BSTR
, IDispatch
**));
224 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
227 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
229 HRESULT(IDispatch
**));
230 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
233 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
238 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
241 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE
,
243 HRESULT(UINT
, LCID
, ITypeInfo
**));
244 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE
,
246 HRESULT(REFIID
, LPOLESTR
*, UINT
, LCID
, DISPID
*));
247 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE
,
249 HRESULT(DISPID
, REFIID
, LCID
, WORD
, DISPPARAMS
*,
250 VARIANT
*, EXCEPINFO
*, UINT
*));
253 DISALLOW_COPY_AND_ASSIGN(MockApp
);
256 class MockAppBundle
: public CComObjectRootEx
<CComSingleThreadModel
>,
257 public IAppBundleWeb
{
259 BEGIN_COM_MAP(MockAppBundle
)
260 COM_INTERFACE_ENTRY(IAppBundleWeb
)
266 MOCK_METHOD4_WITH_CALLTYPE(STDMETHODCALLTYPE
,
268 HRESULT(BSTR
, BSTR
, BSTR
, BSTR
));
269 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
272 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
273 createAllInstalledApps
,
275 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
278 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
281 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
284 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
287 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
289 HRESULT(int, IDispatch
**));
290 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
293 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
296 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
299 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
302 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
305 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
308 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
311 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
313 HRESULT(BSTR
, BSTR
));
314 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
319 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
322 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE
,
324 HRESULT(UINT
, LCID
, ITypeInfo
**));
325 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE
,
327 HRESULT(REFIID
, LPOLESTR
*, UINT
, LCID
, DISPID
*));
328 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE
,
330 HRESULT(DISPID
, REFIID
, LCID
, WORD
, DISPPARAMS
*,
331 VARIANT
*, EXCEPINFO
*, UINT
*));
334 DISALLOW_COPY_AND_ASSIGN(MockAppBundle
);
337 class MockGoogleUpdate
: public CComObjectRootEx
<CComSingleThreadModel
>,
338 public IGoogleUpdate3Web
{
340 BEGIN_COM_MAP(MockGoogleUpdate
)
341 COM_INTERFACE_ENTRY(IGoogleUpdate3Web
)
344 MockGoogleUpdate() {}
346 // IGoogleUpdate3Web:
347 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
349 HRESULT(IDispatch
**));
352 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
355 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE
,
357 HRESULT(UINT
, LCID
, ITypeInfo
**));
358 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE
,
360 HRESULT(REFIID
, LPOLESTR
*, UINT
, LCID
, DISPID
*));
361 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE
,
363 HRESULT(DISPID
, REFIID
, LCID
, WORD
, DISPPARAMS
*,
364 VARIANT
*, EXCEPINFO
*, UINT
*));
366 DISALLOW_COPY_AND_ASSIGN(MockGoogleUpdate
);
371 // A test fixture that can simulate the IGoogleUpdate3Web API via Google Mock.
372 // Individual tests must wire up the factories by a call to one of the
373 // PrepareSimulator methods. The family of Push*State methods are then used to
374 // configure the set of states to be simulated.
375 class GoogleUpdateWinTest
: public ::testing::TestWithParam
<bool> {
377 static void SetUpTestCase() {
378 ui::win::CreateATLModuleIfNeeded();
379 // Configure all mock functions that return HRESULT to return failure.
380 ::testing::DefaultValue
<HRESULT
>::Set(E_FAIL
);
383 static void TearDownTestCase() { ::testing::DefaultValue
<HRESULT
>::Clear(); }
386 GoogleUpdateWinTest()
387 : task_runner_(new base::TestSimpleTaskRunner()),
388 task_runner_handle_(task_runner_
),
389 system_level_install_(GetParam()),
391 mock_app_bundle_(nullptr) {}
393 void SetUp() override
{
394 ::testing::TestWithParam
<bool>::SetUp();
396 // Override FILE_EXE so that it looks like the test is running from the
397 // standard install location for this mode (system-level or user-level).
398 base::FilePath file_exe
;
399 ASSERT_TRUE(PathService::Get(base::FILE_EXE
, &file_exe
));
400 base::FilePath
install_dir(installer::GetChromeInstallPath(
401 system_level_install_
, BrowserDistribution::GetDistribution()));
402 file_exe_override_
.reset(new base::ScopedPathOverride(
403 base::FILE_EXE
, install_dir
.Append(file_exe
.BaseName()),
404 true /* is_absolute */, false /* create */));
406 // Override these paths so that they can be found after the registry
407 // override manager is in place.
409 PathService::Get(base::DIR_PROGRAM_FILES
, &temp
);
410 program_files_override_
.reset(
411 new base::ScopedPathOverride(base::DIR_PROGRAM_FILES
, temp
));
412 PathService::Get(base::DIR_PROGRAM_FILESX86
, &temp
);
413 program_files_x86_override_
.reset(
414 new base::ScopedPathOverride(base::DIR_PROGRAM_FILESX86
, temp
));
415 PathService::Get(base::DIR_LOCAL_APP_DATA
, &temp
);
416 local_app_data_override_
.reset(
417 new base::ScopedPathOverride(base::DIR_LOCAL_APP_DATA
, temp
));
419 // Override the registry so that tests can freely push state to it.
420 registry_override_manager_
.OverrideRegistry(HKEY_CURRENT_USER
);
421 registry_override_manager_
.OverrideRegistry(HKEY_LOCAL_MACHINE
);
423 // Chrome is installed as multi-install.
425 system_level_install_
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
;
426 base::win::RegKey
key(root
, kClients
, KEY_WRITE
| KEY_WOW64_32KEY
);
427 ASSERT_EQ(ERROR_SUCCESS
,
428 key
.CreateKey(kChromeGuid
, KEY_WRITE
| KEY_WOW64_32KEY
));
429 ASSERT_EQ(ERROR_SUCCESS
,
431 L
"pv", base::ASCIIToUTF16(CHROME_VERSION_STRING
).c_str()));
432 ASSERT_EQ(ERROR_SUCCESS
,
433 key
.Create(root
, kClientState
, KEY_WRITE
| KEY_WOW64_32KEY
));
434 ASSERT_EQ(ERROR_SUCCESS
,
435 key
.CreateKey(kChromeGuid
, KEY_WRITE
| KEY_WOW64_32KEY
));
436 ASSERT_EQ(ERROR_SUCCESS
,
437 key
.WriteValue(L
"UninstallArguments",
438 L
"--uninstall --multi-install --chrome"));
440 // Provide an IGoogleUpdate3Web class factory so that this test can provide
441 // a mocked-out instance.
442 SetGoogleUpdateFactoryForTesting(
443 base::Bind(&GoogleUpdateFactory::Create
,
444 base::Unretained(&mock_google_update_factory_
)));
446 // Compute a newer version.
447 base::Version
current_version(CHROME_VERSION_STRING
);
448 new_version_
= base::StringPrintf(L
"%u.%u.%u.%u",
449 current_version
.components()[0],
450 current_version
.components()[1],
451 current_version
.components()[2] + 1,
452 current_version
.components()[3]);
455 void TearDown() override
{
456 ASSERT_EQ(nullptr, mock_app_
);
457 ASSERT_EQ(nullptr, mock_app_bundle_
);
458 ASSERT_TRUE(states_
.empty());
459 // Remove the test's IGoogleUpdate on-demand update class factory.
460 SetGoogleUpdateFactoryForTesting(GoogleUpdate3ClassFactory());
461 ::testing::TestWithParam
<bool>::TearDown();
464 // Prepares the IGoogleUpdate3Web simulator.
465 void PrepareSimulator(const base::char16
* app_guid
) {
466 // Make the installed app and configure it to call the test fixture's
467 // GetNextState method.
468 ASSERT_EQ(S_OK
, CComObject
<MockApp
>::CreateInstance(&mock_app_
));
469 ON_CALL(*mock_app_
, get_currentState(_
))
470 .WillByDefault(Invoke(this, &GoogleUpdateWinTest::GetNextState
));
472 // Make the app bundle containing the app.
474 CComObject
<MockAppBundle
>::CreateInstance(&mock_app_bundle_
));
475 EXPECT_CALL(*mock_app_bundle_
, initialize())
476 .WillOnce(Return(S_OK
));
477 // The bundle will be called on to create the installed app.
478 EXPECT_CALL(*mock_app_bundle_
, createInstalledApp(StrEq(app_guid
)))
479 .WillOnce(Return(S_OK
));
480 // Give mock_app_bundle a ref to the app which it will return when asked.
482 EXPECT_CALL(*mock_app_bundle_
, get_appWeb(0, _
))
483 .WillOnce(DoAll(SetArgPointee
<1>(mock_app_
),
484 Assign(&mock_app_
, nullptr),
487 // Make the updater which will return the app bundle above.
488 CComObject
<MockGoogleUpdate
>* mock_google_update
= nullptr;
489 ASSERT_EQ(S_OK
, CComObject
<MockGoogleUpdate
>::CreateInstance(
490 &mock_google_update
));
491 // Give mock_google_update a ref to the bundle which it will return when
493 mock_app_bundle_
->AddRef();
494 EXPECT_CALL(*mock_google_update
, createAppBundleWeb(_
))
495 .WillOnce(DoAll(SetArgPointee
<0>(mock_app_bundle_
),
496 Assign(&mock_app_bundle_
, nullptr),
499 // Give the factory this updater. Do not add a ref, as the factory will add
500 // one when it hands out its instance.
501 EXPECT_CALL(mock_google_update_factory_
, Create(_
))
502 .WillOnce(DoAll(SetArgPointee
<0>(mock_google_update
), Return(S_OK
)));
505 // Prepares the IGoogleUpdate3Web simulator to process an update check.
506 void PrepareSimulatorForUpdateCheck(const base::char16
* app_guid
) {
507 PrepareSimulator(app_guid
);
508 // Expect the bundle to be called on to start the update.
509 EXPECT_CALL(*mock_app_bundle_
, checkForUpdate())
510 .WillOnce(Return(S_OK
));
513 // Prepares the IGoogleUpdate3Web simulator to process an upgrade.
514 void PrepareSimulatorForUpgrade(const base::char16
* app_guid
) {
515 PrepareSimulatorForUpdateCheck(app_guid
);
516 // Expect the bundle to be called on to start the install.
517 EXPECT_CALL(*mock_app_bundle_
, install())
518 .WillOnce(Return(S_OK
));
521 // Adds a MockCurrentState to the back of the sequence to be returned by the
523 void PushState(CurrentState state
) {
524 MakeNextState(state
);
527 // Adds a MockCurrentState to the back of the sequence to be returned by the
528 // mock IAppWeb for an ERROR state.
529 void PushErrorState(LONG error_code
,
530 const base::string16
& completion_message
,
531 LONG installer_result_code
) {
532 CComObject
<MockCurrentState
>* mock_state
= MakeNextState(STATE_ERROR
);
533 EXPECT_CALL(*mock_state
, get_errorCode(_
))
534 .WillRepeatedly(DoAll(SetArgPointee
<0>(error_code
), Return(S_OK
)));
535 mock_state
->ExpectCompletionMessage(completion_message
);
536 if (installer_result_code
!= -1) {
537 EXPECT_CALL(*mock_state
, get_installerResultCode(_
))
538 .WillRepeatedly(DoAll(SetArgPointee
<0>(installer_result_code
),
543 // Adds a MockCurrentState to the back of the sequence to be returned by the
544 // mock IAppWeb for an UPDATE_AVAILABLE state.
545 void PushUpdateAvailableState(const base::string16
& new_version
) {
546 MakeNextState(STATE_UPDATE_AVAILABLE
)->ExpectAvailableVersion(new_version
);
549 // Adds a MockCurrentState to the back of the sequence to be returned by the
550 // mock IAppWeb for a DOWNLOADING or INSTALLING state.
551 void PushProgressiveState(CurrentState state
, int progress
) {
552 CComObject
<MockCurrentState
>* mock_state
= MakeNextState(state
);
553 if (state
== STATE_DOWNLOADING
) {
554 const ULONG kTotalBytes
= 1024;
555 ULONG bytes_down
= static_cast<double>(kTotalBytes
) * progress
/ 100.0;
556 EXPECT_CALL(*mock_state
, get_totalBytesToDownload(_
))
557 .WillRepeatedly(DoAll(SetArgPointee
<0>(kTotalBytes
), Return(S_OK
)));
558 EXPECT_CALL(*mock_state
, get_bytesDownloaded(_
))
559 .WillRepeatedly(DoAll(SetArgPointee
<0>(bytes_down
), Return(S_OK
)));
560 } else if (state
== STATE_INSTALLING
) {
561 EXPECT_CALL(*mock_state
, get_installProgress(_
))
562 .WillRepeatedly(DoAll(SetArgPointee
<0>(progress
), Return(S_OK
)));
564 ADD_FAILURE() << "unsupported state " << state
;
568 static const base::char16 kClients
[];
569 static const base::char16 kClientState
[];
570 static const base::char16 kChromeGuid
[];
571 static const base::char16 kChromeBinariesGuid
[];
573 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
574 base::ThreadTaskRunnerHandle task_runner_handle_
;
575 bool system_level_install_
;
576 scoped_ptr
<base::ScopedPathOverride
> file_exe_override_
;
577 scoped_ptr
<base::ScopedPathOverride
> program_files_override_
;
578 scoped_ptr
<base::ScopedPathOverride
> program_files_x86_override_
;
579 scoped_ptr
<base::ScopedPathOverride
> local_app_data_override_
;
580 registry_util::RegistryOverrideManager registry_override_manager_
;
582 // A mock object, the OnUpdateCheckCallback method of which will be invoked
583 // each time the update check machinery invokes the given UpdateCheckCallback.
584 StrictMock
<MockUpdateCheckDelegate
> mock_update_check_delegate_
;
586 // A mock object that provides a GoogleUpdate3ClassFactory by which the test
587 // fixture's IGoogleUpdate3Web simulator is provided to the update check
589 StrictMock
<MockGoogleUpdateFactory
> mock_google_update_factory_
;
591 // The mock objects that simulate the IGoogleUpdate3Web API.
592 CComObject
<MockApp
>* mock_app_
;
593 CComObject
<MockAppBundle
>* mock_app_bundle_
;
595 // A gmock sequence under which expectations on the MockApp are evaluated.
596 Sequence state_sequence_
;
598 // The states returned by the MockApp when probed.
599 std::queue
<CComObject
<MockCurrentState
>*> states_
;
601 // The new version that the fixture will pretend is available.
602 base::string16 new_version_
;
605 // Returns a new MockCurrentState that will be returned by the mock IAppWeb's
606 // get_currentState method.
607 CComObject
<MockCurrentState
>* MakeNextState(CurrentState state
) {
608 CComObject
<MockCurrentState
>* mock_state
= nullptr;
609 // The new object's refcount is held at zero until it is released from the
610 // simulator in GetNextState.
611 EXPECT_EQ(S_OK
, CComObject
<MockCurrentState
>::CreateInstance(&mock_state
));
612 EXPECT_CALL(*mock_state
, get_stateValue(_
))
613 .WillRepeatedly(DoAll(SetArgPointee
<0>(state
), Return(S_OK
)));
614 states_
.push(mock_state
);
615 // Tell the app to expect this state.
616 EXPECT_CALL(*mock_app_
, get_currentState(_
))
617 .InSequence(state_sequence_
);
621 // An implementation of IAppWeb::get_currentState that advances the
622 // IGoogleUpdate3Web simulator through a series of states.
623 HRESULT
GetNextState(IDispatch
** current_state
) {
624 EXPECT_FALSE(states_
.empty());
625 *current_state
= states_
.front();
626 // Give a reference to the caller.
627 (*current_state
)->AddRef();
632 DISALLOW_COPY_AND_ASSIGN(GoogleUpdateWinTest
);
636 const base::char16
GoogleUpdateWinTest::kClients
[] =
637 L
"Software\\Google\\Update\\Clients";
638 const base::char16
GoogleUpdateWinTest::kClientState
[] =
639 L
"Software\\Google\\Update\\ClientState";
640 const base::char16
GoogleUpdateWinTest::kChromeGuid
[] =
641 L
"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
642 const base::char16
GoogleUpdateWinTest::kChromeBinariesGuid
[] =
643 L
"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
645 // Test that an update check fails with the proper error code if Chrome isn't in
646 // one of the expected install directories.
647 TEST_P(GoogleUpdateWinTest
, InvalidInstallDirectory
) {
648 // Override FILE_EXE so that it looks like the test is running from a
649 // non-standard location.
650 base::FilePath file_exe
;
651 base::FilePath dir_temp
;
652 ASSERT_TRUE(PathService::Get(base::FILE_EXE
, &file_exe
));
653 ASSERT_TRUE(PathService::Get(base::DIR_TEMP
, &dir_temp
));
654 file_exe_override_
.reset();
655 file_exe_override_
.reset(new base::ScopedPathOverride(
656 base::FILE_EXE
, dir_temp
.Append(file_exe
.BaseName()),
657 true /* is_absolute */, false /* create */));
659 EXPECT_CALL(mock_update_check_delegate_
,
660 OnError(CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY
, _
, _
));
661 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
662 mock_update_check_delegate_
.AsWeakPtr());
663 task_runner_
->RunUntilIdle();
666 // Test the case where the GoogleUpdate class can't be created for an update
668 TEST_P(GoogleUpdateWinTest
, NoGoogleUpdateForCheck
) {
669 // The factory should be called upon: let it fail.
670 EXPECT_CALL(mock_google_update_factory_
, Create(_
));
672 // Expect the appropriate error when the on-demand class cannot be created.
673 EXPECT_CALL(mock_update_check_delegate_
,
674 OnError(GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND
, _
, _
));
675 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
676 mock_update_check_delegate_
.AsWeakPtr());
677 task_runner_
->RunUntilIdle();
680 // Test the case where the GoogleUpdate class can't be created for an upgrade.
681 TEST_P(GoogleUpdateWinTest
, NoGoogleUpdateForUpgrade
) {
682 // The factory should be called upon: let it fail.
683 EXPECT_CALL(mock_google_update_factory_
, Create(_
));
685 // Expect the appropriate error when the on-demand class cannot be created.
686 EXPECT_CALL(mock_update_check_delegate_
,
687 OnError(GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND
, _
, _
));
688 BeginUpdateCheck(task_runner_
, std::string(), true, 0,
689 mock_update_check_delegate_
.AsWeakPtr());
690 task_runner_
->RunUntilIdle();
693 // Test the case where the GoogleUpdate class returns an error when an update
695 TEST_P(GoogleUpdateWinTest
, FailUpdateCheck
) {
696 // The factory should be called upon: let it return the mock on-demand class.
697 PrepareSimulator(kChromeBinariesGuid
);
698 // checkForUpdate will fail.
699 EXPECT_CALL(*mock_app_bundle_
, checkForUpdate())
700 .WillOnce(Return(E_FAIL
));
702 EXPECT_CALL(mock_update_check_delegate_
,
703 OnError(GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR
, _
, _
));
704 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
705 mock_update_check_delegate_
.AsWeakPtr());
706 task_runner_
->RunUntilIdle();
709 // Test the case where the GoogleUpdate class reports that updates are disabled
711 TEST_P(GoogleUpdateWinTest
, UpdatesDisabledByPolicy
) {
712 static const HRESULT GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY
= 0x80040813;
713 PrepareSimulatorForUpdateCheck(kChromeBinariesGuid
);
714 PushState(STATE_INIT
);
715 PushState(STATE_CHECKING_FOR_UPDATE
);
716 PushErrorState(GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY
,
717 L
"disabled by policy", -1);
719 EXPECT_CALL(mock_update_check_delegate_
,
720 OnError(GOOGLE_UPDATE_DISABLED_BY_POLICY
, _
, _
));
721 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
722 mock_update_check_delegate_
.AsWeakPtr());
723 task_runner_
->RunUntilIdle();
726 // Test the case where the GoogleUpdate class reports that manual updates are
727 // disabled by Group Policy, but that automatic updates are enabled.
728 TEST_P(GoogleUpdateWinTest
, ManualUpdatesDisabledByPolicy
) {
729 static const HRESULT GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY_MANUAL
=
731 PrepareSimulatorForUpdateCheck(kChromeBinariesGuid
);
732 PushState(STATE_INIT
);
733 PushState(STATE_CHECKING_FOR_UPDATE
);
734 PushErrorState(GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY_MANUAL
,
735 L
"manual updates disabled by policy", -1);
737 EXPECT_CALL(mock_update_check_delegate_
,
738 OnError(GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY
, _
, _
));
739 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
740 mock_update_check_delegate_
.AsWeakPtr());
741 task_runner_
->RunUntilIdle();
744 // Test an update check where no update is available.
745 TEST_P(GoogleUpdateWinTest
, UpdateCheckNoUpdate
) {
746 PrepareSimulatorForUpdateCheck(kChromeBinariesGuid
);
747 PushState(STATE_INIT
);
748 PushState(STATE_CHECKING_FOR_UPDATE
);
749 PushState(STATE_NO_UPDATE
);
751 EXPECT_CALL(mock_update_check_delegate_
,
752 OnUpdateCheckComplete(IsEmpty())); // new_version
753 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
754 mock_update_check_delegate_
.AsWeakPtr());
755 task_runner_
->RunUntilIdle();
758 // Test an update check where an update is available.
759 TEST_P(GoogleUpdateWinTest
, UpdateCheckUpdateAvailable
) {
760 PrepareSimulatorForUpdateCheck(kChromeBinariesGuid
);
761 PushState(STATE_INIT
);
762 PushState(STATE_CHECKING_FOR_UPDATE
);
763 PushUpdateAvailableState(new_version_
);
765 EXPECT_CALL(mock_update_check_delegate_
,
766 OnUpdateCheckComplete(StrEq(new_version_
)));
767 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
768 mock_update_check_delegate_
.AsWeakPtr());
769 task_runner_
->RunUntilIdle();
772 // Test a successful upgrade.
773 TEST_P(GoogleUpdateWinTest
, UpdateInstalled
) {
774 PrepareSimulatorForUpgrade(kChromeBinariesGuid
);
775 PushState(STATE_INIT
);
776 PushState(STATE_CHECKING_FOR_UPDATE
);
777 PushUpdateAvailableState(new_version_
);
778 PushState(STATE_WAITING_TO_DOWNLOAD
);
779 PushProgressiveState(STATE_DOWNLOADING
, 0);
780 PushProgressiveState(STATE_DOWNLOADING
, 25);
781 PushProgressiveState(STATE_DOWNLOADING
, 25);
782 PushProgressiveState(STATE_DOWNLOADING
, 75);
783 PushState(STATE_WAITING_TO_INSTALL
);
784 PushProgressiveState(STATE_INSTALLING
, 50);
785 PushState(STATE_INSTALL_COMPLETE
);
788 InSequence callback_sequence
;
789 EXPECT_CALL(mock_update_check_delegate_
,
790 OnUpgradeProgress(0, StrEq(new_version_
)));
791 EXPECT_CALL(mock_update_check_delegate_
,
792 OnUpgradeProgress(12, StrEq(new_version_
)));
793 EXPECT_CALL(mock_update_check_delegate_
,
794 OnUpgradeProgress(37, StrEq(new_version_
)));
795 EXPECT_CALL(mock_update_check_delegate_
,
796 OnUpgradeProgress(50, StrEq(new_version_
)));
797 EXPECT_CALL(mock_update_check_delegate_
,
798 OnUpgradeProgress(75, StrEq(new_version_
)));
799 EXPECT_CALL(mock_update_check_delegate_
,
800 OnUpgradeComplete(StrEq(new_version_
)));
802 BeginUpdateCheck(task_runner_
, std::string(), true, 0,
803 mock_update_check_delegate_
.AsWeakPtr());
804 task_runner_
->RunUntilIdle();
807 // Test a failed upgrade where Google Update reports that the installer failed.
808 TEST_P(GoogleUpdateWinTest
, UpdateFailed
) {
809 const base::string16
error(L
"It didn't work.");
810 static const HRESULT GOOPDATEINSTALL_E_INSTALLER_FAILED
= 0x80040902;
811 static const int kInstallerError
= 12;
813 PrepareSimulatorForUpgrade(kChromeBinariesGuid
);
814 PushState(STATE_INIT
);
815 PushState(STATE_CHECKING_FOR_UPDATE
);
816 PushUpdateAvailableState(new_version_
);
817 PushState(STATE_WAITING_TO_DOWNLOAD
);
818 PushProgressiveState(STATE_DOWNLOADING
, 0);
819 PushProgressiveState(STATE_DOWNLOADING
, 25);
820 PushProgressiveState(STATE_DOWNLOADING
, 25);
821 PushProgressiveState(STATE_DOWNLOADING
, 75);
822 PushState(STATE_WAITING_TO_INSTALL
);
823 PushProgressiveState(STATE_INSTALLING
, 50);
824 PushErrorState(GOOPDATEINSTALL_E_INSTALLER_FAILED
, error
, kInstallerError
);
827 InSequence callback_sequence
;
828 EXPECT_CALL(mock_update_check_delegate_
,
829 OnUpgradeProgress(0, StrEq(new_version_
)));
830 EXPECT_CALL(mock_update_check_delegate_
,
831 OnUpgradeProgress(12, StrEq(new_version_
)));
832 EXPECT_CALL(mock_update_check_delegate_
,
833 OnUpgradeProgress(37, StrEq(new_version_
)));
834 EXPECT_CALL(mock_update_check_delegate_
,
835 OnUpgradeProgress(50, StrEq(new_version_
)));
836 EXPECT_CALL(mock_update_check_delegate_
,
837 OnUpgradeProgress(75, StrEq(new_version_
)));
838 EXPECT_CALL(mock_update_check_delegate_
,
839 OnError(GOOGLE_UPDATE_ERROR_UPDATING
, HasSubstr(error
),
840 StrEq(new_version_
)));
842 BeginUpdateCheck(task_runner_
, std::string(), true, 0,
843 mock_update_check_delegate_
.AsWeakPtr());
844 task_runner_
->RunUntilIdle();
847 INSTANTIATE_TEST_CASE_P(UserLevel
, GoogleUpdateWinTest
, Values(false));
849 INSTANTIATE_TEST_CASE_P(SystemLevel
, GoogleUpdateWinTest
, Values(true));