| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/installer/setup/setup_util_unittest.h" | 5 #include "chrome/installer/setup/setup_util_unittest.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/macros.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/process/kill.h" | 16 #include "base/process/kill.h" |
| 16 #include "base/process/launch.h" | 17 #include "base/process/launch.h" |
| 17 #include "base/process/process_handle.h" | 18 #include "base/process/process_handle.h" |
| 18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 19 #include "base/test/test_reg_util_win.h" | 20 #include "base/test/test_reg_util_win.h" |
| 20 #include "base/threading/platform_thread.h" | 21 #include "base/threading/platform_thread.h" |
| 21 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 22 #include "base/version.h" | 23 #include "base/version.h" |
| 24 #include "base/win/registry.h" |
| 23 #include "base/win/scoped_handle.h" | 25 #include "base/win/scoped_handle.h" |
| 24 #include "base/win/windows_version.h" | 26 #include "base/win/windows_version.h" |
| 25 #include "chrome/installer/setup/setup_constants.h" | 27 #include "chrome/installer/setup/setup_constants.h" |
| 26 #include "chrome/installer/setup/setup_util.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" |
| 27 #include "chrome/installer/util/google_update_constants.h" | 31 #include "chrome/installer/util/google_update_constants.h" |
| 32 #include "chrome/installer/util/install_util.h" |
| 28 #include "chrome/installer/util/installation_state.h" | 33 #include "chrome/installer/util/installation_state.h" |
| 29 #include "chrome/installer/util/installer_state.h" | 34 #include "chrome/installer/util/installer_state.h" |
| 30 #include "chrome/installer/util/updating_app_registration_data.h" | 35 #include "chrome/installer/util/updating_app_registration_data.h" |
| 31 #include "chrome/installer/util/util_constants.h" | 36 #include "chrome/installer/util/util_constants.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 37 #include "testing/gtest/include/gtest/gtest.h" |
| 33 | 38 |
| 34 namespace { | 39 namespace { |
| 35 | 40 |
| 36 class SetupUtilTestWithDir : public testing::Test { | 41 class SetupUtilTest : public testing::Test { |
| 37 protected: | 42 protected: |
| 43 SetupUtilTest() {} |
| 44 |
| 38 void SetUp() override { | 45 void SetUp() override { |
| 39 // Create a temp directory for testing. | |
| 40 ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); | 46 ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); |
| 47 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER); |
| 48 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE); |
| 41 } | 49 } |
| 42 | 50 |
| 43 void TearDown() override { | 51 base::ScopedTempDir test_dir_; |
| 44 // Clean up test directory manually so we can fail if it leaks. | |
| 45 ASSERT_TRUE(test_dir_.Delete()); | |
| 46 } | |
| 47 | 52 |
| 48 // The temporary directory used to contain the test operations. | 53 private: |
| 49 base::ScopedTempDir test_dir_; | 54 registry_util::RegistryOverrideManager registry_override_manager_; |
| 55 |
| 56 DISALLOW_COPY_AND_ASSIGN(SetupUtilTest); |
| 50 }; | 57 }; |
| 51 | 58 |
| 52 // The privilege tested in ScopeTokenPrivilege tests below. | 59 // The privilege tested in ScopeTokenPrivilege tests below. |
| 53 // Use SE_RESTORE_NAME as it is one of the many privileges that is available, | 60 // Use SE_RESTORE_NAME as it is one of the many privileges that is available, |
| 54 // but not enabled by default on processes running at high integrity. | 61 // but not enabled by default on processes running at high integrity. |
| 55 static const wchar_t kTestedPrivilege[] = SE_RESTORE_NAME; | 62 static const wchar_t kTestedPrivilege[] = SE_RESTORE_NAME; |
| 56 | 63 |
| 57 // Returns true if the current process' token has privilege |privilege_name| | 64 // Returns true if the current process' token has privilege |privilege_name| |
| 58 // enabled. | 65 // enabled. |
| 59 bool CurrentProcessHasPrivilege(const wchar_t* privilege_name) { | 66 bool CurrentProcessHasPrivilege(const wchar_t* privilege_name) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 if (size == desired_size && | 100 if (size == desired_size && |
| 94 wcscmp(name_buffer.get(), privilege_name) == 0) { | 101 wcscmp(name_buffer.get(), privilege_name) == 0) { |
| 95 return luid_and_att.Attributes == SE_PRIVILEGE_ENABLED; | 102 return luid_and_att.Attributes == SE_PRIVILEGE_ENABLED; |
| 96 } | 103 } |
| 97 } | 104 } |
| 98 return false; | 105 return false; |
| 99 } | 106 } |
| 100 | 107 |
| 101 } // namespace | 108 } // namespace |
| 102 | 109 |
| 110 TEST_F(SetupUtilTest, UpdateLastOSUpgradeHandledByActiveSetup) { |
| 111 BrowserDistribution* chrome_dist = |
| 112 BrowserDistribution::GetSpecificDistribution( |
| 113 BrowserDistribution::CHROME_BROWSER); |
| 114 const base::string16 active_setup_path( |
| 115 InstallUtil::GetActiveSetupPath(chrome_dist)); |
| 116 |
| 117 base::win::RegKey test_key; |
| 118 base::string16 unused_tmp; |
| 119 |
| 120 EXPECT_EQ(ERROR_FILE_NOT_FOUND, |
| 121 test_key.Open(HKEY_LOCAL_MACHINE, active_setup_path.c_str(), |
| 122 KEY_QUERY_VALUE)); |
| 123 // The WorkItem assume the ActiveSetup key itself already exists and only |
| 124 // handles the Version entry, create it now, but don't fill the "Version" |
| 125 // entry just yet. |
| 126 EXPECT_EQ(ERROR_SUCCESS, |
| 127 test_key.Create(HKEY_LOCAL_MACHINE, active_setup_path.c_str(), |
| 128 KEY_QUERY_VALUE)); |
| 129 EXPECT_EQ(ERROR_FILE_NOT_FOUND, test_key.ReadValue(L"Version", &unused_tmp)); |
| 130 |
| 131 // Test returns false when no Active Setup version present (and doesn't alter |
| 132 // that state). |
| 133 EXPECT_FALSE( |
| 134 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist)); |
| 135 EXPECT_EQ(ERROR_FILE_NOT_FOUND, test_key.ReadValue(L"Version", &unused_tmp)); |
| 136 |
| 137 { |
| 138 UpdateActiveSetupVersionWorkItem active_setup_work_item( |
| 139 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE); |
| 140 active_setup_work_item.Do(); |
| 141 EXPECT_EQ(ERROR_SUCCESS, test_key.ReadValue(L"Version", &unused_tmp)); |
| 142 } |
| 143 |
| 144 // Test returns false with default Active Setup version. |
| 145 EXPECT_FALSE( |
| 146 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist)); |
| 147 EXPECT_EQ(ERROR_SUCCESS, test_key.ReadValue(L"Version", &unused_tmp)); |
| 148 |
| 149 // Run through |kIterations| sequences of bumping the OS upgrade version |i| |
| 150 // times and simulating a regular update |kIterations-i| times, confirming |
| 151 // that handling any number of OS upgrades only results in a single hit and |
| 152 // that no amount of regular updates after that result in any hit. |
| 153 const size_t kIterations = 4U; |
| 154 for (size_t i = 0U; i < kIterations; ++i) { |
| 155 SCOPED_TRACE(i); |
| 156 // Bump the OS_UPGRADES component |i| times. |
| 157 for (size_t j = 0; j < i; ++j) { |
| 158 UpdateActiveSetupVersionWorkItem active_setup_work_item( |
| 159 active_setup_path, UpdateActiveSetupVersionWorkItem:: |
| 160 UPDATE_AND_BUMP_OS_UPGRADES_COMPONENT); |
| 161 active_setup_work_item.Do(); |
| 162 } |
| 163 |
| 164 // There should be a single OS upgrade to handle if the OS_UPGRADES |
| 165 // component was bumped at least once. |
| 166 EXPECT_EQ(i > 0, installer::UpdateLastOSUpgradeHandledByActiveSetup( |
| 167 chrome_dist)); |
| 168 |
| 169 // We should only be told to handle the latest OS upgrade once above. |
| 170 EXPECT_FALSE( |
| 171 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist)); |
| 172 EXPECT_FALSE( |
| 173 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist)); |
| 174 |
| 175 // Run |kIterations-i| regular updates. |
| 176 for (size_t j = i; j < kIterations; ++j) { |
| 177 UpdateActiveSetupVersionWorkItem active_setup_work_item( |
| 178 active_setup_path, UpdateActiveSetupVersionWorkItem::UPDATE); |
| 179 active_setup_work_item.Do(); |
| 180 } |
| 181 |
| 182 // No amount of regular updates should trigger an OS upgrade to be handled. |
| 183 EXPECT_FALSE( |
| 184 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist)); |
| 185 EXPECT_FALSE( |
| 186 installer::UpdateLastOSUpgradeHandledByActiveSetup(chrome_dist)); |
| 187 } |
| 188 } |
| 189 |
| 103 // Test that we are parsing Chrome version correctly. | 190 // Test that we are parsing Chrome version correctly. |
| 104 TEST_F(SetupUtilTestWithDir, GetMaxVersionFromArchiveDirTest) { | 191 TEST_F(SetupUtilTest, GetMaxVersionFromArchiveDirTest) { |
| 105 // Create a version dir | 192 // Create a version dir |
| 106 base::FilePath chrome_dir = test_dir_.path().AppendASCII("1.0.0.0"); | 193 base::FilePath chrome_dir = test_dir_.path().AppendASCII("1.0.0.0"); |
| 107 base::CreateDirectory(chrome_dir); | 194 base::CreateDirectory(chrome_dir); |
| 108 ASSERT_TRUE(base::PathExists(chrome_dir)); | 195 ASSERT_TRUE(base::PathExists(chrome_dir)); |
| 109 scoped_ptr<Version> version( | 196 scoped_ptr<Version> version( |
| 110 installer::GetMaxVersionFromArchiveDir(test_dir_.path())); | 197 installer::GetMaxVersionFromArchiveDir(test_dir_.path())); |
| 111 ASSERT_EQ(version->GetString(), "1.0.0.0"); | 198 ASSERT_EQ(version->GetString(), "1.0.0.0"); |
| 112 | 199 |
| 113 base::DeleteFile(chrome_dir, true); | 200 base::DeleteFile(chrome_dir, true); |
| 114 ASSERT_FALSE(base::PathExists(chrome_dir)); | 201 ASSERT_FALSE(base::PathExists(chrome_dir)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 130 base::CreateDirectory(chrome_dir); | 217 base::CreateDirectory(chrome_dir); |
| 131 ASSERT_TRUE(base::PathExists(chrome_dir)); | 218 ASSERT_TRUE(base::PathExists(chrome_dir)); |
| 132 chrome_dir = test_dir_.path().AppendASCII("1.1.1.1"); | 219 chrome_dir = test_dir_.path().AppendASCII("1.1.1.1"); |
| 133 base::CreateDirectory(chrome_dir); | 220 base::CreateDirectory(chrome_dir); |
| 134 ASSERT_TRUE(base::PathExists(chrome_dir)); | 221 ASSERT_TRUE(base::PathExists(chrome_dir)); |
| 135 | 222 |
| 136 version.reset(installer::GetMaxVersionFromArchiveDir(test_dir_.path())); | 223 version.reset(installer::GetMaxVersionFromArchiveDir(test_dir_.path())); |
| 137 ASSERT_EQ(version->GetString(), "9.9.9.9"); | 224 ASSERT_EQ(version->GetString(), "9.9.9.9"); |
| 138 } | 225 } |
| 139 | 226 |
| 140 TEST_F(SetupUtilTestWithDir, DeleteFileFromTempProcess) { | 227 TEST_F(SetupUtilTest, DeleteFileFromTempProcess) { |
| 141 base::FilePath test_file; | 228 base::FilePath test_file; |
| 142 base::CreateTemporaryFileInDir(test_dir_.path(), &test_file); | 229 base::CreateTemporaryFileInDir(test_dir_.path(), &test_file); |
| 143 ASSERT_TRUE(base::PathExists(test_file)); | 230 ASSERT_TRUE(base::PathExists(test_file)); |
| 144 base::WriteFile(test_file, "foo", 3); | 231 base::WriteFile(test_file, "foo", 3); |
| 145 EXPECT_TRUE(installer::DeleteFileFromTempProcess(test_file, 0)); | 232 EXPECT_TRUE(installer::DeleteFileFromTempProcess(test_file, 0)); |
| 146 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); | 233 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); |
| 147 EXPECT_FALSE(base::PathExists(test_file)); | 234 EXPECT_FALSE(base::PathExists(test_file)); |
| 148 } | 235 } |
| 149 | 236 |
| 150 // Note: This test is only valid when run at high integrity (i.e. it will fail | 237 // Note: This test is only valid when run at high integrity (i.e. it will fail |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 if (base::win::GetVersion() > base::win::VERSION_SERVER_2003) | 347 if (base::win::GetVersion() > base::win::VERSION_SERVER_2003) |
| 261 EXPECT_EQ(PCCR_CHANGED, RelaunchAndDoProcessPriorityAdjustment()); | 348 EXPECT_EQ(PCCR_CHANGED, RelaunchAndDoProcessPriorityAdjustment()); |
| 262 else | 349 else |
| 263 EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment()); | 350 EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment()); |
| 264 } | 351 } |
| 265 | 352 |
| 266 namespace { | 353 namespace { |
| 267 | 354 |
| 268 // A test fixture that configures an InstallationState and an InstallerState | 355 // A test fixture that configures an InstallationState and an InstallerState |
| 269 // with a product being updated. | 356 // with a product being updated. |
| 270 class FindArchiveToPatchTest : public SetupUtilTestWithDir { | 357 class FindArchiveToPatchTest : public SetupUtilTest { |
| 271 protected: | 358 protected: |
| 272 class FakeInstallationState : public installer::InstallationState { | 359 class FakeInstallationState : public installer::InstallationState { |
| 273 }; | 360 }; |
| 274 | 361 |
| 275 class FakeProductState : public installer::ProductState { | 362 class FakeProductState : public installer::ProductState { |
| 276 public: | 363 public: |
| 277 static FakeProductState* FromProductState(const ProductState* product) { | 364 static FakeProductState* FromProductState(const ProductState* product) { |
| 278 return static_cast<FakeProductState*>(const_cast<ProductState*>(product)); | 365 return static_cast<FakeProductState*>(const_cast<ProductState*>(product)); |
| 279 } | 366 } |
| 280 | 367 |
| 281 void set_version(const Version& version) { | 368 void set_version(const Version& version) { |
| 282 if (version.IsValid()) | 369 if (version.IsValid()) |
| 283 version_.reset(new Version(version)); | 370 version_.reset(new Version(version)); |
| 284 else | 371 else |
| 285 version_.reset(); | 372 version_.reset(); |
| 286 } | 373 } |
| 287 | 374 |
| 288 void set_uninstall_command(const base::CommandLine& uninstall_command) { | 375 void set_uninstall_command(const base::CommandLine& uninstall_command) { |
| 289 uninstall_command_ = uninstall_command; | 376 uninstall_command_ = uninstall_command; |
| 290 } | 377 } |
| 291 }; | 378 }; |
| 292 | 379 |
| 293 void SetUp() override { | 380 void SetUp() override { |
| 294 SetupUtilTestWithDir::SetUp(); | 381 SetupUtilTest::SetUp(); |
| 295 product_version_ = Version("30.0.1559.0"); | 382 product_version_ = Version("30.0.1559.0"); |
| 296 max_version_ = Version("47.0.1559.0"); | 383 max_version_ = Version("47.0.1559.0"); |
| 297 | 384 |
| 298 // Install the product according to the version. | 385 // Install the product according to the version. |
| 299 original_state_.reset(new FakeInstallationState()); | 386 original_state_.reset(new FakeInstallationState()); |
| 300 InstallProduct(); | 387 InstallProduct(); |
| 301 | 388 |
| 302 // Prepare to update the product in the temp dir. | 389 // Prepare to update the product in the temp dir. |
| 303 installer_state_.reset(new installer::InstallerState( | 390 installer_state_.reset(new installer::InstallerState( |
| 304 kSystemInstall_ ? installer::InstallerState::SYSTEM_LEVEL : | 391 kSystemInstall_ ? installer::InstallerState::SYSTEM_LEVEL : |
| 305 installer::InstallerState::USER_LEVEL)); | 392 installer::InstallerState::USER_LEVEL)); |
| 306 installer_state_->AddProductFromState( | 393 installer_state_->AddProductFromState( |
| 307 kProductType_, | 394 kProductType_, |
| 308 *original_state_->GetProductState(kSystemInstall_, kProductType_)); | 395 *original_state_->GetProductState(kSystemInstall_, kProductType_)); |
| 309 | 396 |
| 310 // Create archives in the two version dirs. | 397 // Create archives in the two version dirs. |
| 311 ASSERT_TRUE( | 398 ASSERT_TRUE( |
| 312 base::CreateDirectory(GetProductVersionArchivePath().DirName())); | 399 base::CreateDirectory(GetProductVersionArchivePath().DirName())); |
| 313 ASSERT_EQ(1, base::WriteFile(GetProductVersionArchivePath(), "a", 1)); | 400 ASSERT_EQ(1, base::WriteFile(GetProductVersionArchivePath(), "a", 1)); |
| 314 ASSERT_TRUE( | 401 ASSERT_TRUE( |
| 315 base::CreateDirectory(GetMaxVersionArchivePath().DirName())); | 402 base::CreateDirectory(GetMaxVersionArchivePath().DirName())); |
| 316 ASSERT_EQ(1, base::WriteFile(GetMaxVersionArchivePath(), "b", 1)); | 403 ASSERT_EQ(1, base::WriteFile(GetMaxVersionArchivePath(), "b", 1)); |
| 317 } | 404 } |
| 318 | 405 |
| 319 void TearDown() override { | 406 void TearDown() override { |
| 320 original_state_.reset(); | 407 original_state_.reset(); |
| 321 SetupUtilTestWithDir::TearDown(); | 408 SetupUtilTest::TearDown(); |
| 322 } | 409 } |
| 323 | 410 |
| 324 base::FilePath GetArchivePath(const Version& version) const { | 411 base::FilePath GetArchivePath(const Version& version) const { |
| 325 return test_dir_.path() | 412 return test_dir_.path() |
| 326 .AppendASCII(version.GetString()) | 413 .AppendASCII(version.GetString()) |
| 327 .Append(installer::kInstallerDir) | 414 .Append(installer::kInstallerDir) |
| 328 .Append(installer::kChromeArchive); | 415 .Append(installer::kChromeArchive); |
| 329 } | 416 } |
| 330 | 417 |
| 331 base::FilePath GetMaxVersionArchivePath() const { | 418 base::FilePath GetMaxVersionArchivePath() const { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 class MigrateMultiToSingleTest : public testing::Test { | 514 class MigrateMultiToSingleTest : public testing::Test { |
| 428 protected: | 515 protected: |
| 429 void SetUp() override { | 516 void SetUp() override { |
| 430 registry_override_manager_.OverrideRegistry(kRootKey); | 517 registry_override_manager_.OverrideRegistry(kRootKey); |
| 431 } | 518 } |
| 432 | 519 |
| 433 static const bool kSystemLevel = false; | 520 static const bool kSystemLevel = false; |
| 434 static const HKEY kRootKey; | 521 static const HKEY kRootKey; |
| 435 static const wchar_t kVersionString[]; | 522 static const wchar_t kVersionString[]; |
| 436 static const wchar_t kMultiChannel[]; | 523 static const wchar_t kMultiChannel[]; |
| 524 |
| 525 private: |
| 437 registry_util::RegistryOverrideManager registry_override_manager_; | 526 registry_util::RegistryOverrideManager registry_override_manager_; |
| 438 }; | 527 }; |
| 439 | 528 |
| 440 const bool MigrateMultiToSingleTest::kSystemLevel; | 529 const bool MigrateMultiToSingleTest::kSystemLevel; |
| 441 const HKEY MigrateMultiToSingleTest::kRootKey = | 530 const HKEY MigrateMultiToSingleTest::kRootKey = |
| 442 kSystemLevel ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 531 kSystemLevel ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| 443 const wchar_t MigrateMultiToSingleTest::kVersionString[] = L"30.0.1574.0"; | 532 const wchar_t MigrateMultiToSingleTest::kVersionString[] = L"30.0.1574.0"; |
| 444 const wchar_t MigrateMultiToSingleTest::kMultiChannel[] = | 533 const wchar_t MigrateMultiToSingleTest::kMultiChannel[] = |
| 445 L"2.0-dev-multi-chromeframe"; | 534 L"2.0-dev-multi-chromeframe"; |
| 446 | 535 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 base::CommandLine::FromString(L"foo.exe --chrome-frame"))); | 602 base::CommandLine::FromString(L"foo.exe --chrome-frame"))); |
| 514 } | 603 } |
| 515 | 604 |
| 516 TEST(SetupUtilTest, GetRegistrationDataCommandKey) { | 605 TEST(SetupUtilTest, GetRegistrationDataCommandKey) { |
| 517 base::string16 app_guid = L"{AAAAAAAA-BBBB-1111-0123-456789ABCDEF}"; | 606 base::string16 app_guid = L"{AAAAAAAA-BBBB-1111-0123-456789ABCDEF}"; |
| 518 UpdatingAppRegistrationData reg_data(app_guid); | 607 UpdatingAppRegistrationData reg_data(app_guid); |
| 519 base::string16 key = | 608 base::string16 key = |
| 520 installer::GetRegistrationDataCommandKey(reg_data, L"test_name"); | 609 installer::GetRegistrationDataCommandKey(reg_data, L"test_name"); |
| 521 EXPECT_TRUE(base::EndsWith(key, app_guid + L"\\Commands\\test_name", true)); | 610 EXPECT_TRUE(base::EndsWith(key, app_guid + L"\\Commands\\test_name", true)); |
| 522 } | 611 } |
| OLD | NEW |