Report HTTPS links in MalwareDetails. This is only sent if
[chromium-blink-merge.git] / chrome / installer / setup / install_worker_unittest.cc
blobc288549f5de363a9f732721bf54b1da7a74edebd
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 "base/win/registry.h"
8 #include "base/version.h"
9 #include "chrome/common/chrome_constants.h"
10 #include "chrome/installer/setup/setup_util.h"
11 #include "chrome/installer/util/delete_reg_key_work_item.h"
12 #include "chrome/installer/util/create_reg_key_work_item.h"
13 #include "chrome/installer/util/helper.h"
14 #include "chrome/installer/util/google_update_constants.h"
15 #include "chrome/installer/util/installation_state.h"
16 #include "chrome/installer/util/installer_state.h"
17 #include "chrome/installer/util/set_reg_value_work_item.h"
18 #include "chrome/installer/util/util_constants.h"
19 #include "chrome/installer/util/work_item_list.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "testing/gmock/include/gmock/gmock.h"
24 using base::win::RegKey;
25 using installer::InstallationState;
26 using installer::InstallerState;
27 using installer::Product;
28 using installer::ProductState;
30 using ::testing::_;
31 using ::testing::AtLeast;
32 using ::testing::AtMost;
33 using ::testing::Bool;
34 using ::testing::Combine;
35 using ::testing::HasSubstr;
36 using ::testing::Eq;
37 using ::testing::Return;
38 using ::testing::StrCaseEq;
39 using ::testing::StrEq;
40 using ::testing::StrictMock;
41 using ::testing::Values;
43 // Mock classes to help with testing
44 //------------------------------------------------------------------------------
46 class MockWorkItemList : public WorkItemList {
47 public:
48 MockWorkItemList() {}
50 MOCK_METHOD4(AddCopyRegKeyWorkItem, WorkItem* (HKEY,
51 const std::wstring&,
52 const std::wstring&,
53 CopyOverWriteOption));
54 MOCK_METHOD5(AddCopyTreeWorkItem, WorkItem*(const std::wstring&,
55 const std::wstring&,
56 const std::wstring&,
57 CopyOverWriteOption,
58 const std::wstring&));
59 MOCK_METHOD1(AddCreateDirWorkItem, WorkItem* (const base::FilePath&));
60 MOCK_METHOD2(AddCreateRegKeyWorkItem, WorkItem* (HKEY, const std::wstring&));
61 MOCK_METHOD2(AddDeleteRegKeyWorkItem, WorkItem* (HKEY, const std::wstring&));
62 MOCK_METHOD3(AddDeleteRegValueWorkItem, WorkItem* (HKEY,
63 const std::wstring&,
64 const std::wstring&));
65 MOCK_METHOD2(AddDeleteTreeWorkItem, WorkItem* (
66 const base::FilePath&,
67 const std::vector<base::FilePath>&));
68 MOCK_METHOD1(AddDeleteTreeWorkItem, WorkItem* (const base::FilePath&));
69 MOCK_METHOD3(AddMoveTreeWorkItem, WorkItem* (const std::wstring&,
70 const std::wstring&,
71 const std::wstring&));
72 // Workaround for gmock problems with disambiguating between string pointers
73 // and DWORD.
74 virtual WorkItem* AddSetRegValueWorkItem(HKEY a1, const std::wstring& a2,
75 const std::wstring& a3, const std::wstring& a4, bool a5) {
76 return AddSetRegStringValueWorkItem(a1, a2, a3, a4, a5);
79 virtual WorkItem* AddSetRegValueWorkItem(HKEY a1, const std::wstring& a2,
80 const std::wstring& a3,
81 DWORD a4, bool a5) {
82 return AddSetRegDwordValueWorkItem(a1, a2, a3, a4, a5);
85 MOCK_METHOD5(AddSetRegStringValueWorkItem, WorkItem*(HKEY,
86 const std::wstring&,
87 const std::wstring&,
88 const std::wstring&,
89 bool));
90 MOCK_METHOD5(AddSetRegDwordValueWorkItem, WorkItem* (HKEY,
91 const std::wstring&,
92 const std::wstring&,
93 DWORD,
94 bool));
95 MOCK_METHOD3(AddSelfRegWorkItem, WorkItem* (const std::wstring&,
96 bool,
97 bool));
100 class MockProductState : public ProductState {
101 public:
102 // Takes ownership of |version|.
103 void set_version(Version* version) { version_.reset(version); }
104 void set_multi_install(bool multi) { multi_install_ = multi; }
105 void set_brand(const std::wstring& brand) { brand_ = brand; }
106 void set_eula_accepted(DWORD eula_accepted) {
107 has_eula_accepted_ = true;
108 eula_accepted_ = eula_accepted;
110 void clear_eula_accepted() { has_eula_accepted_ = false; }
111 void set_usagestats(DWORD usagestats) {
112 has_usagestats_ = true;
113 usagestats_ = usagestats;
115 void clear_usagestats() { has_usagestats_ = false; }
116 void set_oem_install(const std::wstring& oem_install) {
117 has_oem_install_ = true;
118 oem_install_ = oem_install;
120 void clear_oem_install() { has_oem_install_ = false; }
121 void SetUninstallProgram(const base::FilePath& setup_exe) {
122 uninstall_command_ = base::CommandLine(setup_exe);
124 void AddUninstallSwitch(const std::string& option) {
125 uninstall_command_.AppendSwitch(option);
129 // Okay, so this isn't really a mock as such, but it does add setter methods
130 // to make it easier to build custom InstallationStates.
131 class MockInstallationState : public InstallationState {
132 public:
133 // Included for testing.
134 void SetProductState(bool system_install,
135 BrowserDistribution::Type type,
136 const ProductState& product_state) {
137 ProductState& target = (system_install ? system_products_ :
138 user_products_)[IndexFromDistType(type)];
139 target.CopyFrom(product_state);
143 class MockInstallerState : public InstallerState {
144 public:
145 void set_level(Level level) {
146 InstallerState::set_level(level);
149 void set_operation(Operation operation) { operation_ = operation; }
151 void set_state_key(const std::wstring& state_key) {
152 state_key_ = state_key;
155 void set_state_type(BrowserDistribution::Type state_type) {
156 state_type_ = state_type;
159 void set_package_type(PackageType type) {
160 InstallerState::set_package_type(type);
164 // The test fixture
165 //------------------------------------------------------------------------------
167 class InstallWorkerTest : public testing::Test {
168 public:
169 virtual void SetUp() {
170 current_version_.reset(new Version("1.0.0.0"));
171 new_version_.reset(new Version("42.0.0.0"));
173 // Don't bother ensuring that these paths exist. Since we're just
174 // building the work item lists and not running them, they shouldn't
175 // actually be touched.
176 archive_path_ =
177 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z");
178 // TODO(robertshield): Take this from the BrowserDistribution once that
179 // no longer depends on MasterPreferences.
180 installation_path_ =
181 base::FilePath(L"C:\\Program Files\\Google\\Chrome\\");
182 src_path_ = base::FilePath(
183 L"C:\\UnlikelyPath\\Temp\\chrome_123\\source\\Chrome-bin");
184 setup_path_ = base::FilePath(
185 L"C:\\UnlikelyPath\\Temp\\CR_123.tmp\\setup.exe");
186 temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123");
189 virtual void TearDown() {
192 void MaybeAddBinariesToInstallationState(
193 bool system_level,
194 MockInstallationState* installation_state) {
195 if (installation_state->GetProductState(
196 system_level, BrowserDistribution::CHROME_BINARIES) == NULL) {
197 MockProductState product_state;
198 product_state.set_version(new Version(*current_version_));
199 product_state.set_brand(L"TEST");
200 product_state.set_multi_install(true);
201 BrowserDistribution* dist =
202 BrowserDistribution::GetSpecificDistribution(
203 BrowserDistribution::CHROME_BINARIES);
204 base::FilePath install_path =
205 installer::GetChromeInstallPath(system_level, dist);
206 product_state.SetUninstallProgram(
207 install_path.AppendASCII(current_version_->GetString())
208 .Append(installer::kInstallerDir)
209 .Append(installer::kSetupExe));
210 product_state.AddUninstallSwitch(installer::switches::kUninstall);
211 product_state.AddUninstallSwitch(installer::switches::kMultiInstall);
212 if (system_level)
213 product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
214 installation_state->SetProductState(system_level,
215 BrowserDistribution::CHROME_BINARIES,
216 product_state);
220 void AddChromeToInstallationState(
221 bool system_level,
222 bool multi_install,
223 MockInstallationState* installation_state) {
224 if (multi_install)
225 MaybeAddBinariesToInstallationState(system_level, installation_state);
226 MockProductState product_state;
227 product_state.set_version(new Version(*current_version_));
228 product_state.set_multi_install(multi_install);
229 product_state.set_brand(L"TEST");
230 product_state.set_eula_accepted(1);
231 BrowserDistribution* dist =
232 BrowserDistribution::GetSpecificDistribution(
233 BrowserDistribution::CHROME_BROWSER);
234 base::FilePath install_path =
235 installer::GetChromeInstallPath(system_level, dist);
236 product_state.SetUninstallProgram(
237 install_path.AppendASCII(current_version_->GetString())
238 .Append(installer::kInstallerDir)
239 .Append(installer::kSetupExe));
240 product_state.AddUninstallSwitch(installer::switches::kUninstall);
241 if (system_level)
242 product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
243 if (multi_install) {
244 product_state.AddUninstallSwitch(installer::switches::kMultiInstall);
245 product_state.AddUninstallSwitch(installer::switches::kChrome);
248 installation_state->SetProductState(system_level,
249 BrowserDistribution::CHROME_BROWSER,
250 product_state);
253 void AddChromeFrameToInstallationState(
254 bool system_level,
255 bool multi_install,
256 MockInstallationState* installation_state) {
257 if (multi_install)
258 MaybeAddBinariesToInstallationState(system_level, installation_state);
259 MockProductState product_state;
260 product_state.set_version(new Version(*current_version_));
261 product_state.set_multi_install(multi_install);
262 BrowserDistribution* dist =
263 BrowserDistribution::GetSpecificDistribution(
264 multi_install ? BrowserDistribution::CHROME_BINARIES :
265 BrowserDistribution::CHROME_FRAME);
266 base::FilePath install_path =
267 installer::GetChromeInstallPath(system_level, dist);
268 product_state.SetUninstallProgram(
269 install_path.AppendASCII(current_version_->GetString())
270 .Append(installer::kInstallerDir)
271 .Append(installer::kSetupExe));
272 product_state.AddUninstallSwitch(installer::switches::kUninstall);
273 product_state.AddUninstallSwitch(installer::switches::kChromeFrame);
274 if (system_level)
275 product_state.AddUninstallSwitch(installer::switches::kSystemLevel);
276 if (multi_install)
277 product_state.AddUninstallSwitch(installer::switches::kMultiInstall);
279 installation_state->SetProductState(system_level,
280 BrowserDistribution::CHROME_FRAME,
281 product_state);
284 MockInstallationState* BuildChromeInstallationState(bool system_level,
285 bool multi_install) {
286 scoped_ptr<MockInstallationState> installation_state(
287 new MockInstallationState());
288 AddChromeToInstallationState(system_level, multi_install,
289 installation_state.get());
290 return installation_state.release();
293 static MockInstallerState* BuildBasicInstallerState(
294 bool system_install,
295 bool multi_install,
296 const InstallationState& machine_state,
297 InstallerState::Operation operation) {
298 scoped_ptr<MockInstallerState> installer_state(new MockInstallerState());
300 InstallerState::Level level = system_install ?
301 InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL;
302 installer_state->set_level(level);
303 installer_state->set_operation(operation);
304 // Hope this next one isn't checked for now.
305 installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH");
306 installer_state->set_state_type(BrowserDistribution::CHROME_BROWSER);
307 installer_state->set_package_type(multi_install ?
308 InstallerState::MULTI_PACKAGE :
309 InstallerState::SINGLE_PACKAGE);
310 return installer_state.release();
313 static void AddChromeBinariesToInstallerState(
314 const InstallationState& machine_state,
315 MockInstallerState* installer_state) {
316 if (!installer_state->is_multi_install()) {
317 NOTREACHED();
318 return;
320 if (installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES))
321 return;
323 // Fresh install or upgrade?
324 const ProductState* chrome_binaries =
325 machine_state.GetProductState(installer_state->system_install(),
326 BrowserDistribution::CHROME_BINARIES);
327 if (chrome_binaries != NULL) {
328 installer_state->AddProductFromState(BrowserDistribution::CHROME_BINARIES,
329 *chrome_binaries);
330 } else {
331 BrowserDistribution* dist =
332 BrowserDistribution::GetSpecificDistribution(
333 BrowserDistribution::CHROME_BINARIES);
334 scoped_ptr<Product> product(new Product(dist));
335 product->SetOption(installer::kOptionMultiInstall, true);
336 installer_state->AddProduct(&product);
340 static void AddChromeToInstallerState(
341 const InstallationState& machine_state,
342 MockInstallerState* installer_state) {
343 // Fresh install or upgrade?
344 const ProductState* chrome =
345 machine_state.GetProductState(installer_state->system_install(),
346 BrowserDistribution::CHROME_BROWSER);
347 if (chrome != NULL &&
348 chrome->is_multi_install() == installer_state->is_multi_install()) {
349 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER,
350 *chrome);
351 } else {
352 BrowserDistribution* dist =
353 BrowserDistribution::GetSpecificDistribution(
354 BrowserDistribution::CHROME_BROWSER);
355 scoped_ptr<Product> product(new Product(dist));
356 if (installer_state->is_multi_install())
357 product->SetOption(installer::kOptionMultiInstall, true);
358 installer_state->AddProduct(&product);
362 static void AddChromeFrameToInstallerState(
363 const InstallationState& machine_state,
364 MockInstallerState* installer_state) {
365 // Fresh install or upgrade?
366 const ProductState* cf =
367 machine_state.GetProductState(installer_state->system_install(),
368 BrowserDistribution::CHROME_FRAME);
369 if (cf != NULL) {
370 installer_state->AddProductFromState(BrowserDistribution::CHROME_FRAME,
371 *cf);
372 } else {
373 BrowserDistribution* dist =
374 BrowserDistribution::GetSpecificDistribution(
375 BrowserDistribution::CHROME_FRAME);
376 scoped_ptr<Product> product(new Product(dist));
377 if (installer_state->is_multi_install())
378 product->SetOption(installer::kOptionMultiInstall, true);
379 installer_state->AddProduct(&product);
383 static MockInstallerState* BuildChromeInstallerState(
384 bool system_install,
385 bool multi_install,
386 const InstallationState& machine_state,
387 InstallerState::Operation operation) {
388 scoped_ptr<MockInstallerState> installer_state(
389 BuildBasicInstallerState(system_install, multi_install, machine_state,
390 operation));
391 if (multi_install) {
392 // We don't want to include Chrome Binaries for uninstall if the machine
393 // has other products. For simplicity, we check Chrome Frame only.
394 bool machine_has_other_products =
395 machine_state.GetProductState(system_install,
396 BrowserDistribution::CHROME_FRAME) != NULL;
397 if (operation != InstallerState::UNINSTALL || !machine_has_other_products)
398 AddChromeBinariesToInstallerState(machine_state, installer_state.get());
400 AddChromeToInstallerState(machine_state, installer_state.get());
401 return installer_state.release();
404 static MockInstallerState* BuildChromeFrameInstallerState(
405 bool system_install,
406 bool multi_install,
407 const InstallationState& machine_state,
408 InstallerState::Operation operation) {
409 // This method only works for installation/upgrade.
410 DCHECK(operation != InstallerState::UNINSTALL);
411 scoped_ptr<MockInstallerState> installer_state(
412 BuildBasicInstallerState(system_install, multi_install, machine_state,
413 operation));
414 if (multi_install)
415 AddChromeBinariesToInstallerState(machine_state, installer_state.get());
416 AddChromeFrameToInstallerState(machine_state, installer_state.get());
417 return installer_state.release();
420 protected:
421 scoped_ptr<Version> current_version_;
422 scoped_ptr<Version> new_version_;
423 base::FilePath archive_path_;
424 base::FilePath installation_path_;
425 base::FilePath setup_path_;
426 base::FilePath src_path_;
427 base::FilePath temp_dir_;
430 // Tests
431 //------------------------------------------------------------------------------
433 TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) {
434 const bool system_level = true;
435 const bool multi_install = false;
436 MockWorkItemList work_item_list;
438 const HKEY kRegRoot = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
439 static const wchar_t kRegKeyPath[] = L"Software\\Chromium\\test";
440 scoped_ptr<CreateRegKeyWorkItem> create_reg_key_work_item(
441 WorkItem::CreateCreateRegKeyWorkItem(
442 kRegRoot, kRegKeyPath, WorkItem::kWow64Default));
443 scoped_ptr<SetRegValueWorkItem> set_reg_value_work_item(
444 WorkItem::CreateSetRegValueWorkItem(
445 kRegRoot, kRegKeyPath, WorkItem::kWow64Default, L"", L"", false));
447 scoped_ptr<InstallationState> installation_state(
448 BuildChromeInstallationState(system_level, multi_install));
450 scoped_ptr<InstallerState> installer_state(
451 BuildChromeInstallerState(system_level, multi_install,
452 *installation_state,
453 InstallerState::SINGLE_INSTALL_OR_UPDATE));
455 // Set up some expectations.
456 // TODO(robertshield): Set up some real expectations.
457 EXPECT_CALL(work_item_list, AddCopyTreeWorkItem(_, _, _, _, _))
458 .Times(AtLeast(1));
459 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem(_, _))
460 .WillRepeatedly(Return(create_reg_key_work_item.get()));
461 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem(_, _, _, _, _))
462 .WillRepeatedly(Return(set_reg_value_work_item.get()));
464 AddInstallWorkItems(*installation_state.get(),
465 *installer_state.get(),
466 setup_path_,
467 archive_path_,
468 src_path_,
469 temp_dir_,
470 current_version_.get(),
471 *new_version_.get(),
472 &work_item_list);
475 namespace {
477 const wchar_t elevation_key[] =
478 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\"
479 L"{E0A900DF-9611-4446-86BD-4B1D47E7DB2A}";
480 const wchar_t old_elevation_key[] =
481 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\"
482 L"{6C288DD7-76FB-4721-B628-56FAC252E199}";
484 } // namespace
486 // A test class for worker functions that manipulate the old IE low rights
487 // policies.
488 // Parameters:
489 // bool : system_level_
490 // bool : multi_install_
491 class OldIELowRightsTests : public InstallWorkerTest,
492 public ::testing::WithParamInterface<std::tr1::tuple<bool, bool> > {
493 protected:
494 virtual void SetUp() override {
495 InstallWorkerTest::SetUp();
497 const ParamType& param = GetParam();
498 system_level_ = std::tr1::get<0>(param);
499 multi_install_ = std::tr1::get<1>(param);
500 root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
502 installation_state_.reset(new MockInstallationState());
503 AddChromeFrameToInstallationState(system_level_, multi_install_,
504 installation_state_.get());
505 installer_state_.reset(BuildBasicInstallerState(
506 system_level_, multi_install_, *installation_state_,
507 multi_install_ ? InstallerState::MULTI_UPDATE :
508 InstallerState::SINGLE_INSTALL_OR_UPDATE));
509 if (multi_install_)
510 AddChromeBinariesToInstallerState(*installation_state_,
511 installer_state_.get());
512 AddChromeFrameToInstallerState(*installation_state_,
513 installer_state_.get());
516 scoped_ptr<MockInstallationState> installation_state_;
517 scoped_ptr<MockInstallerState> installer_state_;
518 bool system_level_;
519 bool multi_install_;
520 HKEY root_key_;
523 TEST_P(OldIELowRightsTests, AddDeleteOldIELowRightsPolicyWorkItems) {
524 StrictMock<MockWorkItemList> work_item_list;
526 EXPECT_CALL(work_item_list,
527 AddDeleteRegKeyWorkItem(root_key_, StrEq(old_elevation_key)))
528 .Times(1);
530 AddDeleteOldIELowRightsPolicyWorkItems(*installer_state_.get(),
531 &work_item_list);
534 INSTANTIATE_TEST_CASE_P(Variations, OldIELowRightsTests,
535 Combine(Bool(), Bool()));
537 TEST_F(InstallWorkerTest, GoogleUpdateWorkItemsTest) {
538 const bool system_level = true;
539 const bool multi_install = true;
540 MockWorkItemList work_item_list;
542 scoped_ptr<MockInstallationState> installation_state(
543 BuildChromeInstallationState(system_level, false));
545 MockProductState cf_state;
546 cf_state.set_version(new Version(*current_version_));
547 cf_state.set_multi_install(false);
549 installation_state->SetProductState(system_level,
550 BrowserDistribution::CHROME_FRAME, cf_state);
552 scoped_ptr<MockInstallerState> installer_state(
553 BuildChromeInstallerState(system_level, multi_install,
554 *installation_state,
555 InstallerState::MULTI_INSTALL));
557 // Expect the multi Client State key to be created.
558 BrowserDistribution* multi_dist =
559 BrowserDistribution::GetSpecificDistribution(
560 BrowserDistribution::CHROME_BINARIES);
561 std::wstring multi_app_guid(multi_dist->GetAppGuid());
562 std::wstring multi_client_state_suffix(L"ClientState\\" + multi_app_guid);
563 EXPECT_CALL(work_item_list,
564 AddCreateRegKeyWorkItem(_, HasSubstr(multi_client_state_suffix)))
565 .Times(testing::AnyNumber());
567 // Expect ClientStateMedium to be created for system-level installs.
568 EXPECT_CALL(work_item_list,
569 AddCreateRegKeyWorkItem(_, HasSubstr(L"ClientStateMedium\\" +
570 multi_app_guid)))
571 .Times(system_level ? 1 : 0);
573 // Expect to see a set value for the "TEST" brand code in the multi Client
574 // State key.
575 EXPECT_CALL(work_item_list,
576 AddSetRegStringValueWorkItem(_,
577 HasSubstr(multi_client_state_suffix),
578 StrEq(google_update::kRegBrandField),
579 StrEq(L"TEST"),
580 _)).Times(1);
582 // There may also be some calls to set 'ap' values.
583 EXPECT_CALL(work_item_list,
584 AddSetRegStringValueWorkItem(_, _,
585 StrEq(google_update::kRegApField),
586 _, _)).Times(testing::AnyNumber());
588 // Expect "oeminstall" to be cleared.
589 EXPECT_CALL(work_item_list,
590 AddDeleteRegValueWorkItem(
592 HasSubstr(multi_client_state_suffix),
593 StrEq(google_update::kRegOemInstallField))).Times(1);
595 // Expect "eulaaccepted" to set.
596 EXPECT_CALL(work_item_list,
597 AddSetRegDwordValueWorkItem(
599 HasSubstr(multi_client_state_suffix),
600 StrEq(google_update::kRegEULAAceptedField),
601 Eq(static_cast<DWORD>(1)),
602 _)).Times(1);
604 AddGoogleUpdateWorkItems(*installation_state.get(),
605 *installer_state.get(),
606 &work_item_list);
609 // Test that usagestats values are migrated properly.
610 TEST_F(InstallWorkerTest, AddUsageStatsWorkItems) {
611 const bool system_level = true;
612 const bool multi_install = true;
613 MockWorkItemList work_item_list;
615 scoped_ptr<MockInstallationState> installation_state(
616 BuildChromeInstallationState(system_level, multi_install));
618 MockProductState chrome_state;
619 chrome_state.set_version(new Version(*current_version_));
620 chrome_state.set_multi_install(false);
621 chrome_state.set_usagestats(1);
623 installation_state->SetProductState(system_level,
624 BrowserDistribution::CHROME_BROWSER, chrome_state);
626 scoped_ptr<MockInstallerState> installer_state(
627 BuildChromeInstallerState(system_level, multi_install,
628 *installation_state,
629 InstallerState::MULTI_INSTALL));
631 // Expect the multi Client State key to be created.
632 BrowserDistribution* multi_dist =
633 BrowserDistribution::GetSpecificDistribution(
634 BrowserDistribution::CHROME_BINARIES);
635 std::wstring multi_app_guid(multi_dist->GetAppGuid());
636 EXPECT_CALL(work_item_list,
637 AddCreateRegKeyWorkItem(_, HasSubstr(multi_app_guid))).Times(1);
639 // Expect to see a set value for the usagestats in the multi Client State key.
640 EXPECT_CALL(work_item_list,
641 AddSetRegDwordValueWorkItem(
643 HasSubstr(multi_app_guid),
644 StrEq(google_update::kRegUsageStatsField),
645 Eq(static_cast<DWORD>(1)),
646 Eq(true))).Times(1);
648 // Expect to see some values cleaned up from Chrome's keys.
649 BrowserDistribution* chrome_dist =
650 BrowserDistribution::GetSpecificDistribution(
651 BrowserDistribution::CHROME_BROWSER);
652 if (system_level) {
653 EXPECT_CALL(work_item_list,
654 AddDeleteRegValueWorkItem(
656 StrEq(chrome_dist->GetStateMediumKey()),
657 StrEq(google_update::kRegUsageStatsField))).Times(1);
658 EXPECT_CALL(work_item_list,
659 AddDeleteRegValueWorkItem(
660 Eq(HKEY_CURRENT_USER),
661 StrEq(chrome_dist->GetStateKey()),
662 StrEq(google_update::kRegUsageStatsField))).Times(1);
664 EXPECT_CALL(work_item_list,
665 AddDeleteRegValueWorkItem(
666 Eq(installer_state->root_key()),
667 StrEq(chrome_dist->GetStateKey()),
668 StrEq(google_update::kRegUsageStatsField))).Times(1);
670 AddUsageStatsWorkItems(*installation_state.get(),
671 *installer_state.get(),
672 &work_item_list);
675 // The Quick Enable tests only make sense for the Google Chrome build as it
676 // interacts with registry values that are specific to Google Update.
677 #if defined(GOOGLE_CHROME_BUILD)
679 // Test scenarios under which the quick-enable-cf command should not exist after
680 // the run. We're permissive in that we allow the DeleteRegKeyWorkItem even if
681 // it isn't strictly needed.
682 class QuickEnableAbsentTest : public InstallWorkerTest {
683 public:
684 virtual void SetUp() {
685 InstallWorkerTest::SetUp();
686 root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
687 delete_reg_key_item_.reset(WorkItem::CreateDeleteRegKeyWorkItem(
688 root_key_, kRegKeyPath, WorkItem::kWow64Default));
689 machine_state_.reset(new MockInstallationState());
690 EXPECT_CALL(work_item_list_,
691 AddDeleteRegKeyWorkItem(Eq(root_key_), StrCaseEq(kRegKeyPath)))
692 .Times(AtMost(1))
693 .WillRepeatedly(Return(delete_reg_key_item_.get()));
695 virtual void TearDown() {
696 machine_state_.reset();
697 delete_reg_key_item_.reset();
698 root_key_ = NULL;
699 InstallWorkerTest::TearDown();
701 protected:
702 static const bool system_level_ = false;
703 static const wchar_t kRegKeyPath[];
704 HKEY root_key_;
705 scoped_ptr<DeleteRegKeyWorkItem> delete_reg_key_item_;
706 scoped_ptr<MockInstallationState> machine_state_;
707 StrictMock<MockWorkItemList> work_item_list_;
710 const wchar_t QuickEnableAbsentTest::kRegKeyPath[] =
711 L"Software\\Google\\Update\\Clients\\"
712 L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}\\Commands\\quick-enable-cf";
714 TEST_F(QuickEnableAbsentTest, CleanInstallSingleChrome) {
715 // Install single Chrome on a clean system.
716 scoped_ptr<MockInstallerState> installer_state(
717 BuildBasicInstallerState(system_level_, true, *machine_state_,
718 InstallerState::MULTI_UPDATE));
719 AddQuickEnableChromeFrameWorkItems(*installer_state, &work_item_list_);
722 TEST_F(InstallWorkerTest, WillProductBePresentAfterSetup) {
723 BrowserDistribution::Type prod_type_list[] = {
724 BrowserDistribution::CHROME_BROWSER,
725 BrowserDistribution::CHROME_FRAME,
726 // Excluding BrowserDistribution::CHROME_BINARIES, since it is installed
727 // along with other products.
729 enum { // Index into prod_type_list[].
730 TYPE_BROWSER = 0,
731 TYPE_CF,
732 NUM_TYPE // This must appear last.
734 DCHECK(arraysize(prod_type_list) == NUM_TYPE);
735 InstallerState::Operation op_list[] = {
736 InstallerState::UNINSTALL,
737 InstallerState::SINGLE_INSTALL_OR_UPDATE
740 const bool system_level = false;
741 const bool multi_install = true;
743 // Loop over machine states: {No product, Chrome, CF, Chrome + CF}.
744 for (int i_mach = 0; i_mach < (1 << NUM_TYPE); ++i_mach) {
745 // i_mach is the machine state before operation, as bit mask.
746 scoped_ptr<MockInstallationState> machine_state(
747 new MockInstallationState());
748 if ((i_mach & (1 << TYPE_BROWSER)) != 0) { // Add Chrome.
749 AddChromeToInstallationState(system_level, multi_install,
750 machine_state.get());
752 if ((i_mach & (1 << TYPE_CF)) != 0) { // Add Chrome Frame.
753 AddChromeFrameToInstallationState(system_level, multi_install,
754 machine_state.get());
757 // Loop over operations: {uninstall, install/update}.
758 for (int i_op = 0; i_op < arraysize(op_list); ++i_op) {
760 // Loop over product types to operate on: {TYPE_BROWSER, TYPE_CF}.
761 for (int i_type_op = 0; i_type_op < NUM_TYPE; ++i_type_op) {
762 scoped_ptr<InstallerState> installer_state;
763 if (i_type_op == TYPE_BROWSER) {
764 installer_state.reset(BuildChromeInstallerState(
765 system_level, multi_install, *machine_state, op_list[i_op]));
766 } else if (i_type_op == TYPE_CF) {
767 // Skip the CF uninstall case due to limitations in
768 // BuildChromeFrameInstallerState().
769 if (op_list[i_op] == InstallerState::UNINSTALL)
770 continue;
772 installer_state.reset(BuildChromeFrameInstallerState(
773 system_level, multi_install, *machine_state, op_list[i_op]));
774 } else {
775 NOTREACHED();
778 // Calculate the machine state after operation, as bit mask.
779 // If uninstall, remove product with bitwise AND; else add with OR.
780 int mach_after = (op_list[i_op] == InstallerState::UNINSTALL) ?
781 i_mach & ~(1 << i_type_op) : i_mach | (1 << i_type_op);
783 // Verify predicted presence of Chrome Binaries.
784 bool bin_res = installer::WillProductBePresentAfterSetup(
785 *installer_state,
786 *machine_state,
787 BrowserDistribution::CHROME_BINARIES);
788 // Binaries are expected to be present iff any product is installed.
789 bool bin_expect = mach_after != 0;
790 EXPECT_EQ(bin_expect, bin_res);
792 // Loop over product types to check: {TYPE_BROWSER, TYPE_CF}.
793 for (int i_type_check = 0; i_type_check < NUM_TYPE; ++i_type_check) {
794 // Verify predicted presence of product.
795 bool prod_res = installer::WillProductBePresentAfterSetup(
796 *installer_state,
797 *machine_state,
798 prod_type_list[i_type_check]);
799 bool prod_expect = (mach_after & (1 << i_type_check)) != 0;
800 EXPECT_EQ(prod_expect, prod_res);
807 #endif // defined(GOOGLE_CHROME_BUILD)