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 an update check where no update is available.
727 TEST_P(GoogleUpdateWinTest
, UpdateCheckNoUpdate
) {
728 PrepareSimulatorForUpdateCheck(kChromeBinariesGuid
);
729 PushState(STATE_INIT
);
730 PushState(STATE_CHECKING_FOR_UPDATE
);
731 PushState(STATE_NO_UPDATE
);
733 EXPECT_CALL(mock_update_check_delegate_
,
734 OnUpdateCheckComplete(IsEmpty())); // new_version
735 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
736 mock_update_check_delegate_
.AsWeakPtr());
737 task_runner_
->RunUntilIdle();
740 // Test an update check where an update is available.
741 TEST_P(GoogleUpdateWinTest
, UpdateCheckUpdateAvailable
) {
742 PrepareSimulatorForUpdateCheck(kChromeBinariesGuid
);
743 PushState(STATE_INIT
);
744 PushState(STATE_CHECKING_FOR_UPDATE
);
745 PushUpdateAvailableState(new_version_
);
747 EXPECT_CALL(mock_update_check_delegate_
,
748 OnUpdateCheckComplete(StrEq(new_version_
)));
749 BeginUpdateCheck(task_runner_
, std::string(), false, 0,
750 mock_update_check_delegate_
.AsWeakPtr());
751 task_runner_
->RunUntilIdle();
754 // Test a successful upgrade.
755 TEST_P(GoogleUpdateWinTest
, UpdateInstalled
) {
756 PrepareSimulatorForUpgrade(kChromeBinariesGuid
);
757 PushState(STATE_INIT
);
758 PushState(STATE_CHECKING_FOR_UPDATE
);
759 PushUpdateAvailableState(new_version_
);
760 PushState(STATE_WAITING_TO_DOWNLOAD
);
761 PushProgressiveState(STATE_DOWNLOADING
, 0);
762 PushProgressiveState(STATE_DOWNLOADING
, 25);
763 PushProgressiveState(STATE_DOWNLOADING
, 25);
764 PushProgressiveState(STATE_DOWNLOADING
, 75);
765 PushState(STATE_WAITING_TO_INSTALL
);
766 PushProgressiveState(STATE_INSTALLING
, 50);
767 PushState(STATE_INSTALL_COMPLETE
);
770 InSequence callback_sequence
;
771 EXPECT_CALL(mock_update_check_delegate_
,
772 OnUpgradeProgress(0, StrEq(new_version_
)));
773 EXPECT_CALL(mock_update_check_delegate_
,
774 OnUpgradeProgress(12, StrEq(new_version_
)));
775 EXPECT_CALL(mock_update_check_delegate_
,
776 OnUpgradeProgress(37, StrEq(new_version_
)));
777 EXPECT_CALL(mock_update_check_delegate_
,
778 OnUpgradeProgress(50, StrEq(new_version_
)));
779 EXPECT_CALL(mock_update_check_delegate_
,
780 OnUpgradeProgress(75, StrEq(new_version_
)));
781 EXPECT_CALL(mock_update_check_delegate_
,
782 OnUpgradeComplete(StrEq(new_version_
)));
784 BeginUpdateCheck(task_runner_
, std::string(), true, 0,
785 mock_update_check_delegate_
.AsWeakPtr());
786 task_runner_
->RunUntilIdle();
789 // Test a failed upgrade where Google Update reports that the installer failed.
790 TEST_P(GoogleUpdateWinTest
, UpdateFailed
) {
791 const base::string16
error(L
"It didn't work.");
792 static const HRESULT GOOPDATEINSTALL_E_INSTALLER_FAILED
= 0x80040902;
793 static const int kInstallerError
= 12;
795 PrepareSimulatorForUpgrade(kChromeBinariesGuid
);
796 PushState(STATE_INIT
);
797 PushState(STATE_CHECKING_FOR_UPDATE
);
798 PushUpdateAvailableState(new_version_
);
799 PushState(STATE_WAITING_TO_DOWNLOAD
);
800 PushProgressiveState(STATE_DOWNLOADING
, 0);
801 PushProgressiveState(STATE_DOWNLOADING
, 25);
802 PushProgressiveState(STATE_DOWNLOADING
, 25);
803 PushProgressiveState(STATE_DOWNLOADING
, 75);
804 PushState(STATE_WAITING_TO_INSTALL
);
805 PushProgressiveState(STATE_INSTALLING
, 50);
806 PushErrorState(GOOPDATEINSTALL_E_INSTALLER_FAILED
, error
, kInstallerError
);
809 InSequence callback_sequence
;
810 EXPECT_CALL(mock_update_check_delegate_
,
811 OnUpgradeProgress(0, StrEq(new_version_
)));
812 EXPECT_CALL(mock_update_check_delegate_
,
813 OnUpgradeProgress(12, StrEq(new_version_
)));
814 EXPECT_CALL(mock_update_check_delegate_
,
815 OnUpgradeProgress(37, StrEq(new_version_
)));
816 EXPECT_CALL(mock_update_check_delegate_
,
817 OnUpgradeProgress(50, StrEq(new_version_
)));
818 EXPECT_CALL(mock_update_check_delegate_
,
819 OnUpgradeProgress(75, StrEq(new_version_
)));
820 EXPECT_CALL(mock_update_check_delegate_
,
821 OnError(GOOGLE_UPDATE_ERROR_UPDATING
, HasSubstr(error
),
822 StrEq(new_version_
)));
824 BeginUpdateCheck(task_runner_
, std::string(), true, 0,
825 mock_update_check_delegate_
.AsWeakPtr());
826 task_runner_
->RunUntilIdle();
829 INSTANTIATE_TEST_CASE_P(UserLevel
, GoogleUpdateWinTest
, Values(false));
831 INSTANTIATE_TEST_CASE_P(SystemLevel
, GoogleUpdateWinTest
, Values(true));