Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / google / google_update_win_unittest.cc
blob3b63c21d826001679a6389a54b64eeadd170006b
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"
7 #include <windows.h>
8 #include <atlbase.h>
9 #include <atlcom.h>
11 #include <queue>
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"
32 #include "version.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;
47 using ::testing::_;
49 namespace {
51 class MockUpdateCheckDelegate : public UpdateCheckDelegate {
52 public:
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&));
66 private:
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
73 // instance.
74 class GoogleUpdateFactory {
75 public:
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 {
83 public:
84 MockGoogleUpdateFactory() {}
85 MOCK_METHOD1(Create, HRESULT(base::win::ScopedComPtr<IGoogleUpdate3Web>*));
87 private:
88 DISALLOW_COPY_AND_ASSIGN(MockGoogleUpdateFactory);
91 class MockCurrentState : public CComObjectRootEx<CComSingleThreadModel>,
92 public ICurrentState {
93 public:
94 BEGIN_COM_MAP(MockCurrentState)
95 COM_INTERFACE_ENTRY(ICurrentState)
96 END_COM_MAP()
98 MockCurrentState() {}
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(_))
105 .WillRepeatedly(
106 ::testing::Invoke(this, &MockCurrentState::GetCompletionMessage));
109 HRESULT GetCompletionMessage(BSTR* completion_message) {
110 *completion_message = SysAllocString(completion_message_.c_str());
111 return S_OK;
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(_))
119 .WillRepeatedly(
120 ::testing::Invoke(this, &MockCurrentState::GetAvailableVersion));
123 HRESULT GetAvailableVersion(BSTR* available_version) {
124 *available_version = SysAllocString(available_version_.c_str());
125 return S_OK;
128 // ICurrentState:
129 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
130 get_stateValue,
131 HRESULT(LONG *));
132 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
133 get_availableVersion,
134 HRESULT(BSTR *));
135 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
136 get_bytesDownloaded,
137 HRESULT(ULONG *));
138 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
139 get_totalBytesToDownload,
140 HRESULT(ULONG *));
141 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
142 get_downloadTimeRemainingMs,
143 HRESULT(LONG *));
144 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
145 get_nextRetryTime,
146 HRESULT(ULONGLONG *));
147 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
148 get_installProgress,
149 HRESULT(LONG *));
150 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
151 get_installTimeRemainingMs,
152 HRESULT(LONG *));
153 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
154 get_isCanceled,
155 HRESULT(VARIANT_BOOL *));
156 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
157 get_errorCode,
158 HRESULT(LONG *));
159 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
160 get_extraCode1,
161 HRESULT(LONG *));
162 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
163 get_completionMessage,
164 HRESULT(BSTR *));
165 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
166 get_installerResultCode,
167 HRESULT(LONG *));
168 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
169 get_installerResultExtraCode1,
170 HRESULT(LONG *));
171 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
172 get_postInstallLaunchCommandLine,
173 HRESULT(BSTR *));
174 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
175 get_postInstallUrl,
176 HRESULT(BSTR *));
177 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
178 get_postInstallAction,
179 HRESULT(LONG *));
181 // IDispatch:
182 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
183 GetTypeInfoCount,
184 HRESULT(UINT *));
185 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
186 GetTypeInfo,
187 HRESULT(UINT, LCID, ITypeInfo **));
188 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE,
189 GetIDsOfNames,
190 HRESULT(REFIID, LPOLESTR *, UINT, LCID, DISPID *));
191 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE,
192 Invoke,
193 HRESULT(DISPID, REFIID, LCID, WORD, DISPPARAMS *,
194 VARIANT *, EXCEPINFO *, UINT *));
196 private:
197 base::string16 completion_message_;
198 base::string16 available_version_;
200 DISALLOW_COPY_AND_ASSIGN(MockCurrentState);
203 class MockApp : public CComObjectRootEx<CComSingleThreadModel>, public IAppWeb {
204 public:
205 BEGIN_COM_MAP(MockApp)
206 COM_INTERFACE_ENTRY(IAppWeb)
207 END_COM_MAP()
209 MockApp() {}
211 // IAppWeb:
212 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
213 get_appId,
214 HRESULT(BSTR *));
215 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
216 get_currentVersionWeb,
217 HRESULT(IDispatch **));
218 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
219 get_nextVersionWeb,
220 HRESULT(IDispatch **));
221 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
222 get_command,
223 HRESULT(BSTR, IDispatch **));
224 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
225 cancel,
226 HRESULT());
227 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
228 get_currentState,
229 HRESULT(IDispatch **));
230 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
231 launch,
232 HRESULT());
233 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
234 uninstall,
235 HRESULT());
237 // IDispatch:
238 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
239 GetTypeInfoCount,
240 HRESULT(UINT *));
241 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
242 GetTypeInfo,
243 HRESULT(UINT, LCID, ITypeInfo **));
244 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE,
245 GetIDsOfNames,
246 HRESULT(REFIID, LPOLESTR *, UINT, LCID, DISPID *));
247 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE,
248 Invoke,
249 HRESULT(DISPID, REFIID, LCID, WORD, DISPPARAMS *,
250 VARIANT *, EXCEPINFO *, UINT *));
252 private:
253 DISALLOW_COPY_AND_ASSIGN(MockApp);
256 class MockAppBundle : public CComObjectRootEx<CComSingleThreadModel>,
257 public IAppBundleWeb {
258 public:
259 BEGIN_COM_MAP(MockAppBundle)
260 COM_INTERFACE_ENTRY(IAppBundleWeb)
261 END_COM_MAP()
263 MockAppBundle() {}
265 // IAppBundleWeb:
266 MOCK_METHOD4_WITH_CALLTYPE(STDMETHODCALLTYPE,
267 createApp,
268 HRESULT(BSTR, BSTR, BSTR, BSTR));
269 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
270 createInstalledApp,
271 HRESULT(BSTR));
272 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
273 createAllInstalledApps,
274 HRESULT());
275 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
276 get_displayLanguage,
277 HRESULT(BSTR *));
278 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
279 put_displayLanguage,
280 HRESULT(BSTR));
281 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
282 put_parentHWND,
283 HRESULT(ULONG_PTR));
284 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
285 get_length,
286 HRESULT(int *));
287 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
288 get_appWeb,
289 HRESULT(int, IDispatch **));
290 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
291 initialize,
292 HRESULT());
293 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
294 checkForUpdate,
295 HRESULT());
296 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
297 download,
298 HRESULT());
299 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
300 install,
301 HRESULT());
302 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
303 pause,
304 HRESULT());
305 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
306 resume,
307 HRESULT());
308 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
309 cancel,
310 HRESULT());
311 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
312 downloadPackage,
313 HRESULT(BSTR, BSTR));
314 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
315 get_currentState,
316 HRESULT(VARIANT *));
318 // IDispatch:
319 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
320 GetTypeInfoCount,
321 HRESULT(UINT *));
322 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
323 GetTypeInfo,
324 HRESULT(UINT, LCID, ITypeInfo **));
325 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE,
326 GetIDsOfNames,
327 HRESULT(REFIID, LPOLESTR *, UINT, LCID, DISPID *));
328 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE,
329 Invoke,
330 HRESULT(DISPID, REFIID, LCID, WORD, DISPPARAMS *,
331 VARIANT *, EXCEPINFO *, UINT *));
333 private:
334 DISALLOW_COPY_AND_ASSIGN(MockAppBundle);
337 class MockGoogleUpdate : public CComObjectRootEx<CComSingleThreadModel>,
338 public IGoogleUpdate3Web {
339 public:
340 BEGIN_COM_MAP(MockGoogleUpdate)
341 COM_INTERFACE_ENTRY(IGoogleUpdate3Web)
342 END_COM_MAP()
344 MockGoogleUpdate() {}
346 // IGoogleUpdate3Web:
347 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
348 createAppBundleWeb,
349 HRESULT(IDispatch**));
351 // IDispatch:
352 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
353 GetTypeInfoCount,
354 HRESULT(UINT *));
355 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
356 GetTypeInfo,
357 HRESULT(UINT, LCID, ITypeInfo **));
358 MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE,
359 GetIDsOfNames,
360 HRESULT(REFIID, LPOLESTR *, UINT, LCID, DISPID *));
361 MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE,
362 Invoke,
363 HRESULT(DISPID, REFIID, LCID, WORD, DISPPARAMS *,
364 VARIANT *, EXCEPINFO *, UINT *));
366 DISALLOW_COPY_AND_ASSIGN(MockGoogleUpdate);
369 } // namespace
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> {
376 public:
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(); }
385 protected:
386 GoogleUpdateWinTest()
387 : task_runner_(new base::TestSimpleTaskRunner()),
388 task_runner_handle_(task_runner_),
389 system_level_install_(GetParam()),
390 mock_app_(nullptr),
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.
408 base::FilePath temp;
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.
424 const HKEY root =
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,
430 key.WriteValue(
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.
473 ASSERT_EQ(S_OK,
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.
481 mock_app_->AddRef();
482 EXPECT_CALL(*mock_app_bundle_, get_appWeb(0, _))
483 .WillOnce(DoAll(SetArgPointee<1>(mock_app_),
484 Assign(&mock_app_, nullptr),
485 Return(S_OK)));
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
492 // created.
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),
497 Return(S_OK)));
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
522 // mock IAppWeb.
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),
539 Return(S_OK)));
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)));
563 } else {
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
588 // machinery.
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_;
604 private:
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_);
618 return mock_state;
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();
628 states_.pop();
629 return S_OK;
632 DISALLOW_COPY_AND_ASSIGN(GoogleUpdateWinTest);
635 // static
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
667 // check.
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
694 // check is started.
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
710 // by Group Policy.
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));