Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / installer / setup / install_worker_unittest.cc
blob8ff63c36d62310d0c4d2b84ef1a85119ff00e40a
1 // Copyright (c) 2012 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/installer/setup/install_worker.h"
7 #include <vector>
9 #include "base/win/registry.h"
10 #include "base/version.h"
11 #include "chrome/common/chrome_constants.h"
12 #include "chrome/installer/setup/setup_util.h"
13 #include "chrome/installer/util/create_reg_key_work_item.h"
14 #include "chrome/installer/util/delete_reg_key_work_item.h"
15 #include "chrome/installer/util/delete_tree_work_item.h"
16 #include "chrome/installer/util/helper.h"
17 #include "chrome/installer/util/google_update_constants.h"
18 #include "chrome/installer/util/installation_state.h"
19 #include "chrome/installer/util/installer_state.h"
20 #include "chrome/installer/util/set_reg_value_work_item.h"
21 #include "chrome/installer/util/util_constants.h"
22 #include "chrome/installer/util/work_item_list.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "testing/gmock/include/gmock/gmock.h"
27 using base::win::RegKey;
28 using installer::InstallationState;
29 using installer::InstallerState;
30 using installer::Product;
31 using installer::ProductState;
33 using ::testing::_;
34 using ::testing::AnyNumber;
35 using ::testing::AtLeast;
36 using ::testing::AtMost;
37 using ::testing::Bool;
38 using ::testing::Combine;
39 using ::testing::Eq;
40 using ::testing::HasSubstr;
41 using ::testing::NiceMock;
42 using ::testing::Return;
43 using ::testing::StrCaseEq;
44 using ::testing::StrEq;
45 using ::testing::StrictMock;
46 using ::testing::Values;
48 // Mock classes to help with testing
49 //------------------------------------------------------------------------------
51 class MockWorkItemList : public WorkItemList {
52 public:
53 MockWorkItemList() {}
55 MOCK_METHOD5(AddCopyTreeWorkItem,
56 WorkItem*(const std::wstring&,
57 const std::wstring&,
58 const std::wstring&,
59 CopyOverWriteOption,
60 const std::wstring&));
61 MOCK_METHOD1(AddCreateDirWorkItem, WorkItem* (const base::FilePath&));
62 MOCK_METHOD3(AddCreateRegKeyWorkItem,
63 WorkItem*(HKEY, const std::wstring&, REGSAM));
64 MOCK_METHOD3(AddDeleteRegKeyWorkItem,
65 WorkItem*(HKEY, const std::wstring&, REGSAM));
66 MOCK_METHOD4(
67 AddDeleteRegValueWorkItem,
68 WorkItem*(HKEY, const std::wstring&, REGSAM, const std::wstring&));
69 MOCK_METHOD3(AddDeleteTreeWorkItem,
70 WorkItem*(const base::FilePath&,
71 const base::FilePath&,
72 const std::vector<base::FilePath>&));
73 MOCK_METHOD2(AddDeleteTreeWorkItem,
74 WorkItem*(const base::FilePath&, const base::FilePath&));
75 MOCK_METHOD4(AddMoveTreeWorkItem,
76 WorkItem*(const std::wstring&,
77 const std::wstring&,
78 const std::wstring&,
79 MoveTreeOption));
80 // Workaround for gmock problems with disambiguating between string pointers
81 // and DWORD.
82 virtual WorkItem* AddSetRegValueWorkItem(HKEY a1,
83 const std::wstring& a2,
84 REGSAM a3,
85 const std::wstring& a4,
86 const std::wstring& a5,
87 bool a6) {
88 return AddSetRegStringValueWorkItem(a1, a2, a3, a4, a5, a6);
91 virtual WorkItem* AddSetRegValueWorkItem(HKEY a1,
92 const std::wstring& a2,
93 REGSAM a3,
94 const std::wstring& a4,
95 DWORD a5,
96 bool a6) {
97 return AddSetRegDwordValueWorkItem(a1, a2, a3, a4, a5, a6);
100 MOCK_METHOD6(AddSetRegStringValueWorkItem,
101 WorkItem*(HKEY,
102 const std::wstring&,
103 REGSAM,
104 const std::wstring&,
105 const std::wstring&,
106 bool));
107 MOCK_METHOD6(AddSetRegDwordValueWorkItem,
108 WorkItem*(HKEY,
109 const std::wstring&,
110 REGSAM,
111 const std::wstring&,
112 DWORD,
113 bool));
114 MOCK_METHOD3(AddSelfRegWorkItem, WorkItem* (const std::wstring&,
115 bool,
116 bool));
119 class MockProductState : public ProductState {
120 public:
121 // Takes ownership of |version|.
122 void set_version(Version* version) { version_.reset(version); }
123 void set_multi_install(bool multi) { multi_install_ = multi; }
124 void set_brand(const std::wstring& brand) { brand_ = brand; }
125 void set_eula_accepted(DWORD eula_accepted) {
126 has_eula_accepted_ = true;
127 eula_accepted_ = eula_accepted;
129 void clear_eula_accepted() { has_eula_accepted_ = false; }
130 void set_usagestats(DWORD usagestats) {
131 has_usagestats_ = true;
132 usagestats_ = usagestats;
134 void clear_usagestats() { has_usagestats_ = false; }
135 void set_oem_install(const std::wstring& oem_install) {
136 has_oem_install_ = true;
137 oem_install_ = oem_install;
139 void clear_oem_install() { has_oem_install_ = false; }
140 void SetUninstallProgram(const base::FilePath& setup_exe) {
141 uninstall_command_ = base::CommandLine(setup_exe);
143 void AddUninstallSwitch(const std::string& option) {
144 uninstall_command_.AppendSwitch(option);
148 // Okay, so this isn't really a mock as such, but it does add setter methods
149 // to make it easier to build custom InstallationStates.
150 class MockInstallationState : public InstallationState {
151 public:
152 // Included for testing.
153 void SetProductState(bool system_install,
154 BrowserDistribution::Type type,
155 const ProductState& product_state) {
156 ProductState& target = (system_install ? system_products_ :
157 user_products_)[IndexFromDistType(type)];
158 target.CopyFrom(product_state);
162 class MockInstallerState : public InstallerState {
163 public:
164 void set_level(Level level) {
165 InstallerState::set_level(level);
168 void set_operation(Operation operation) { operation_ = operation; }
170 void set_state_key(const std::wstring& state_key) {
171 state_key_ = state_key;
174 void set_state_type(BrowserDistribution::Type state_type) {
175 state_type_ = state_type;
178 void set_package_type(PackageType type) {
179 InstallerState::set_package_type(type);
183 // The test fixture
184 //------------------------------------------------------------------------------
186 class InstallWorkerTest : public testing::Test {
187 public:
188 void SetUp() override {
189 current_version_.reset(new Version("1.0.0.0"));
190 new_version_.reset(new Version("42.0.0.0"));
192 // Don't bother ensuring that these paths exist. Since we're just
193 // building the work item lists and not running them, they shouldn't
194 // actually be touched.
195 archive_path_ =
196 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z");
197 // TODO(robertshield): Take this from the BrowserDistribution once that
198 // no longer depends on MasterPreferences.
199 installation_path_ =
200 base::FilePath(L"C:\\Program Files\\Google\\Chrome\\");
201 src_path_ = base::FilePath(
202 L"C:\\UnlikelyPath\\Temp\\chrome_123\\source\\Chrome-bin");
203 setup_path_ = base::FilePath(
204 L"C:\\UnlikelyPath\\Temp\\CR_123.tmp\\setup.exe");
205 temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123");
208 void TearDown() override {}
210 void MaybeAddBinariesToInstallationState(
211 bool system_level,
212 MockInstallationState* installation_state) {
213 if (installation_state->GetProductState(
214 system_level, BrowserDistribution::CHROME_BINARIES) == NULL) {
215 MockProductState product_state;
216 product_state.set_version(new Version(*current_version_));
217 product_state.set_brand(L"TEST");
218 product_state.set_multi_install(true);
219 BrowserDistribution* dist =
220 BrowserDistribution::GetSpecificDistribution(
221 BrowserDistribution::CHROME_BINARIES);
222 base::FilePath install_path =
223 installer::GetChromeInstallPath(system_level, dist);
224 product_state.SetUninstallProgram(
225 install_path.AppendASCII(current_version_->GetString())
226 .Append(installer::kInstallerDir)
227 .Append(installer::kSetupExe));
228 product_state.AddUninstallSwitch(installer::switches::kUninstall);
229 product_state.AddUninstallSwitch(installer::switches::kMultiInstall);
230 if (system_level)
231 product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
232 installation_state->SetProductState(system_level,
233 BrowserDistribution::CHROME_BINARIES,
234 product_state);
238 void AddChromeToInstallationState(
239 bool system_level,
240 bool multi_install,
241 MockInstallationState* installation_state) {
242 if (multi_install)
243 MaybeAddBinariesToInstallationState(system_level, installation_state);
244 MockProductState product_state;
245 product_state.set_version(new Version(*current_version_));
246 product_state.set_multi_install(multi_install);
247 product_state.set_brand(L"TEST");
248 product_state.set_eula_accepted(1);
249 BrowserDistribution* dist =
250 BrowserDistribution::GetSpecificDistribution(
251 BrowserDistribution::CHROME_BROWSER);
252 base::FilePath install_path =
253 installer::GetChromeInstallPath(system_level, dist);
254 product_state.SetUninstallProgram(
255 install_path.AppendASCII(current_version_->GetString())
256 .Append(installer::kInstallerDir)
257 .Append(installer::kSetupExe));
258 product_state.AddUninstallSwitch(installer::switches::kUninstall);
259 if (system_level)
260 product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
261 if (multi_install) {
262 product_state.AddUninstallSwitch(installer::switches::kMultiInstall);
263 product_state.AddUninstallSwitch(installer::switches::kChrome);
266 installation_state->SetProductState(system_level,
267 BrowserDistribution::CHROME_BROWSER,
268 product_state);
271 void AddChromeFrameToInstallationState(
272 bool system_level,
273 bool multi_install,
274 MockInstallationState* installation_state) {
275 if (multi_install)
276 MaybeAddBinariesToInstallationState(system_level, installation_state);
277 MockProductState product_state;
278 product_state.set_version(new Version(*current_version_));
279 product_state.set_multi_install(multi_install);
280 BrowserDistribution* dist =
281 BrowserDistribution::GetSpecificDistribution(
282 multi_install ? BrowserDistribution::CHROME_BINARIES :
283 BrowserDistribution::CHROME_FRAME);
284 base::FilePath install_path =
285 installer::GetChromeInstallPath(system_level, dist);
286 product_state.SetUninstallProgram(
287 install_path.AppendASCII(current_version_->GetString())
288 .Append(installer::kInstallerDir)
289 .Append(installer::kSetupExe));
290 product_state.AddUninstallSwitch(installer::switches::kUninstall);
291 product_state.AddUninstallSwitch(installer::switches::kChromeFrame);
292 if (system_level)
293 product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
294 if (multi_install)
295 product_state.AddUninstallSwitch(installer::switches::kMultiInstall);
297 installation_state->SetProductState(system_level,
298 BrowserDistribution::CHROME_FRAME,
299 product_state);
302 MockInstallationState* BuildChromeInstallationState(bool system_level,
303 bool multi_install) {
304 scoped_ptr<MockInstallationState> installation_state(
305 new MockInstallationState());
306 AddChromeToInstallationState(system_level, multi_install,
307 installation_state.get());
308 return installation_state.release();
311 static MockInstallerState* BuildBasicInstallerState(
312 bool system_install,
313 bool multi_install,
314 const InstallationState& machine_state,
315 InstallerState::Operation operation) {
316 scoped_ptr<MockInstallerState> installer_state(new MockInstallerState());
318 InstallerState::Level level = system_install ?
319 InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL;
320 installer_state->set_level(level);
321 installer_state->set_operation(operation);
322 // Hope this next one isn't checked for now.
323 installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH");
324 installer_state->set_state_type(BrowserDistribution::CHROME_BROWSER);
325 installer_state->set_package_type(multi_install ?
326 InstallerState::MULTI_PACKAGE :
327 InstallerState::SINGLE_PACKAGE);
328 return installer_state.release();
331 static void AddChromeBinariesToInstallerState(
332 const InstallationState& machine_state,
333 MockInstallerState* installer_state) {
334 if (!installer_state->is_multi_install()) {
335 NOTREACHED();
336 return;
338 if (installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES))
339 return;
341 // Fresh install or upgrade?
342 const ProductState* chrome_binaries =
343 machine_state.GetProductState(installer_state->system_install(),
344 BrowserDistribution::CHROME_BINARIES);
345 if (chrome_binaries != NULL) {
346 installer_state->AddProductFromState(BrowserDistribution::CHROME_BINARIES,
347 *chrome_binaries);
348 } else {
349 BrowserDistribution* dist =
350 BrowserDistribution::GetSpecificDistribution(
351 BrowserDistribution::CHROME_BINARIES);
352 scoped_ptr<Product> product(new Product(dist));
353 product->SetOption(installer::kOptionMultiInstall, true);
354 installer_state->AddProduct(&product);
358 static void AddChromeToInstallerState(
359 const InstallationState& machine_state,
360 MockInstallerState* installer_state) {
361 // Fresh install or upgrade?
362 const ProductState* chrome =
363 machine_state.GetProductState(installer_state->system_install(),
364 BrowserDistribution::CHROME_BROWSER);
365 if (chrome != NULL &&
366 chrome->is_multi_install() == installer_state->is_multi_install()) {
367 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER,
368 *chrome);
369 } else {
370 BrowserDistribution* dist =
371 BrowserDistribution::GetSpecificDistribution(
372 BrowserDistribution::CHROME_BROWSER);
373 scoped_ptr<Product> product(new Product(dist));
374 if (installer_state->is_multi_install())
375 product->SetOption(installer::kOptionMultiInstall, true);
376 installer_state->AddProduct(&product);
380 static void AddChromeFrameToInstallerState(
381 const InstallationState& machine_state,
382 MockInstallerState* installer_state) {
383 // Fresh install or upgrade?
384 const ProductState* cf =
385 machine_state.GetProductState(installer_state->system_install(),
386 BrowserDistribution::CHROME_FRAME);
387 if (cf != NULL) {
388 installer_state->AddProductFromState(BrowserDistribution::CHROME_FRAME,
389 *cf);
390 } else {
391 BrowserDistribution* dist =
392 BrowserDistribution::GetSpecificDistribution(
393 BrowserDistribution::CHROME_FRAME);
394 scoped_ptr<Product> product(new Product(dist));
395 if (installer_state->is_multi_install())
396 product->SetOption(installer::kOptionMultiInstall, true);
397 installer_state->AddProduct(&product);
401 static MockInstallerState* BuildChromeInstallerState(
402 bool system_install,
403 bool multi_install,
404 const InstallationState& machine_state,
405 InstallerState::Operation operation) {
406 scoped_ptr<MockInstallerState> installer_state(
407 BuildBasicInstallerState(system_install, multi_install, machine_state,
408 operation));
409 if (multi_install) {
410 // We don't want to include Chrome Binaries for uninstall if the machine
411 // has other products. For simplicity, we check Chrome Frame only.
412 bool machine_has_other_products =
413 machine_state.GetProductState(system_install,
414 BrowserDistribution::CHROME_FRAME) != NULL;
415 if (operation != InstallerState::UNINSTALL || !machine_has_other_products)
416 AddChromeBinariesToInstallerState(machine_state, installer_state.get());
418 AddChromeToInstallerState(machine_state, installer_state.get());
419 return installer_state.release();
422 static MockInstallerState* BuildChromeFrameInstallerState(
423 bool system_install,
424 bool multi_install,
425 const InstallationState& machine_state,
426 InstallerState::Operation operation) {
427 // This method only works for installation/upgrade.
428 DCHECK(operation != InstallerState::UNINSTALL);
429 scoped_ptr<MockInstallerState> installer_state(
430 BuildBasicInstallerState(system_install, multi_install, machine_state,
431 operation));
432 if (multi_install)
433 AddChromeBinariesToInstallerState(machine_state, installer_state.get());
434 AddChromeFrameToInstallerState(machine_state, installer_state.get());
435 return installer_state.release();
438 protected:
439 scoped_ptr<Version> current_version_;
440 scoped_ptr<Version> new_version_;
441 base::FilePath archive_path_;
442 base::FilePath installation_path_;
443 base::FilePath setup_path_;
444 base::FilePath src_path_;
445 base::FilePath temp_dir_;
448 // Tests
449 //------------------------------------------------------------------------------
451 TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) {
452 const bool system_level = true;
453 const bool multi_install = false;
454 NiceMock<MockWorkItemList> work_item_list;
456 const HKEY kRegRoot = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
457 static const wchar_t kRegKeyPath[] = L"Software\\Chromium\\test";
458 scoped_ptr<CreateRegKeyWorkItem> create_reg_key_work_item(
459 WorkItem::CreateCreateRegKeyWorkItem(
460 kRegRoot, kRegKeyPath, WorkItem::kWow64Default));
461 scoped_ptr<SetRegValueWorkItem> set_reg_value_work_item(
462 WorkItem::CreateSetRegValueWorkItem(
463 kRegRoot, kRegKeyPath, WorkItem::kWow64Default, L"", L"", false));
464 scoped_ptr<DeleteTreeWorkItem> delete_tree_work_item(
465 WorkItem::CreateDeleteTreeWorkItem(base::FilePath(), base::FilePath(),
466 std::vector<base::FilePath>()));
467 scoped_ptr<DeleteRegKeyWorkItem> delete_reg_key_work_item(
468 WorkItem::CreateDeleteRegKeyWorkItem(kRegRoot, kRegKeyPath,
469 WorkItem::kWow64Default));
471 scoped_ptr<InstallationState> installation_state(
472 BuildChromeInstallationState(system_level, multi_install));
474 scoped_ptr<InstallerState> installer_state(
475 BuildChromeInstallerState(system_level, multi_install,
476 *installation_state,
477 InstallerState::SINGLE_INSTALL_OR_UPDATE));
479 // Set up some expectations.
480 // TODO(robertshield): Set up some real expectations.
481 EXPECT_CALL(work_item_list, AddCopyTreeWorkItem(_, _, _, _, _))
482 .Times(AtLeast(1));
483 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem(_, _, _))
484 .WillRepeatedly(Return(create_reg_key_work_item.get()));
485 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem(_, _, _, _, _, _))
486 .WillRepeatedly(Return(set_reg_value_work_item.get()));
487 EXPECT_CALL(work_item_list, AddDeleteTreeWorkItem(_, _))
488 .WillRepeatedly(Return(delete_tree_work_item.get()));
489 EXPECT_CALL(work_item_list, AddDeleteRegKeyWorkItem(_, _, _))
490 .WillRepeatedly(Return(delete_reg_key_work_item.get()));
492 AddInstallWorkItems(*installation_state.get(),
493 *installer_state.get(),
494 setup_path_,
495 archive_path_,
496 src_path_,
497 temp_dir_,
498 current_version_.get(),
499 *new_version_.get(),
500 &work_item_list);
503 namespace {
505 const wchar_t old_elevation_key[] =
506 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\"
507 L"{6C288DD7-76FB-4721-B628-56FAC252E199}";
509 } // namespace
511 // A test class for worker functions that manipulate the old IE low rights
512 // policies.
513 // Parameters:
514 // bool : system_level_
515 // bool : multi_install_
516 class OldIELowRightsTests : public InstallWorkerTest,
517 public ::testing::WithParamInterface<std::tr1::tuple<bool, bool> > {
518 protected:
519 void SetUp() override {
520 InstallWorkerTest::SetUp();
522 const ParamType& param = GetParam();
523 system_level_ = std::tr1::get<0>(param);
524 multi_install_ = std::tr1::get<1>(param);
525 root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
527 installation_state_.reset(new MockInstallationState());
528 AddChromeFrameToInstallationState(system_level_, multi_install_,
529 installation_state_.get());
530 installer_state_.reset(BuildBasicInstallerState(
531 system_level_, multi_install_, *installation_state_,
532 multi_install_ ? InstallerState::MULTI_UPDATE :
533 InstallerState::SINGLE_INSTALL_OR_UPDATE));
534 if (multi_install_)
535 AddChromeBinariesToInstallerState(*installation_state_,
536 installer_state_.get());
537 AddChromeFrameToInstallerState(*installation_state_,
538 installer_state_.get());
541 scoped_ptr<MockInstallationState> installation_state_;
542 scoped_ptr<MockInstallerState> installer_state_;
543 bool system_level_;
544 bool multi_install_;
545 HKEY root_key_;
548 TEST_P(OldIELowRightsTests, AddDeleteOldIELowRightsPolicyWorkItems) {
549 StrictMock<MockWorkItemList> work_item_list;
551 EXPECT_CALL(work_item_list,
552 AddDeleteRegKeyWorkItem(root_key_, StrEq(old_elevation_key), _))
553 .Times(1);
555 AddDeleteOldIELowRightsPolicyWorkItems(*installer_state_.get(),
556 &work_item_list);
559 INSTANTIATE_TEST_CASE_P(Variations, OldIELowRightsTests,
560 Combine(Bool(), Bool()));
562 TEST_F(InstallWorkerTest, GoogleUpdateWorkItemsTest) {
563 const bool system_level = true;
564 const bool multi_install = true;
565 MockWorkItemList work_item_list;
567 // Per-machine single-install Chrome is installed.
568 scoped_ptr<MockInstallationState> installation_state(
569 BuildChromeInstallationState(system_level, false));
571 MockProductState cf_state;
572 cf_state.set_version(new Version(*current_version_));
573 cf_state.set_multi_install(false);
575 // Per-machine single-install Chrome Frame is installed.
576 installation_state->SetProductState(system_level,
577 BrowserDistribution::CHROME_FRAME, cf_state);
579 // Prepare per-machine multi-install Chrome for installation.
580 scoped_ptr<MockInstallerState> installer_state(
581 BuildChromeInstallerState(system_level, multi_install,
582 *installation_state,
583 InstallerState::MULTI_INSTALL));
585 // Expect the multi Client State key to be created for the binaries.
586 #if defined(GOOGLE_CHROME_BUILD)
587 BrowserDistribution* multi_dist =
588 BrowserDistribution::GetSpecificDistribution(
589 BrowserDistribution::CHROME_BINARIES);
590 std::wstring multi_app_guid(multi_dist->GetAppGuid());
591 std::wstring multi_client_state_suffix(L"ClientState\\" + multi_app_guid);
592 std::wstring multi_medium_suffix(L"ClientStateMedium\\" + multi_app_guid);
594 // Expect ClientStateMedium to be created for system-level installs.
595 EXPECT_CALL(work_item_list,
596 AddCreateRegKeyWorkItem(_, HasSubstr(multi_medium_suffix), _))
597 .Times(system_level ? 1 : 0);
598 #else
599 std::wstring multi_client_state_suffix(L"Chromium Binaries");
600 #endif
601 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem(
602 _, HasSubstr(multi_client_state_suffix), _))
603 .Times(AnyNumber());
605 // Expect to see a set value for the "TEST" brand code in the multi Client
606 // State key.
607 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem(
608 _, HasSubstr(multi_client_state_suffix), _,
609 StrEq(google_update::kRegBrandField),
610 StrEq(L"TEST"), _)).Times(1);
612 // There may also be some calls to set 'ap' values.
613 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem(
614 _, _, _, StrEq(google_update::kRegApField), _,
615 _)).Times(AnyNumber());
617 // Expect "oeminstall" to be cleared.
618 EXPECT_CALL(work_item_list, AddDeleteRegValueWorkItem(
619 _, HasSubstr(multi_client_state_suffix), _,
620 StrEq(google_update::kRegOemInstallField)))
621 .Times(1);
623 // Expect "eulaaccepted" to set.
624 EXPECT_CALL(work_item_list, AddSetRegDwordValueWorkItem(
625 _, HasSubstr(multi_client_state_suffix), _,
626 StrEq(google_update::kRegEULAAceptedField),
627 Eq(static_cast<DWORD>(1)), _)).Times(1);
629 AddGoogleUpdateWorkItems(*installation_state.get(),
630 *installer_state.get(),
631 &work_item_list);
634 // Test that usagestats values are migrated properly.
635 TEST_F(InstallWorkerTest, AddUsageStatsWorkItems) {
636 const bool system_level = true;
637 const bool multi_install = true;
638 MockWorkItemList work_item_list;
640 scoped_ptr<MockInstallationState> installation_state(
641 BuildChromeInstallationState(system_level, multi_install));
643 MockProductState chrome_state;
644 chrome_state.set_version(new Version(*current_version_));
645 chrome_state.set_multi_install(false);
646 chrome_state.set_usagestats(1);
648 installation_state->SetProductState(system_level,
649 BrowserDistribution::CHROME_BROWSER, chrome_state);
651 scoped_ptr<MockInstallerState> installer_state(
652 BuildChromeInstallerState(system_level, multi_install,
653 *installation_state,
654 InstallerState::MULTI_INSTALL));
656 // Expect the multi Client State key to be created.
657 BrowserDistribution* multi_dist =
658 BrowserDistribution::GetSpecificDistribution(
659 BrowserDistribution::CHROME_BINARIES);
660 std::wstring multi_app_guid(multi_dist->GetAppGuid());
661 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem(
662 _, HasSubstr(multi_app_guid), _)).Times(1);
664 // Expect to see a set value for the usagestats in the multi Client State key.
665 EXPECT_CALL(work_item_list, AddSetRegDwordValueWorkItem(
666 _, HasSubstr(multi_app_guid), _,
667 StrEq(google_update::kRegUsageStatsField),
668 Eq(static_cast<DWORD>(1)), Eq(true)))
669 .Times(1);
671 // Expect to see some values cleaned up from Chrome's keys.
672 BrowserDistribution* chrome_dist =
673 BrowserDistribution::GetSpecificDistribution(
674 BrowserDistribution::CHROME_BROWSER);
675 if (system_level) {
676 #if defined(GOOGLE_CHROME_BUILD)
677 EXPECT_CALL(work_item_list,
678 AddDeleteRegValueWorkItem(
679 _, StrEq(chrome_dist->GetStateMediumKey()), _,
680 StrEq(google_update::kRegUsageStatsField))).Times(1);
681 #endif
682 EXPECT_CALL(work_item_list,
683 AddDeleteRegValueWorkItem(
684 Eq(HKEY_CURRENT_USER), StrEq(chrome_dist->GetStateKey()), _,
685 StrEq(google_update::kRegUsageStatsField))).Times(1);
687 #if defined(GOOGLE_CHROME_BUILD)
688 const int kDeleteTimes = 1;
689 #else
690 // Expect two deletes to the same key name since ClientState and
691 // ClientStateMedium are identical for Chromium.
692 const int kDeleteTimes = 2;
693 #endif
694 EXPECT_CALL(
695 work_item_list,
696 AddDeleteRegValueWorkItem(
697 Eq(installer_state->root_key()), StrEq(chrome_dist->GetStateKey()), _,
698 StrEq(google_update::kRegUsageStatsField))).Times(kDeleteTimes);
700 AddUsageStatsWorkItems(*installation_state.get(),
701 *installer_state.get(),
702 &work_item_list);
705 // The Quick Enable tests only make sense for the Google Chrome build as it
706 // interacts with registry values that are specific to Google Update.
707 #if defined(GOOGLE_CHROME_BUILD)
709 // Test scenarios under which the quick-enable-cf command should not exist after
710 // the run. We're permissive in that we allow the DeleteRegKeyWorkItem even if
711 // it isn't strictly needed.
712 class QuickEnableAbsentTest : public InstallWorkerTest {
713 public:
714 virtual void SetUp() {
715 InstallWorkerTest::SetUp();
716 root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
717 delete_reg_key_item_.reset(WorkItem::CreateDeleteRegKeyWorkItem(
718 root_key_, kRegKeyPath, WorkItem::kWow64Default));
719 machine_state_.reset(new MockInstallationState());
720 EXPECT_CALL(work_item_list_, AddDeleteRegKeyWorkItem(
721 Eq(root_key_), StrCaseEq(kRegKeyPath), _))
722 .Times(AtMost(1))
723 .WillRepeatedly(Return(delete_reg_key_item_.get()));
725 virtual void TearDown() {
726 machine_state_.reset();
727 delete_reg_key_item_.reset();
728 root_key_ = NULL;
729 InstallWorkerTest::TearDown();
731 protected:
732 static const bool system_level_ = false;
733 static const wchar_t kRegKeyPath[];
734 HKEY root_key_;
735 scoped_ptr<DeleteRegKeyWorkItem> delete_reg_key_item_;
736 scoped_ptr<MockInstallationState> machine_state_;
737 StrictMock<MockWorkItemList> work_item_list_;
740 const wchar_t QuickEnableAbsentTest::kRegKeyPath[] =
741 L"Software\\Google\\Update\\Clients\\"
742 L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}\\Commands\\quick-enable-cf";
744 TEST_F(QuickEnableAbsentTest, CleanInstallSingleChrome) {
745 // Install single Chrome on a clean system.
746 scoped_ptr<MockInstallerState> installer_state(
747 BuildBasicInstallerState(system_level_, true, *machine_state_,
748 InstallerState::MULTI_UPDATE));
749 AddQuickEnableChromeFrameWorkItems(*installer_state, &work_item_list_);
752 TEST_F(InstallWorkerTest, WillProductBePresentAfterSetup) {
753 BrowserDistribution::Type prod_type_list[] = {
754 BrowserDistribution::CHROME_BROWSER,
755 BrowserDistribution::CHROME_FRAME,
756 // Excluding BrowserDistribution::CHROME_BINARIES, since it is installed
757 // along with other products.
759 enum { // Index into prod_type_list[].
760 TYPE_BROWSER = 0,
761 TYPE_CF,
762 NUM_TYPE // This must appear last.
764 DCHECK(arraysize(prod_type_list) == NUM_TYPE);
765 InstallerState::Operation op_list[] = {
766 InstallerState::UNINSTALL,
767 InstallerState::SINGLE_INSTALL_OR_UPDATE
770 const bool system_level = false;
771 const bool multi_install = true;
773 // Loop over machine states: {No product, Chrome, CF, Chrome + CF}.
774 for (int i_mach = 0; i_mach < (1 << NUM_TYPE); ++i_mach) {
775 // i_mach is the machine state before operation, as bit mask.
776 scoped_ptr<MockInstallationState> machine_state(
777 new MockInstallationState());
778 if ((i_mach & (1 << TYPE_BROWSER)) != 0) { // Add Chrome.
779 AddChromeToInstallationState(system_level, multi_install,
780 machine_state.get());
782 if ((i_mach & (1 << TYPE_CF)) != 0) { // Add Chrome Frame.
783 AddChromeFrameToInstallationState(system_level, multi_install,
784 machine_state.get());
787 // Loop over operations: {uninstall, install/update}.
788 for (int i_op = 0; i_op < arraysize(op_list); ++i_op) {
790 // Loop over product types to operate on: {TYPE_BROWSER, TYPE_CF}.
791 for (int i_type_op = 0; i_type_op < NUM_TYPE; ++i_type_op) {
792 scoped_ptr<InstallerState> installer_state;
793 if (i_type_op == TYPE_BROWSER) {
794 installer_state.reset(BuildChromeInstallerState(
795 system_level, multi_install, *machine_state, op_list[i_op]));
796 } else if (i_type_op == TYPE_CF) {
797 // Skip the CF uninstall case due to limitations in
798 // BuildChromeFrameInstallerState().
799 if (op_list[i_op] == InstallerState::UNINSTALL)
800 continue;
802 installer_state.reset(BuildChromeFrameInstallerState(
803 system_level, multi_install, *machine_state, op_list[i_op]));
804 } else {
805 NOTREACHED();
808 // Calculate the machine state after operation, as bit mask.
809 // If uninstall, remove product with bitwise AND; else add with OR.
810 int mach_after = (op_list[i_op] == InstallerState::UNINSTALL) ?
811 i_mach & ~(1 << i_type_op) : i_mach | (1 << i_type_op);
813 // Verify predicted presence of Chrome Binaries.
814 bool bin_res = installer::WillProductBePresentAfterSetup(
815 *installer_state,
816 *machine_state,
817 BrowserDistribution::CHROME_BINARIES);
818 // Binaries are expected to be present iff any product is installed.
819 bool bin_expect = mach_after != 0;
820 EXPECT_EQ(bin_expect, bin_res);
822 // Loop over product types to check: {TYPE_BROWSER, TYPE_CF}.
823 for (int i_type_check = 0; i_type_check < NUM_TYPE; ++i_type_check) {
824 // Verify predicted presence of product.
825 bool prod_res = installer::WillProductBePresentAfterSetup(
826 *installer_state,
827 *machine_state,
828 prod_type_list[i_type_check]);
829 bool prod_expect = (mach_after & (1 << i_type_check)) != 0;
830 EXPECT_EQ(prod_expect, prod_res);
837 #endif // defined(GOOGLE_CHROME_BUILD)