Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / installer / setup / setup_util_unittest.cc
blob1ac23b80fb28cf7e7c88e3a17a8d7762959892bf
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/setup_util_unittest.h"
7 #include <windows.h>
9 #include <string>
11 #include "base/command_line.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/macros.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/process/kill.h"
17 #include "base/process/launch.h"
18 #include "base/process/process_handle.h"
19 #include "base/strings/string_util.h"
20 #include "base/test/test_reg_util_win.h"
21 #include "base/test/test_timeouts.h"
22 #include "base/threading/platform_thread.h"
23 #include "base/version.h"
24 #include "base/win/registry.h"
25 #include "base/win/scoped_handle.h"
26 #include "base/win/windows_version.h"
27 #include "chrome/installer/setup/setup_constants.h"
28 #include "chrome/installer/setup/setup_util.h"
29 #include "chrome/installer/setup/update_active_setup_version_work_item.h"
30 #include "chrome/installer/util/browser_distribution.h"
31 #include "chrome/installer/util/google_update_constants.h"
32 #include "chrome/installer/util/install_util.h"
33 #include "chrome/installer/util/installation_state.h"
34 #include "chrome/installer/util/installer_state.h"
35 #include "chrome/installer/util/updating_app_registration_data.h"
36 #include "chrome/installer/util/util_constants.h"
37 #include "testing/gtest/include/gtest/gtest.h"
39 namespace {
41 // The privilege tested in ScopeTokenPrivilege tests below.
42 // Use SE_RESTORE_NAME as it is one of the many privileges that is available,
43 // but not enabled by default on processes running at high integrity.
44 static const wchar_t kTestedPrivilege[] = SE_RESTORE_NAME;
46 // Returns true if the current process' token has privilege |privilege_name|
47 // enabled.
48 bool CurrentProcessHasPrivilege(const wchar_t* privilege_name) {
49 HANDLE temp_handle;
50 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY,
51 &temp_handle)) {
52 ADD_FAILURE();
53 return false;
56 base::win::ScopedHandle token(temp_handle);
58 // First get the size of the buffer needed for |privileges| below.
59 DWORD size;
60 EXPECT_FALSE(::GetTokenInformation(token.Get(), TokenPrivileges, NULL, 0,
61 &size));
63 scoped_ptr<BYTE[]> privileges_bytes(new BYTE[size]);
64 TOKEN_PRIVILEGES* privileges =
65 reinterpret_cast<TOKEN_PRIVILEGES*>(privileges_bytes.get());
67 if (!::GetTokenInformation(token.Get(), TokenPrivileges, privileges, size,
68 &size)) {
69 ADD_FAILURE();
70 return false;
73 // There is no point getting a buffer to store more than |privilege_name|\0 as
74 // anything longer will obviously not be equal to |privilege_name|.
75 const DWORD desired_size = wcslen(privilege_name);
76 const DWORD buffer_size = desired_size + 1;
77 scoped_ptr<wchar_t[]> name_buffer(new wchar_t[buffer_size]);
78 for (int i = privileges->PrivilegeCount - 1; i >= 0 ; --i) {
79 LUID_AND_ATTRIBUTES& luid_and_att = privileges->Privileges[i];
80 DWORD size = buffer_size;
81 ::LookupPrivilegeName(NULL, &luid_and_att.Luid, name_buffer.get(), &size);
82 if (size == desired_size &&
83 wcscmp(name_buffer.get(), privilege_name) == 0) {
84 return luid_and_att.Attributes == SE_PRIVILEGE_ENABLED;
87 return false;
90 } // namespace
92 TEST(SetupUtilTest, UpdateLastOSUpgradeHandledByActiveSetup) {
93 registry_util::RegistryOverrideManager registry_override_manager;
94 registry_override_manager.OverrideRegistry(HKEY_CURRENT_USER);
95 registry_override_manager.OverrideRegistry(HKEY_LOCAL_MACHINE);
97 BrowserDistribution* chrome_dist =
98 BrowserDistribution::GetSpecificDistribution(
99 BrowserDistribution::CHROME_BROWSER);
100 const base::string16 active_setup_path(
101 InstallUtil::GetActiveSetupPath(chrome_dist));
103 base::win::RegKey test_key;
104 base::string16 unused_tmp;
106 EXPECT_EQ(ERROR_FILE_NOT_FOUND,
107 test_key.Open(HKEY_LOCAL_MACHINE, active_setup_path.c_str(),
108 KEY_QUERY_VALUE));
109 // The WorkItem assume the ActiveSetup key itself already exists and only
110 // handles the Version entry, create it now, but don't fill the "Version"
111 // entry just yet.
112 EXPECT_EQ(ERROR_SUCCESS,
113 test_key.Create(HKEY_LOCAL_MACHINE, active_setup_path.c_str(),
114 KEY_QUERY_VALUE));
115 EXPECT_EQ(ERROR_FILE_NOT_FOUND, test_key.ReadValue(L"Version", &unused_tmp));
117 // Test returns false when no Active Setup version present (and doesn't alter
118 // that state).
119 EXPECT_FALSE(
120 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist));
121 EXPECT_EQ(ERROR_FILE_NOT_FOUND, test_key.ReadValue(L"Version", &unused_tmp));
124 UpdateActiveSetupVersionWorkItem active_setup_work_item(
125 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE);
126 active_setup_work_item.Do();
127 EXPECT_EQ(ERROR_SUCCESS, test_key.ReadValue(L"Version", &unused_tmp));
130 // Test returns false with default Active Setup version.
131 EXPECT_FALSE(
132 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist));
133 EXPECT_EQ(ERROR_SUCCESS, test_key.ReadValue(L"Version", &unused_tmp));
135 // Run through |kIterations| sequences of bumping the OS upgrade version |i|
136 // times and simulating a regular update |kIterations-i| times, confirming
137 // that handling any number of OS upgrades only results in a single hit and
138 // that no amount of regular updates after that result in any hit.
139 const size_t kIterations = 4U;
140 for (size_t i = 0U; i < kIterations; ++i) {
141 SCOPED_TRACE(i);
142 // Bump the OS_UPGRADES component |i| times.
143 for (size_t j = 0; j < i; ++j) {
144 UpdateActiveSetupVersionWorkItem active_setup_work_item(
145 active_setup_path, UpdateActiveSetupVersionWorkItem::
146 UPDATE_AND_BUMP_OS_UPGRADES_COMPONENT);
147 active_setup_work_item.Do();
150 // There should be a single OS upgrade to handle if the OS_UPGRADES
151 // component was bumped at least once.
152 EXPECT_EQ(i > 0, installer::UpdateLastOSUpgradeHandledByActiveSetup(
153 chrome_dist));
155 // We should only be told to handle the latest OS upgrade once above.
156 EXPECT_FALSE(
157 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist));
158 EXPECT_FALSE(
159 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist));
161 // Run |kIterations-i| regular updates.
162 for (size_t j = i; j < kIterations; ++j) {
163 UpdateActiveSetupVersionWorkItem active_setup_work_item(
164 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE);
165 active_setup_work_item.Do();
168 // No amount of regular updates should trigger an OS upgrade to be handled.
169 EXPECT_FALSE(
170 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist));
171 EXPECT_FALSE(
172 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist));
176 // Test that we are parsing Chrome version correctly.
177 TEST(SetupUtilTest, GetMaxVersionFromArchiveDirTest) {
178 // Create a version dir
179 base::ScopedTempDir test_dir;
180 ASSERT_TRUE(test_dir.CreateUniqueTempDir());
181 base::FilePath chrome_dir = test_dir.path().AppendASCII("1.0.0.0");
182 base::CreateDirectory(chrome_dir);
183 ASSERT_TRUE(base::PathExists(chrome_dir));
184 scoped_ptr<Version> version(
185 installer::GetMaxVersionFromArchiveDir(test_dir.path()));
186 ASSERT_EQ(version->GetString(), "1.0.0.0");
188 base::DeleteFile(chrome_dir, true);
189 ASSERT_FALSE(base::PathExists(chrome_dir)) << chrome_dir.value();
190 ASSERT_TRUE(installer::GetMaxVersionFromArchiveDir(test_dir.path()) == NULL);
192 chrome_dir = test_dir.path().AppendASCII("ABC");
193 base::CreateDirectory(chrome_dir);
194 ASSERT_TRUE(base::PathExists(chrome_dir));
195 ASSERT_TRUE(installer::GetMaxVersionFromArchiveDir(test_dir.path()) == NULL);
197 chrome_dir = test_dir.path().AppendASCII("2.3.4.5");
198 base::CreateDirectory(chrome_dir);
199 ASSERT_TRUE(base::PathExists(chrome_dir));
200 version.reset(installer::GetMaxVersionFromArchiveDir(test_dir.path()));
201 ASSERT_EQ(version->GetString(), "2.3.4.5");
203 // Create multiple version dirs, ensure that we select the greatest.
204 chrome_dir = test_dir.path().AppendASCII("9.9.9.9");
205 base::CreateDirectory(chrome_dir);
206 ASSERT_TRUE(base::PathExists(chrome_dir));
207 chrome_dir = test_dir.path().AppendASCII("1.1.1.1");
208 base::CreateDirectory(chrome_dir);
209 ASSERT_TRUE(base::PathExists(chrome_dir));
211 version.reset(installer::GetMaxVersionFromArchiveDir(test_dir.path()));
212 ASSERT_EQ(version->GetString(), "9.9.9.9");
215 TEST(SetupUtilTest, DeleteFileFromTempProcess) {
216 base::ScopedTempDir test_dir;
217 ASSERT_TRUE(test_dir.CreateUniqueTempDir());
218 base::FilePath test_file;
219 base::CreateTemporaryFileInDir(test_dir.path(), &test_file);
220 ASSERT_TRUE(base::PathExists(test_file));
221 base::WriteFile(test_file, "foo", 3);
222 EXPECT_TRUE(installer::DeleteFileFromTempProcess(test_file, 0));
223 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 3);
224 EXPECT_FALSE(base::PathExists(test_file)) << test_file.value();
227 // Note: This test is only valid when run at high integrity (i.e. it will fail
228 // at medium integrity).
229 TEST(SetupUtilTest, ScopedTokenPrivilegeBasic) {
230 ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
233 installer::ScopedTokenPrivilege test_scoped_privilege(kTestedPrivilege);
234 ASSERT_TRUE(test_scoped_privilege.is_enabled());
235 ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
238 ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
241 // Note: This test is only valid when run at high integrity (i.e. it will fail
242 // at medium integrity).
243 TEST(SetupUtilTest, ScopedTokenPrivilegeAlreadyEnabled) {
244 ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
247 installer::ScopedTokenPrivilege test_scoped_privilege(kTestedPrivilege);
248 ASSERT_TRUE(test_scoped_privilege.is_enabled());
249 ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
251 installer::ScopedTokenPrivilege dup_scoped_privilege(kTestedPrivilege);
252 ASSERT_TRUE(dup_scoped_privilege.is_enabled());
253 ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
255 ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
258 ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
261 const char kAdjustProcessPriority[] = "adjust-process-priority";
263 PriorityClassChangeResult DoProcessPriorityAdjustment() {
264 return installer::AdjustProcessPriority() ? PCCR_CHANGED : PCCR_UNCHANGED;
267 namespace {
269 // A scoper that sets/resets the current process's priority class.
270 class ScopedPriorityClass {
271 public:
272 // Applies |priority_class|, returning an instance if a change was made.
273 // Otherwise, returns an empty scoped_ptr.
274 static scoped_ptr<ScopedPriorityClass> Create(DWORD priority_class);
275 ~ScopedPriorityClass();
277 private:
278 explicit ScopedPriorityClass(DWORD original_priority_class);
279 DWORD original_priority_class_;
280 DISALLOW_COPY_AND_ASSIGN(ScopedPriorityClass);
283 scoped_ptr<ScopedPriorityClass> ScopedPriorityClass::Create(
284 DWORD priority_class) {
285 HANDLE this_process = ::GetCurrentProcess();
286 DWORD original_priority_class = ::GetPriorityClass(this_process);
287 EXPECT_NE(0U, original_priority_class);
288 if (original_priority_class && original_priority_class != priority_class) {
289 BOOL result = ::SetPriorityClass(this_process, priority_class);
290 EXPECT_NE(FALSE, result);
291 if (result) {
292 return scoped_ptr<ScopedPriorityClass>(
293 new ScopedPriorityClass(original_priority_class));
296 return scoped_ptr<ScopedPriorityClass>();
299 ScopedPriorityClass::ScopedPriorityClass(DWORD original_priority_class)
300 : original_priority_class_(original_priority_class) {}
302 ScopedPriorityClass::~ScopedPriorityClass() {
303 BOOL result = ::SetPriorityClass(::GetCurrentProcess(),
304 original_priority_class_);
305 EXPECT_NE(FALSE, result);
308 PriorityClassChangeResult RelaunchAndDoProcessPriorityAdjustment() {
309 base::CommandLine cmd_line(*base::CommandLine::ForCurrentProcess());
310 cmd_line.AppendSwitch(kAdjustProcessPriority);
311 base::Process process = base::LaunchProcess(cmd_line, base::LaunchOptions());
312 int exit_code = 0;
313 if (!process.IsValid()) {
314 ADD_FAILURE() << " to launch subprocess.";
315 } else if (!process.WaitForExit(&exit_code)) {
316 ADD_FAILURE() << " to wait for subprocess to exit.";
317 } else {
318 return static_cast<PriorityClassChangeResult>(exit_code);
320 return PCCR_UNKNOWN;
323 } // namespace
325 // Launching a subprocess at normal priority class is a noop.
326 TEST(SetupUtilTest, AdjustFromNormalPriority) {
327 ASSERT_EQ(NORMAL_PRIORITY_CLASS, ::GetPriorityClass(::GetCurrentProcess()));
328 EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment());
331 // Launching a subprocess below normal priority class drops it to bg mode for
332 // sufficiently recent operating systems.
333 TEST(SetupUtilTest, AdjustFromBelowNormalPriority) {
334 scoped_ptr<ScopedPriorityClass> below_normal =
335 ScopedPriorityClass::Create(BELOW_NORMAL_PRIORITY_CLASS);
336 ASSERT_TRUE(below_normal);
337 if (base::win::GetVersion() > base::win::VERSION_SERVER_2003)
338 EXPECT_EQ(PCCR_CHANGED, RelaunchAndDoProcessPriorityAdjustment());
339 else
340 EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment());
343 namespace {
345 // A test fixture that configures an InstallationState and an InstallerState
346 // with a product being updated.
347 class FindArchiveToPatchTest : public testing::Test {
348 protected:
349 class FakeInstallationState : public installer::InstallationState {
352 class FakeProductState : public installer::ProductState {
353 public:
354 static FakeProductState* FromProductState(const ProductState* product) {
355 return static_cast<FakeProductState*>(const_cast<ProductState*>(product));
358 void set_version(const Version& version) {
359 if (version.IsValid())
360 version_.reset(new Version(version));
361 else
362 version_.reset();
365 void set_uninstall_command(const base::CommandLine& uninstall_command) {
366 uninstall_command_ = uninstall_command;
370 FindArchiveToPatchTest() {}
372 void SetUp() override {
373 ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
374 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
375 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE);
376 product_version_ = Version("30.0.1559.0");
377 max_version_ = Version("47.0.1559.0");
379 // Install the product according to the version.
380 original_state_.reset(new FakeInstallationState());
381 InstallProduct();
383 // Prepare to update the product in the temp dir.
384 installer_state_.reset(new installer::InstallerState(
385 kSystemInstall_ ? installer::InstallerState::SYSTEM_LEVEL :
386 installer::InstallerState::USER_LEVEL));
387 installer_state_->AddProductFromState(
388 kProductType_,
389 *original_state_->GetProductState(kSystemInstall_, kProductType_));
391 // Create archives in the two version dirs.
392 ASSERT_TRUE(
393 base::CreateDirectory(GetProductVersionArchivePath().DirName()));
394 ASSERT_EQ(1, base::WriteFile(GetProductVersionArchivePath(), "a", 1));
395 ASSERT_TRUE(
396 base::CreateDirectory(GetMaxVersionArchivePath().DirName()));
397 ASSERT_EQ(1, base::WriteFile(GetMaxVersionArchivePath(), "b", 1));
400 void TearDown() override {
401 original_state_.reset();
404 base::FilePath GetArchivePath(const Version& version) const {
405 return test_dir_.path()
406 .AppendASCII(version.GetString())
407 .Append(installer::kInstallerDir)
408 .Append(installer::kChromeArchive);
411 base::FilePath GetMaxVersionArchivePath() const {
412 return GetArchivePath(max_version_);
415 base::FilePath GetProductVersionArchivePath() const {
416 return GetArchivePath(product_version_);
419 void InstallProduct() {
420 FakeProductState* product = FakeProductState::FromProductState(
421 original_state_->GetNonVersionedProductState(kSystemInstall_,
422 kProductType_));
424 product->set_version(product_version_);
425 base::CommandLine uninstall_command(
426 test_dir_.path()
427 .AppendASCII(product_version_.GetString())
428 .Append(installer::kInstallerDir)
429 .Append(installer::kSetupExe));
430 uninstall_command.AppendSwitch(installer::switches::kUninstall);
431 product->set_uninstall_command(uninstall_command);
434 void UninstallProduct() {
435 FakeProductState::FromProductState(
436 original_state_->GetNonVersionedProductState(kSystemInstall_,
437 kProductType_))
438 ->set_version(Version());
441 static const bool kSystemInstall_;
442 static const BrowserDistribution::Type kProductType_;
443 base::ScopedTempDir test_dir_;
444 Version product_version_;
445 Version max_version_;
446 scoped_ptr<FakeInstallationState> original_state_;
447 scoped_ptr<installer::InstallerState> installer_state_;
449 private:
450 registry_util::RegistryOverrideManager registry_override_manager_;
452 DISALLOW_COPY_AND_ASSIGN(FindArchiveToPatchTest);
455 const bool FindArchiveToPatchTest::kSystemInstall_ = false;
456 const BrowserDistribution::Type FindArchiveToPatchTest::kProductType_ =
457 BrowserDistribution::CHROME_BROWSER;
459 } // namespace
461 // Test that the path to the advertised product version is found.
462 TEST_F(FindArchiveToPatchTest, ProductVersionFound) {
463 base::FilePath patch_source(installer::FindArchiveToPatch(
464 *original_state_, *installer_state_, base::Version()));
465 EXPECT_EQ(GetProductVersionArchivePath().value(), patch_source.value());
468 // Test that the path to the max version is found if the advertised version is
469 // missing.
470 TEST_F(FindArchiveToPatchTest, MaxVersionFound) {
471 // The patch file is absent.
472 ASSERT_TRUE(base::DeleteFile(GetProductVersionArchivePath(), false));
473 base::FilePath patch_source(installer::FindArchiveToPatch(
474 *original_state_, *installer_state_, base::Version()));
475 EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source.value());
477 // The product doesn't appear to be installed, so the max version is found.
478 UninstallProduct();
479 patch_source = installer::FindArchiveToPatch(
480 *original_state_, *installer_state_, base::Version());
481 EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source.value());
484 // Test that an empty path is returned if no version is found.
485 TEST_F(FindArchiveToPatchTest, NoVersionFound) {
486 // The product doesn't appear to be installed and no archives are present.
487 UninstallProduct();
488 ASSERT_TRUE(base::DeleteFile(GetProductVersionArchivePath(), false));
489 ASSERT_TRUE(base::DeleteFile(GetMaxVersionArchivePath(), false));
491 base::FilePath patch_source(installer::FindArchiveToPatch(
492 *original_state_, *installer_state_, base::Version()));
493 EXPECT_EQ(base::FilePath::StringType(), patch_source.value());
496 TEST_F(FindArchiveToPatchTest, DesiredVersionFound) {
497 base::FilePath patch_source1(installer::FindArchiveToPatch(
498 *original_state_, *installer_state_, product_version_));
499 EXPECT_EQ(GetProductVersionArchivePath().value(), patch_source1.value());
500 base::FilePath patch_source2(installer::FindArchiveToPatch(
501 *original_state_, *installer_state_, max_version_));
502 EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source2.value());
505 TEST_F(FindArchiveToPatchTest, DesiredVersionNotFound) {
506 base::FilePath patch_source(installer::FindArchiveToPatch(
507 *original_state_, *installer_state_, base::Version("1.2.3.4")));
508 EXPECT_EQ(base::FilePath().value(), patch_source.value());
511 #if defined(GOOGLE_CHROME_BUILD)
512 namespace {
513 const bool kSystemLevel = false;
514 const HKEY kRootKey = kSystemLevel ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
515 const wchar_t kVersionString[] = L"30.0.1574.0";
516 const wchar_t kMultiChannel[] = L"2.0-dev-multi-chromeframe";
518 class MigrateMultiToSingleTest : public testing::Test {
519 protected:
520 void SetUp() override {
521 registry_override_manager_.OverrideRegistry(kRootKey);
524 private:
525 registry_util::RegistryOverrideManager registry_override_manager_;
527 } // namespace
529 // Test migrating Chrome Frame from multi to single.
530 TEST_F(MigrateMultiToSingleTest, ChromeFrame) {
531 installer::ProductState chrome_frame;
532 installer::ProductState binaries;
533 DWORD usagestats = 0;
535 // Set up a config with dev-channel multi-install GCF.
536 base::win::RegKey key;
538 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
539 BrowserDistribution::CHROME_BINARIES);
540 ASSERT_EQ(ERROR_SUCCESS,
541 base::win::RegKey(kRootKey, dist->GetVersionKey().c_str(),
542 KEY_SET_VALUE)
543 .WriteValue(google_update::kRegVersionField, kVersionString));
544 ASSERT_EQ(ERROR_SUCCESS,
545 base::win::RegKey(kRootKey, dist->GetStateKey().c_str(),
546 KEY_SET_VALUE)
547 .WriteValue(google_update::kRegApField, kMultiChannel));
548 ASSERT_EQ(ERROR_SUCCESS,
549 base::win::RegKey(kRootKey, dist->GetStateKey().c_str(),
550 KEY_SET_VALUE)
551 .WriteValue(google_update::kRegUsageStatsField, 1U));
553 dist = BrowserDistribution::GetSpecificDistribution(
554 BrowserDistribution::CHROME_FRAME);
555 ASSERT_EQ(ERROR_SUCCESS,
556 base::win::RegKey(kRootKey, dist->GetVersionKey().c_str(),
557 KEY_SET_VALUE)
558 .WriteValue(google_update::kRegVersionField, kVersionString));
559 ASSERT_EQ(ERROR_SUCCESS,
560 base::win::RegKey(kRootKey, dist->GetStateKey().c_str(),
561 KEY_SET_VALUE)
562 .WriteValue(google_update::kRegApField, kMultiChannel));
564 // Do the registry migration.
565 installer::InstallationState machine_state;
566 machine_state.Initialize();
568 installer::MigrateGoogleUpdateStateMultiToSingle(
569 kSystemLevel,
570 BrowserDistribution::CHROME_FRAME,
571 machine_state);
573 // Confirm that usagestats were copied to CF and that its channel was
574 // stripped.
575 ASSERT_TRUE(chrome_frame.Initialize(kSystemLevel,
576 BrowserDistribution::CHROME_FRAME));
577 EXPECT_TRUE(chrome_frame.GetUsageStats(&usagestats));
578 EXPECT_EQ(1U, usagestats);
579 EXPECT_EQ(L"2.0-dev", chrome_frame.channel().value());
581 // Confirm that the binaries' channel no longer contains GCF.
582 ASSERT_TRUE(binaries.Initialize(kSystemLevel,
583 BrowserDistribution::CHROME_BINARIES));
584 EXPECT_EQ(L"2.0-dev-multi", binaries.channel().value());
586 #endif
588 TEST(SetupUtilTest, ContainsUnsupportedSwitch) {
589 EXPECT_FALSE(installer::ContainsUnsupportedSwitch(
590 base::CommandLine::FromString(L"foo.exe")));
591 EXPECT_FALSE(installer::ContainsUnsupportedSwitch(
592 base::CommandLine::FromString(L"foo.exe --multi-install --chrome")));
593 EXPECT_TRUE(installer::ContainsUnsupportedSwitch(
594 base::CommandLine::FromString(L"foo.exe --chrome-frame")));
597 TEST(SetupUtilTest, GetRegistrationDataCommandKey) {
598 base::string16 app_guid = L"{AAAAAAAA-BBBB-1111-0123-456789ABCDEF}";
599 UpdatingAppRegistrationData reg_data(app_guid);
600 base::string16 key =
601 installer::GetRegistrationDataCommandKey(reg_data, L"test_name");
602 EXPECT_TRUE(base::EndsWith(key, app_guid + L"\\Commands\\test_name",
603 base::CompareCase::SENSITIVE));