| 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/install_worker.h" | 5 #include "chrome/installer/setup/install_worker.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <memory> |
| 8 #include <string> |
| 8 | 9 |
| 9 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" |
| 10 #include "base/version.h" | 12 #include "base/version.h" |
| 11 #include "base/win/registry.h" | 13 #include "base/win/registry.h" |
| 12 #include "chrome/common/chrome_constants.h" | 14 #include "chrome/common/chrome_constants.h" |
| 13 #include "chrome/installer/setup/installer_state.h" | 15 #include "chrome/installer/setup/installer_state.h" |
| 14 #include "chrome/installer/setup/setup_util.h" | 16 #include "chrome/installer/setup/setup_util.h" |
| 15 #include "chrome/installer/util/create_reg_key_work_item.h" | 17 #include "chrome/installer/util/create_reg_key_work_item.h" |
| 16 #include "chrome/installer/util/delete_reg_key_work_item.h" | 18 #include "chrome/installer/util/delete_reg_key_work_item.h" |
| 17 #include "chrome/installer/util/delete_tree_work_item.h" | 19 #include "chrome/installer/util/delete_tree_work_item.h" |
| 18 #include "chrome/installer/util/google_update_constants.h" | 20 #include "chrome/installer/util/google_update_constants.h" |
| 19 #include "chrome/installer/util/helper.h" | 21 #include "chrome/installer/util/helper.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 bool)); | 111 bool)); |
| 110 MOCK_METHOD3(AddSelfRegWorkItem, WorkItem* (const std::wstring&, | 112 MOCK_METHOD3(AddSelfRegWorkItem, WorkItem* (const std::wstring&, |
| 111 bool, | 113 bool, |
| 112 bool)); | 114 bool)); |
| 113 }; | 115 }; |
| 114 | 116 |
| 115 class MockProductState : public ProductState { | 117 class MockProductState : public ProductState { |
| 116 public: | 118 public: |
| 117 // Takes ownership of |version|. | 119 // Takes ownership of |version|. |
| 118 void set_version(base::Version* version) { version_.reset(version); } | 120 void set_version(base::Version* version) { version_.reset(version); } |
| 119 void set_multi_install(bool multi) { multi_install_ = multi; } | |
| 120 void set_brand(const std::wstring& brand) { brand_ = brand; } | 121 void set_brand(const std::wstring& brand) { brand_ = brand; } |
| 121 void set_eula_accepted(DWORD eula_accepted) { | 122 void set_eula_accepted(DWORD eula_accepted) { |
| 122 has_eula_accepted_ = true; | 123 has_eula_accepted_ = true; |
| 123 eula_accepted_ = eula_accepted; | 124 eula_accepted_ = eula_accepted; |
| 124 } | 125 } |
| 125 void clear_eula_accepted() { has_eula_accepted_ = false; } | 126 void clear_eula_accepted() { has_eula_accepted_ = false; } |
| 126 void set_usagestats(DWORD usagestats) { | 127 void set_usagestats(DWORD usagestats) { |
| 127 has_usagestats_ = true; | 128 has_usagestats_ = true; |
| 128 usagestats_ = usagestats; | 129 usagestats_ = usagestats; |
| 129 } | 130 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 164 |
| 164 void set_operation(Operation operation) { operation_ = operation; } | 165 void set_operation(Operation operation) { operation_ = operation; } |
| 165 | 166 |
| 166 void set_state_key(const std::wstring& state_key) { | 167 void set_state_key(const std::wstring& state_key) { |
| 167 state_key_ = state_key; | 168 state_key_ = state_key; |
| 168 } | 169 } |
| 169 | 170 |
| 170 void set_state_type(BrowserDistribution::Type state_type) { | 171 void set_state_type(BrowserDistribution::Type state_type) { |
| 171 state_type_ = state_type; | 172 state_type_ = state_type; |
| 172 } | 173 } |
| 173 | |
| 174 void set_package_type(PackageType type) { | |
| 175 InstallerState::set_package_type(type); | |
| 176 } | |
| 177 }; | 174 }; |
| 178 | 175 |
| 179 // The test fixture | 176 // The test fixture |
| 180 //------------------------------------------------------------------------------ | 177 //------------------------------------------------------------------------------ |
| 181 | 178 |
| 182 class InstallWorkerTest : public testing::Test { | 179 class InstallWorkerTest : public testing::Test { |
| 183 public: | 180 public: |
| 184 void SetUp() override { | 181 void SetUp() override { |
| 185 current_version_.reset(new base::Version("1.0.0.0")); | 182 current_version_.reset(new base::Version("1.0.0.0")); |
| 186 new_version_.reset(new base::Version("42.0.0.0")); | 183 new_version_.reset(new base::Version("42.0.0.0")); |
| 187 | 184 |
| 188 // Don't bother ensuring that these paths exist. Since we're just | 185 // Don't bother ensuring that these paths exist. Since we're just |
| 189 // building the work item lists and not running them, they shouldn't | 186 // building the work item lists and not running them, they shouldn't |
| 190 // actually be touched. | 187 // actually be touched. |
| 191 archive_path_ = | 188 archive_path_ = |
| 192 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z"); | 189 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z"); |
| 193 // TODO(robertshield): Take this from the BrowserDistribution once that | 190 // TODO(robertshield): Take this from the BrowserDistribution once that |
| 194 // no longer depends on MasterPreferences. | 191 // no longer depends on MasterPreferences. |
| 195 installation_path_ = | 192 installation_path_ = |
| 196 base::FilePath(L"C:\\Program Files\\Google\\Chrome\\"); | 193 base::FilePath(L"C:\\Program Files\\Google\\Chrome\\"); |
| 197 src_path_ = base::FilePath( | 194 src_path_ = base::FilePath( |
| 198 L"C:\\UnlikelyPath\\Temp\\chrome_123\\source\\Chrome-bin"); | 195 L"C:\\UnlikelyPath\\Temp\\chrome_123\\source\\Chrome-bin"); |
| 199 setup_path_ = base::FilePath( | 196 setup_path_ = base::FilePath( |
| 200 L"C:\\UnlikelyPath\\Temp\\CR_123.tmp\\setup.exe"); | 197 L"C:\\UnlikelyPath\\Temp\\CR_123.tmp\\setup.exe"); |
| 201 temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123"); | 198 temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123"); |
| 202 } | 199 } |
| 203 | 200 |
| 204 void TearDown() override {} | |
| 205 | |
| 206 void MaybeAddBinariesToInstallationState( | |
| 207 bool system_level, | |
| 208 MockInstallationState* installation_state) { | |
| 209 if (installation_state->GetProductState( | |
| 210 system_level, BrowserDistribution::CHROME_BINARIES) == NULL) { | |
| 211 MockProductState product_state; | |
| 212 product_state.set_version(new base::Version(*current_version_)); | |
| 213 product_state.set_brand(L"TEST"); | |
| 214 product_state.set_multi_install(true); | |
| 215 BrowserDistribution* dist = | |
| 216 BrowserDistribution::GetSpecificDistribution( | |
| 217 BrowserDistribution::CHROME_BINARIES); | |
| 218 base::FilePath install_path = | |
| 219 installer::GetChromeInstallPath(system_level, dist); | |
| 220 product_state.SetUninstallProgram( | |
| 221 install_path.AppendASCII(current_version_->GetString()) | |
| 222 .Append(installer::kInstallerDir) | |
| 223 .Append(installer::kSetupExe)); | |
| 224 product_state.AddUninstallSwitch(installer::switches::kUninstall); | |
| 225 product_state.AddUninstallSwitch(installer::switches::kMultiInstall); | |
| 226 if (system_level) | |
| 227 product_state.AddUninstallSwitch(installer::switches::kSystemLevel); | |
| 228 installation_state->SetProductState(system_level, | |
| 229 BrowserDistribution::CHROME_BINARIES, | |
| 230 product_state); | |
| 231 } | |
| 232 } | |
| 233 | |
| 234 void AddChromeToInstallationState( | 201 void AddChromeToInstallationState( |
| 235 bool system_level, | 202 bool system_level, |
| 236 bool multi_install, | |
| 237 MockInstallationState* installation_state) { | 203 MockInstallationState* installation_state) { |
| 238 if (multi_install) | |
| 239 MaybeAddBinariesToInstallationState(system_level, installation_state); | |
| 240 MockProductState product_state; | 204 MockProductState product_state; |
| 241 product_state.set_version(new base::Version(*current_version_)); | 205 product_state.set_version(new base::Version(*current_version_)); |
| 242 product_state.set_multi_install(multi_install); | |
| 243 product_state.set_brand(L"TEST"); | 206 product_state.set_brand(L"TEST"); |
| 244 product_state.set_eula_accepted(1); | 207 product_state.set_eula_accepted(1); |
| 245 BrowserDistribution* dist = | 208 BrowserDistribution* dist = |
| 246 BrowserDistribution::GetSpecificDistribution( | 209 BrowserDistribution::GetSpecificDistribution( |
| 247 BrowserDistribution::CHROME_BROWSER); | 210 BrowserDistribution::CHROME_BROWSER); |
| 248 base::FilePath install_path = | 211 base::FilePath install_path = |
| 249 installer::GetChromeInstallPath(system_level, dist); | 212 installer::GetChromeInstallPath(system_level, dist); |
| 250 product_state.SetUninstallProgram( | 213 product_state.SetUninstallProgram( |
| 251 install_path.AppendASCII(current_version_->GetString()) | 214 install_path.AppendASCII(current_version_->GetString()) |
| 252 .Append(installer::kInstallerDir) | 215 .Append(installer::kInstallerDir) |
| 253 .Append(installer::kSetupExe)); | 216 .Append(installer::kSetupExe)); |
| 254 product_state.AddUninstallSwitch(installer::switches::kUninstall); | 217 product_state.AddUninstallSwitch(installer::switches::kUninstall); |
| 255 if (system_level) | 218 if (system_level) |
| 256 product_state.AddUninstallSwitch(installer::switches::kSystemLevel); | 219 product_state.AddUninstallSwitch(installer::switches::kSystemLevel); |
| 257 if (multi_install) { | |
| 258 product_state.AddUninstallSwitch(installer::switches::kMultiInstall); | |
| 259 product_state.AddUninstallSwitch(installer::switches::kChrome); | |
| 260 } | |
| 261 | 220 |
| 262 installation_state->SetProductState(system_level, | 221 installation_state->SetProductState(system_level, |
| 263 BrowserDistribution::CHROME_BROWSER, | 222 BrowserDistribution::CHROME_BROWSER, |
| 264 product_state); | 223 product_state); |
| 265 } | 224 } |
| 266 | 225 |
| 267 void AddChromeFrameToInstallationState( | 226 MockInstallationState* BuildChromeInstallationState(bool system_level) { |
| 268 bool system_level, | |
| 269 bool multi_install, | |
| 270 MockInstallationState* installation_state) { | |
| 271 if (multi_install) | |
| 272 MaybeAddBinariesToInstallationState(system_level, installation_state); | |
| 273 MockProductState product_state; | |
| 274 product_state.set_version(new base::Version(*current_version_)); | |
| 275 product_state.set_multi_install(multi_install); | |
| 276 BrowserDistribution* dist = | |
| 277 BrowserDistribution::GetSpecificDistribution( | |
| 278 multi_install ? BrowserDistribution::CHROME_BINARIES : | |
| 279 BrowserDistribution::CHROME_FRAME); | |
| 280 base::FilePath install_path = | |
| 281 installer::GetChromeInstallPath(system_level, dist); | |
| 282 product_state.SetUninstallProgram( | |
| 283 install_path.AppendASCII(current_version_->GetString()) | |
| 284 .Append(installer::kInstallerDir) | |
| 285 .Append(installer::kSetupExe)); | |
| 286 product_state.AddUninstallSwitch(installer::switches::kUninstall); | |
| 287 product_state.AddUninstallSwitch(installer::switches::kChromeFrame); | |
| 288 if (system_level) | |
| 289 product_state.AddUninstallSwitch(installer::switches::kSystemLevel); | |
| 290 if (multi_install) | |
| 291 product_state.AddUninstallSwitch(installer::switches::kMultiInstall); | |
| 292 | |
| 293 installation_state->SetProductState(system_level, | |
| 294 BrowserDistribution::CHROME_FRAME, | |
| 295 product_state); | |
| 296 } | |
| 297 | |
| 298 MockInstallationState* BuildChromeInstallationState(bool system_level, | |
| 299 bool multi_install) { | |
| 300 std::unique_ptr<MockInstallationState> installation_state( | 227 std::unique_ptr<MockInstallationState> installation_state( |
| 301 new MockInstallationState()); | 228 new MockInstallationState()); |
| 302 AddChromeToInstallationState(system_level, multi_install, | 229 AddChromeToInstallationState(system_level, installation_state.get()); |
| 303 installation_state.get()); | |
| 304 return installation_state.release(); | 230 return installation_state.release(); |
| 305 } | 231 } |
| 306 | 232 |
| 307 static MockInstallerState* BuildBasicInstallerState( | 233 static MockInstallerState* BuildBasicInstallerState( |
| 308 bool system_install, | 234 bool system_install, |
| 309 bool multi_install, | |
| 310 const InstallationState& machine_state, | 235 const InstallationState& machine_state, |
| 311 InstallerState::Operation operation) { | 236 InstallerState::Operation operation) { |
| 312 std::unique_ptr<MockInstallerState> installer_state( | 237 std::unique_ptr<MockInstallerState> installer_state( |
| 313 new MockInstallerState()); | 238 new MockInstallerState()); |
| 314 | 239 |
| 315 InstallerState::Level level = system_install ? | 240 InstallerState::Level level = system_install ? |
| 316 InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL; | 241 InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL; |
| 317 installer_state->set_level(level); | 242 installer_state->set_level(level); |
| 318 installer_state->set_operation(operation); | 243 installer_state->set_operation(operation); |
| 319 // Hope this next one isn't checked for now. | 244 // Hope this next one isn't checked for now. |
| 320 installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH"); | 245 installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH"); |
| 321 installer_state->set_state_type(BrowserDistribution::CHROME_BROWSER); | 246 installer_state->set_state_type(BrowserDistribution::CHROME_BROWSER); |
| 322 installer_state->set_package_type(multi_install ? | |
| 323 InstallerState::MULTI_PACKAGE : | |
| 324 InstallerState::SINGLE_PACKAGE); | |
| 325 return installer_state.release(); | 247 return installer_state.release(); |
| 326 } | 248 } |
| 327 | 249 |
| 328 static void AddChromeBinariesToInstallerState( | |
| 329 const InstallationState& machine_state, | |
| 330 MockInstallerState* installer_state) { | |
| 331 if (!installer_state->is_multi_install()) { | |
| 332 NOTREACHED(); | |
| 333 return; | |
| 334 } | |
| 335 if (installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES)) | |
| 336 return; | |
| 337 | |
| 338 // Fresh install or upgrade? | |
| 339 const ProductState* chrome_binaries = | |
| 340 machine_state.GetProductState(installer_state->system_install(), | |
| 341 BrowserDistribution::CHROME_BINARIES); | |
| 342 if (chrome_binaries != NULL) { | |
| 343 installer_state->AddProductFromState(BrowserDistribution::CHROME_BINARIES, | |
| 344 *chrome_binaries); | |
| 345 } else { | |
| 346 BrowserDistribution* dist = | |
| 347 BrowserDistribution::GetSpecificDistribution( | |
| 348 BrowserDistribution::CHROME_BINARIES); | |
| 349 std::unique_ptr<Product> product(new Product(dist)); | |
| 350 product->SetOption(installer::kOptionMultiInstall, true); | |
| 351 installer_state->AddProduct(&product); | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 static void AddChromeToInstallerState( | 250 static void AddChromeToInstallerState( |
| 356 const InstallationState& machine_state, | 251 const InstallationState& machine_state, |
| 357 MockInstallerState* installer_state) { | 252 MockInstallerState* installer_state) { |
| 358 // Fresh install or upgrade? | 253 // Fresh install or upgrade? |
| 359 const ProductState* chrome = | 254 const ProductState* chrome = |
| 360 machine_state.GetProductState(installer_state->system_install(), | 255 machine_state.GetProductState(installer_state->system_install(), |
| 361 BrowserDistribution::CHROME_BROWSER); | 256 BrowserDistribution::CHROME_BROWSER); |
| 362 if (chrome != NULL && | 257 if (chrome) { |
| 363 chrome->is_multi_install() == installer_state->is_multi_install()) { | |
| 364 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, | 258 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, |
| 365 *chrome); | 259 *chrome); |
| 366 } else { | 260 } else { |
| 367 BrowserDistribution* dist = | 261 BrowserDistribution* dist = |
| 368 BrowserDistribution::GetSpecificDistribution( | 262 BrowserDistribution::GetSpecificDistribution( |
| 369 BrowserDistribution::CHROME_BROWSER); | 263 BrowserDistribution::CHROME_BROWSER); |
| 370 std::unique_ptr<Product> product(new Product(dist)); | 264 installer_state->AddProduct(base::MakeUnique<Product>(dist)); |
| 371 if (installer_state->is_multi_install()) | |
| 372 product->SetOption(installer::kOptionMultiInstall, true); | |
| 373 installer_state->AddProduct(&product); | |
| 374 } | |
| 375 } | |
| 376 | |
| 377 static void AddChromeFrameToInstallerState( | |
| 378 const InstallationState& machine_state, | |
| 379 MockInstallerState* installer_state) { | |
| 380 // Fresh install or upgrade? | |
| 381 const ProductState* cf = | |
| 382 machine_state.GetProductState(installer_state->system_install(), | |
| 383 BrowserDistribution::CHROME_FRAME); | |
| 384 if (cf != NULL) { | |
| 385 installer_state->AddProductFromState(BrowserDistribution::CHROME_FRAME, | |
| 386 *cf); | |
| 387 } else { | |
| 388 BrowserDistribution* dist = | |
| 389 BrowserDistribution::GetSpecificDistribution( | |
| 390 BrowserDistribution::CHROME_FRAME); | |
| 391 std::unique_ptr<Product> product(new Product(dist)); | |
| 392 if (installer_state->is_multi_install()) | |
| 393 product->SetOption(installer::kOptionMultiInstall, true); | |
| 394 installer_state->AddProduct(&product); | |
| 395 } | 265 } |
| 396 } | 266 } |
| 397 | 267 |
| 398 static MockInstallerState* BuildChromeInstallerState( | 268 static MockInstallerState* BuildChromeInstallerState( |
| 399 bool system_install, | 269 bool system_install, |
| 400 bool multi_install, | |
| 401 const InstallationState& machine_state, | 270 const InstallationState& machine_state, |
| 402 InstallerState::Operation operation) { | 271 InstallerState::Operation operation) { |
| 403 std::unique_ptr<MockInstallerState> installer_state( | 272 std::unique_ptr<MockInstallerState> installer_state( |
| 404 BuildBasicInstallerState(system_install, multi_install, machine_state, | 273 BuildBasicInstallerState(system_install, machine_state, operation)); |
| 405 operation)); | |
| 406 if (multi_install) { | |
| 407 // We don't want to include Chrome Binaries for uninstall if the machine | |
| 408 // has other products. For simplicity, we check Chrome Frame only. | |
| 409 bool machine_has_other_products = | |
| 410 machine_state.GetProductState(system_install, | |
| 411 BrowserDistribution::CHROME_FRAME) != NULL; | |
| 412 if (operation != InstallerState::UNINSTALL || !machine_has_other_products) | |
| 413 AddChromeBinariesToInstallerState(machine_state, installer_state.get()); | |
| 414 } | |
| 415 AddChromeToInstallerState(machine_state, installer_state.get()); | 274 AddChromeToInstallerState(machine_state, installer_state.get()); |
| 416 return installer_state.release(); | 275 return installer_state.release(); |
| 417 } | 276 } |
| 418 | 277 |
| 419 static MockInstallerState* BuildChromeFrameInstallerState( | |
| 420 bool system_install, | |
| 421 bool multi_install, | |
| 422 const InstallationState& machine_state, | |
| 423 InstallerState::Operation operation) { | |
| 424 // This method only works for installation/upgrade. | |
| 425 DCHECK(operation != InstallerState::UNINSTALL); | |
| 426 std::unique_ptr<MockInstallerState> installer_state( | |
| 427 BuildBasicInstallerState(system_install, multi_install, machine_state, | |
| 428 operation)); | |
| 429 if (multi_install) | |
| 430 AddChromeBinariesToInstallerState(machine_state, installer_state.get()); | |
| 431 AddChromeFrameToInstallerState(machine_state, installer_state.get()); | |
| 432 return installer_state.release(); | |
| 433 } | |
| 434 | |
| 435 protected: | 278 protected: |
| 436 std::unique_ptr<base::Version> current_version_; | 279 std::unique_ptr<base::Version> current_version_; |
| 437 std::unique_ptr<base::Version> new_version_; | 280 std::unique_ptr<base::Version> new_version_; |
| 438 base::FilePath archive_path_; | 281 base::FilePath archive_path_; |
| 439 base::FilePath installation_path_; | 282 base::FilePath installation_path_; |
| 440 base::FilePath setup_path_; | 283 base::FilePath setup_path_; |
| 441 base::FilePath src_path_; | 284 base::FilePath src_path_; |
| 442 base::FilePath temp_dir_; | 285 base::FilePath temp_dir_; |
| 443 }; | 286 }; |
| 444 | 287 |
| 445 // Tests | 288 // Tests |
| 446 //------------------------------------------------------------------------------ | 289 //------------------------------------------------------------------------------ |
| 447 | 290 |
| 448 TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) { | 291 TEST_F(InstallWorkerTest, TestInstallChromeSystem) { |
| 449 const bool system_level = true; | 292 const bool system_level = true; |
| 450 const bool multi_install = false; | |
| 451 NiceMock<MockWorkItemList> work_item_list; | 293 NiceMock<MockWorkItemList> work_item_list; |
| 452 | 294 |
| 453 const HKEY kRegRoot = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 295 const HKEY kRegRoot = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| 454 static const wchar_t kRegKeyPath[] = L"Software\\Chromium\\test"; | 296 static const wchar_t kRegKeyPath[] = L"Software\\Chromium\\test"; |
| 455 std::unique_ptr<CreateRegKeyWorkItem> create_reg_key_work_item( | 297 std::unique_ptr<CreateRegKeyWorkItem> create_reg_key_work_item( |
| 456 WorkItem::CreateCreateRegKeyWorkItem(kRegRoot, kRegKeyPath, | 298 WorkItem::CreateCreateRegKeyWorkItem(kRegRoot, kRegKeyPath, |
| 457 WorkItem::kWow64Default)); | 299 WorkItem::kWow64Default)); |
| 458 std::unique_ptr<SetRegValueWorkItem> set_reg_value_work_item( | 300 std::unique_ptr<SetRegValueWorkItem> set_reg_value_work_item( |
| 459 WorkItem::CreateSetRegValueWorkItem( | 301 WorkItem::CreateSetRegValueWorkItem( |
| 460 kRegRoot, kRegKeyPath, WorkItem::kWow64Default, L"", L"", false)); | 302 kRegRoot, kRegKeyPath, WorkItem::kWow64Default, L"", L"", false)); |
| 461 std::unique_ptr<DeleteTreeWorkItem> delete_tree_work_item( | 303 std::unique_ptr<DeleteTreeWorkItem> delete_tree_work_item( |
| 462 WorkItem::CreateDeleteTreeWorkItem(base::FilePath(), base::FilePath())); | 304 WorkItem::CreateDeleteTreeWorkItem(base::FilePath(), base::FilePath())); |
| 463 std::unique_ptr<DeleteRegKeyWorkItem> delete_reg_key_work_item( | 305 std::unique_ptr<DeleteRegKeyWorkItem> delete_reg_key_work_item( |
| 464 WorkItem::CreateDeleteRegKeyWorkItem(kRegRoot, kRegKeyPath, | 306 WorkItem::CreateDeleteRegKeyWorkItem(kRegRoot, kRegKeyPath, |
| 465 WorkItem::kWow64Default)); | 307 WorkItem::kWow64Default)); |
| 466 | 308 |
| 467 std::unique_ptr<InstallationState> installation_state( | 309 std::unique_ptr<InstallationState> installation_state( |
| 468 BuildChromeInstallationState(system_level, multi_install)); | 310 BuildChromeInstallationState(system_level)); |
| 469 | 311 |
| 470 std::unique_ptr<InstallerState> installer_state(BuildChromeInstallerState( | 312 std::unique_ptr<InstallerState> installer_state( |
| 471 system_level, multi_install, *installation_state, | 313 BuildChromeInstallerState(system_level, *installation_state, |
| 472 InstallerState::SINGLE_INSTALL_OR_UPDATE)); | 314 InstallerState::SINGLE_INSTALL_OR_UPDATE)); |
| 473 | 315 |
| 474 // Set up some expectations. | 316 // Set up some expectations. |
| 475 // TODO(robertshield): Set up some real expectations. | 317 // TODO(robertshield): Set up some real expectations. |
| 476 EXPECT_CALL(work_item_list, AddCopyTreeWorkItem(_, _, _, _, _)) | 318 EXPECT_CALL(work_item_list, AddCopyTreeWorkItem(_, _, _, _, _)) |
| 477 .Times(AtLeast(1)); | 319 .Times(AtLeast(1)); |
| 478 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem(_, _, _)) | 320 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem(_, _, _)) |
| 479 .WillRepeatedly(Return(create_reg_key_work_item.get())); | 321 .WillRepeatedly(Return(create_reg_key_work_item.get())); |
| 480 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem(_, _, _, _, _, _)) | 322 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem(_, _, _, _, _, _)) |
| 481 .WillRepeatedly(Return(set_reg_value_work_item.get())); | 323 .WillRepeatedly(Return(set_reg_value_work_item.get())); |
| 482 EXPECT_CALL(work_item_list, AddDeleteTreeWorkItem(_, _)) | 324 EXPECT_CALL(work_item_list, AddDeleteTreeWorkItem(_, _)) |
| 483 .WillRepeatedly(Return(delete_tree_work_item.get())); | 325 .WillRepeatedly(Return(delete_tree_work_item.get())); |
| 484 EXPECT_CALL(work_item_list, AddDeleteRegKeyWorkItem(_, _, _)) | 326 EXPECT_CALL(work_item_list, AddDeleteRegKeyWorkItem(_, _, _)) |
| 485 .WillRepeatedly(Return(delete_reg_key_work_item.get())); | 327 .WillRepeatedly(Return(delete_reg_key_work_item.get())); |
| 486 | 328 |
| 487 AddInstallWorkItems(*installation_state.get(), | 329 AddInstallWorkItems(*installation_state.get(), |
| 488 *installer_state.get(), | 330 *installer_state.get(), |
| 489 setup_path_, | 331 setup_path_, |
| 490 archive_path_, | 332 archive_path_, |
| 491 src_path_, | 333 src_path_, |
| 492 temp_dir_, | 334 temp_dir_, |
| 493 current_version_.get(), | 335 current_version_.get(), |
| 494 *new_version_.get(), | 336 *new_version_.get(), |
| 495 &work_item_list); | 337 &work_item_list); |
| 496 } | 338 } |
| 497 | |
| 498 namespace { | |
| 499 | |
| 500 const wchar_t old_elevation_key[] = | |
| 501 L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\" | |
| 502 L"{6C288DD7-76FB-4721-B628-56FAC252E199}"; | |
| 503 | |
| 504 } // namespace | |
| 505 | |
| 506 // A test class for worker functions that manipulate the old IE low rights | |
| 507 // policies. | |
| 508 // Parameters: | |
| 509 // bool : system_level_ | |
| 510 // bool : multi_install_ | |
| 511 class OldIELowRightsTests : public InstallWorkerTest, | |
| 512 public ::testing::WithParamInterface<std::tr1::tuple<bool, bool> > { | |
| 513 protected: | |
| 514 void SetUp() override { | |
| 515 InstallWorkerTest::SetUp(); | |
| 516 | |
| 517 const ParamType& param = GetParam(); | |
| 518 system_level_ = std::tr1::get<0>(param); | |
| 519 multi_install_ = std::tr1::get<1>(param); | |
| 520 root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
| 521 | |
| 522 installation_state_.reset(new MockInstallationState()); | |
| 523 AddChromeFrameToInstallationState(system_level_, multi_install_, | |
| 524 installation_state_.get()); | |
| 525 installer_state_.reset(BuildBasicInstallerState( | |
| 526 system_level_, multi_install_, *installation_state_, | |
| 527 multi_install_ ? InstallerState::MULTI_UPDATE : | |
| 528 InstallerState::SINGLE_INSTALL_OR_UPDATE)); | |
| 529 if (multi_install_) | |
| 530 AddChromeBinariesToInstallerState(*installation_state_, | |
| 531 installer_state_.get()); | |
| 532 AddChromeFrameToInstallerState(*installation_state_, | |
| 533 installer_state_.get()); | |
| 534 } | |
| 535 | |
| 536 std::unique_ptr<MockInstallationState> installation_state_; | |
| 537 std::unique_ptr<MockInstallerState> installer_state_; | |
| 538 bool system_level_; | |
| 539 bool multi_install_; | |
| 540 HKEY root_key_; | |
| 541 }; | |
| 542 | |
| 543 TEST_P(OldIELowRightsTests, AddDeleteOldIELowRightsPolicyWorkItems) { | |
| 544 StrictMock<MockWorkItemList> work_item_list; | |
| 545 | |
| 546 EXPECT_CALL(work_item_list, | |
| 547 AddDeleteRegKeyWorkItem(root_key_, StrEq(old_elevation_key), _)) | |
| 548 .Times(1); | |
| 549 | |
| 550 AddDeleteOldIELowRightsPolicyWorkItems(*installer_state_.get(), | |
| 551 &work_item_list); | |
| 552 } | |
| 553 | |
| 554 INSTANTIATE_TEST_CASE_P(Variations, OldIELowRightsTests, | |
| 555 Combine(Bool(), Bool())); | |
| 556 | |
| 557 TEST_F(InstallWorkerTest, GoogleUpdateWorkItemsTest) { | |
| 558 const bool system_level = true; | |
| 559 const bool multi_install = true; | |
| 560 MockWorkItemList work_item_list; | |
| 561 | |
| 562 // Per-machine single-install Chrome is installed. | |
| 563 std::unique_ptr<MockInstallationState> installation_state( | |
| 564 BuildChromeInstallationState(system_level, false)); | |
| 565 | |
| 566 MockProductState cf_state; | |
| 567 cf_state.set_version(new base::Version(*current_version_)); | |
| 568 cf_state.set_multi_install(false); | |
| 569 | |
| 570 // Per-machine single-install Chrome Frame is installed. | |
| 571 installation_state->SetProductState(system_level, | |
| 572 BrowserDistribution::CHROME_FRAME, cf_state); | |
| 573 | |
| 574 // Prepare per-machine multi-install Chrome for installation. | |
| 575 std::unique_ptr<MockInstallerState> installer_state(BuildChromeInstallerState( | |
| 576 system_level, multi_install, *installation_state, | |
| 577 InstallerState::MULTI_INSTALL)); | |
| 578 | |
| 579 // Expect the multi Client State key to be created for the binaries. | |
| 580 #if defined(GOOGLE_CHROME_BUILD) | |
| 581 BrowserDistribution* multi_dist = | |
| 582 BrowserDistribution::GetSpecificDistribution( | |
| 583 BrowserDistribution::CHROME_BINARIES); | |
| 584 std::wstring multi_app_guid(multi_dist->GetAppGuid()); | |
| 585 std::wstring multi_client_state_suffix(L"ClientState\\" + multi_app_guid); | |
| 586 std::wstring multi_medium_suffix(L"ClientStateMedium\\" + multi_app_guid); | |
| 587 | |
| 588 // Expect ClientStateMedium to be created for system-level installs. | |
| 589 EXPECT_CALL(work_item_list, | |
| 590 AddCreateRegKeyWorkItem(_, HasSubstr(multi_medium_suffix), _)) | |
| 591 .Times(system_level ? 1 : 0); | |
| 592 #else | |
| 593 std::wstring multi_client_state_suffix(L"Chromium Binaries"); | |
| 594 #endif | |
| 595 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem( | |
| 596 _, HasSubstr(multi_client_state_suffix), _)) | |
| 597 .Times(AnyNumber()); | |
| 598 | |
| 599 // Expect to see a set value for the "TEST" brand code in the multi Client | |
| 600 // State key. | |
| 601 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem( | |
| 602 _, HasSubstr(multi_client_state_suffix), _, | |
| 603 StrEq(google_update::kRegBrandField), | |
| 604 StrEq(L"TEST"), _)).Times(1); | |
| 605 | |
| 606 // There may also be some calls to set 'ap' values. | |
| 607 EXPECT_CALL(work_item_list, AddSetRegStringValueWorkItem( | |
| 608 _, _, _, StrEq(google_update::kRegApField), _, | |
| 609 _)).Times(AnyNumber()); | |
| 610 | |
| 611 // Expect "oeminstall" to be cleared. | |
| 612 EXPECT_CALL(work_item_list, AddDeleteRegValueWorkItem( | |
| 613 _, HasSubstr(multi_client_state_suffix), _, | |
| 614 StrEq(google_update::kRegOemInstallField))) | |
| 615 .Times(1); | |
| 616 | |
| 617 // Expect "eulaaccepted" to set. | |
| 618 EXPECT_CALL(work_item_list, AddSetRegDwordValueWorkItem( | |
| 619 _, HasSubstr(multi_client_state_suffix), _, | |
| 620 StrEq(google_update::kRegEULAAceptedField), | |
| 621 Eq(static_cast<DWORD>(1)), _)).Times(1); | |
| 622 | |
| 623 AddGoogleUpdateWorkItems(*installation_state.get(), | |
| 624 *installer_state.get(), | |
| 625 &work_item_list); | |
| 626 } | |
| 627 | |
| 628 // Test that usagestats values are migrated properly. | |
| 629 TEST_F(InstallWorkerTest, AddUsageStatsWorkItems) { | |
| 630 const bool system_level = true; | |
| 631 const bool multi_install = true; | |
| 632 MockWorkItemList work_item_list; | |
| 633 | |
| 634 std::unique_ptr<MockInstallationState> installation_state( | |
| 635 BuildChromeInstallationState(system_level, multi_install)); | |
| 636 | |
| 637 MockProductState chrome_state; | |
| 638 chrome_state.set_version(new base::Version(*current_version_)); | |
| 639 chrome_state.set_multi_install(false); | |
| 640 chrome_state.set_usagestats(1); | |
| 641 | |
| 642 installation_state->SetProductState(system_level, | |
| 643 BrowserDistribution::CHROME_BROWSER, chrome_state); | |
| 644 | |
| 645 std::unique_ptr<MockInstallerState> installer_state(BuildChromeInstallerState( | |
| 646 system_level, multi_install, *installation_state, | |
| 647 InstallerState::MULTI_INSTALL)); | |
| 648 | |
| 649 // Expect the multi Client State key to be created. | |
| 650 BrowserDistribution* multi_dist = | |
| 651 BrowserDistribution::GetSpecificDistribution( | |
| 652 BrowserDistribution::CHROME_BINARIES); | |
| 653 std::wstring multi_app_guid(multi_dist->GetAppGuid()); | |
| 654 EXPECT_CALL(work_item_list, AddCreateRegKeyWorkItem( | |
| 655 _, HasSubstr(multi_app_guid), _)).Times(1); | |
| 656 | |
| 657 // Expect to see a set value for the usagestats in the multi Client State key. | |
| 658 EXPECT_CALL(work_item_list, AddSetRegDwordValueWorkItem( | |
| 659 _, HasSubstr(multi_app_guid), _, | |
| 660 StrEq(google_update::kRegUsageStatsField), | |
| 661 Eq(static_cast<DWORD>(1)), Eq(true))) | |
| 662 .Times(1); | |
| 663 | |
| 664 // Expect to see some values cleaned up from Chrome's keys. | |
| 665 BrowserDistribution* chrome_dist = | |
| 666 BrowserDistribution::GetSpecificDistribution( | |
| 667 BrowserDistribution::CHROME_BROWSER); | |
| 668 if (system_level) { | |
| 669 #if defined(GOOGLE_CHROME_BUILD) | |
| 670 EXPECT_CALL(work_item_list, | |
| 671 AddDeleteRegValueWorkItem( | |
| 672 _, StrEq(chrome_dist->GetStateMediumKey()), _, | |
| 673 StrEq(google_update::kRegUsageStatsField))).Times(1); | |
| 674 #endif | |
| 675 EXPECT_CALL(work_item_list, | |
| 676 AddDeleteRegValueWorkItem( | |
| 677 Eq(HKEY_CURRENT_USER), StrEq(chrome_dist->GetStateKey()), _, | |
| 678 StrEq(google_update::kRegUsageStatsField))).Times(1); | |
| 679 } | |
| 680 #if defined(GOOGLE_CHROME_BUILD) | |
| 681 const int kDeleteTimes = 1; | |
| 682 #else | |
| 683 // Expect two deletes to the same key name since ClientState and | |
| 684 // ClientStateMedium are identical for Chromium. | |
| 685 const int kDeleteTimes = 2; | |
| 686 #endif | |
| 687 EXPECT_CALL( | |
| 688 work_item_list, | |
| 689 AddDeleteRegValueWorkItem( | |
| 690 Eq(installer_state->root_key()), StrEq(chrome_dist->GetStateKey()), _, | |
| 691 StrEq(google_update::kRegUsageStatsField))).Times(kDeleteTimes); | |
| 692 | |
| 693 AddUsageStatsWorkItems(*installation_state.get(), | |
| 694 *installer_state.get(), | |
| 695 &work_item_list); | |
| 696 } | |
| 697 | |
| 698 // The Quick Enable tests only make sense for the Google Chrome build as it | |
| 699 // interacts with registry values that are specific to Google Update. | |
| 700 #if defined(GOOGLE_CHROME_BUILD) | |
| 701 | |
| 702 // Test scenarios under which the quick-enable-cf command should not exist after | |
| 703 // the run. We're permissive in that we allow the DeleteRegKeyWorkItem even if | |
| 704 // it isn't strictly needed. | |
| 705 class QuickEnableAbsentTest : public InstallWorkerTest { | |
| 706 public: | |
| 707 virtual void SetUp() { | |
| 708 InstallWorkerTest::SetUp(); | |
| 709 root_key_ = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
| 710 delete_reg_key_item_.reset(WorkItem::CreateDeleteRegKeyWorkItem( | |
| 711 root_key_, kRegKeyPath, WorkItem::kWow64Default)); | |
| 712 machine_state_.reset(new MockInstallationState()); | |
| 713 EXPECT_CALL(work_item_list_, AddDeleteRegKeyWorkItem( | |
| 714 Eq(root_key_), StrCaseEq(kRegKeyPath), _)) | |
| 715 .Times(AtMost(1)) | |
| 716 .WillRepeatedly(Return(delete_reg_key_item_.get())); | |
| 717 } | |
| 718 virtual void TearDown() { | |
| 719 machine_state_.reset(); | |
| 720 delete_reg_key_item_.reset(); | |
| 721 root_key_ = NULL; | |
| 722 InstallWorkerTest::TearDown(); | |
| 723 } | |
| 724 protected: | |
| 725 static const bool system_level_ = false; | |
| 726 static const wchar_t kRegKeyPath[]; | |
| 727 HKEY root_key_; | |
| 728 std::unique_ptr<DeleteRegKeyWorkItem> delete_reg_key_item_; | |
| 729 std::unique_ptr<MockInstallationState> machine_state_; | |
| 730 StrictMock<MockWorkItemList> work_item_list_; | |
| 731 }; | |
| 732 | |
| 733 const wchar_t QuickEnableAbsentTest::kRegKeyPath[] = | |
| 734 L"Software\\Google\\Update\\Clients\\" | |
| 735 L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}\\Commands\\quick-enable-cf"; | |
| 736 | |
| 737 TEST_F(QuickEnableAbsentTest, CleanInstallSingleChrome) { | |
| 738 // Install single Chrome on a clean system. | |
| 739 std::unique_ptr<MockInstallerState> installer_state(BuildBasicInstallerState( | |
| 740 system_level_, true, *machine_state_, InstallerState::MULTI_UPDATE)); | |
| 741 AddQuickEnableChromeFrameWorkItems(*installer_state, &work_item_list_); | |
| 742 } | |
| 743 | |
| 744 TEST_F(InstallWorkerTest, WillProductBePresentAfterSetup) { | |
| 745 BrowserDistribution::Type prod_type_list[] = { | |
| 746 BrowserDistribution::CHROME_BROWSER, | |
| 747 BrowserDistribution::CHROME_FRAME, | |
| 748 // Excluding BrowserDistribution::CHROME_BINARIES, since it is installed | |
| 749 // along with other products. | |
| 750 }; | |
| 751 enum { // Index into prod_type_list[]. | |
| 752 TYPE_BROWSER = 0, | |
| 753 TYPE_CF, | |
| 754 NUM_TYPE // This must appear last. | |
| 755 }; | |
| 756 DCHECK(arraysize(prod_type_list) == NUM_TYPE); | |
| 757 InstallerState::Operation op_list[] = { | |
| 758 InstallerState::UNINSTALL, | |
| 759 InstallerState::SINGLE_INSTALL_OR_UPDATE | |
| 760 }; | |
| 761 | |
| 762 const bool system_level = false; | |
| 763 const bool multi_install = true; | |
| 764 | |
| 765 // Loop over machine states: {No product, Chrome, CF, Chrome + CF}. | |
| 766 for (int i_mach = 0; i_mach < (1 << NUM_TYPE); ++i_mach) { | |
| 767 // i_mach is the machine state before operation, as bit mask. | |
| 768 std::unique_ptr<MockInstallationState> machine_state( | |
| 769 new MockInstallationState()); | |
| 770 if ((i_mach & (1 << TYPE_BROWSER)) != 0) { // Add Chrome. | |
| 771 AddChromeToInstallationState(system_level, multi_install, | |
| 772 machine_state.get()); | |
| 773 } | |
| 774 if ((i_mach & (1 << TYPE_CF)) != 0) { // Add Chrome Frame. | |
| 775 AddChromeFrameToInstallationState(system_level, multi_install, | |
| 776 machine_state.get()); | |
| 777 } | |
| 778 | |
| 779 // Loop over operations: {uninstall, install/update}. | |
| 780 for (InstallerState::Operation op : op_list) { | |
| 781 | |
| 782 // Loop over product types to operate on: {TYPE_BROWSER, TYPE_CF}. | |
| 783 for (int i_type_op = 0; i_type_op < NUM_TYPE; ++i_type_op) { | |
| 784 std::unique_ptr<InstallerState> installer_state; | |
| 785 if (i_type_op == TYPE_BROWSER) { | |
| 786 installer_state.reset(BuildChromeInstallerState( | |
| 787 system_level, multi_install, *machine_state, op)); | |
| 788 } else if (i_type_op == TYPE_CF) { | |
| 789 // Skip the CF uninstall case due to limitations in | |
| 790 // BuildChromeFrameInstallerState(). | |
| 791 if (op == InstallerState::UNINSTALL) | |
| 792 continue; | |
| 793 | |
| 794 installer_state.reset(BuildChromeFrameInstallerState( | |
| 795 system_level, multi_install, *machine_state, op)); | |
| 796 } else { | |
| 797 NOTREACHED(); | |
| 798 } | |
| 799 | |
| 800 // Calculate the machine state after operation, as bit mask. | |
| 801 // If uninstall, remove product with bitwise AND; else add with OR. | |
| 802 int mach_after = (op == InstallerState::UNINSTALL) | |
| 803 ? i_mach & ~(1 << i_type_op) | |
| 804 : i_mach | (1 << i_type_op); | |
| 805 | |
| 806 // Verify predicted presence of Chrome Binaries. | |
| 807 bool bin_res = installer::WillProductBePresentAfterSetup( | |
| 808 *installer_state, | |
| 809 *machine_state, | |
| 810 BrowserDistribution::CHROME_BINARIES); | |
| 811 // Binaries are expected to be present iff any product is installed. | |
| 812 bool bin_expect = mach_after != 0; | |
| 813 EXPECT_EQ(bin_expect, bin_res); | |
| 814 | |
| 815 // Loop over product types to check: {TYPE_BROWSER, TYPE_CF}. | |
| 816 for (int i_type_check = 0; i_type_check < NUM_TYPE; ++i_type_check) { | |
| 817 // Verify predicted presence of product. | |
| 818 bool prod_res = installer::WillProductBePresentAfterSetup( | |
| 819 *installer_state, | |
| 820 *machine_state, | |
| 821 prod_type_list[i_type_check]); | |
| 822 bool prod_expect = (mach_after & (1 << i_type_check)) != 0; | |
| 823 EXPECT_EQ(prod_expect, prod_res); | |
| 824 } | |
| 825 } | |
| 826 } | |
| 827 } | |
| 828 } | |
| 829 | |
| 830 #endif // defined(GOOGLE_CHROME_BUILD) | |
| OLD | NEW |