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" |
10 #include "base/version.h" | 11 #include "base/version.h" |
11 #include "base/win/registry.h" | 12 #include "base/win/registry.h" |
12 #include "chrome/common/chrome_constants.h" | 13 #include "chrome/common/chrome_constants.h" |
13 #include "chrome/installer/setup/installer_state.h" | 14 #include "chrome/installer/setup/installer_state.h" |
14 #include "chrome/installer/setup/setup_util.h" | 15 #include "chrome/installer/setup/setup_util.h" |
15 #include "chrome/installer/util/create_reg_key_work_item.h" | 16 #include "chrome/installer/util/create_reg_key_work_item.h" |
16 #include "chrome/installer/util/delete_reg_key_work_item.h" | 17 #include "chrome/installer/util/delete_reg_key_work_item.h" |
17 #include "chrome/installer/util/delete_tree_work_item.h" | 18 #include "chrome/installer/util/delete_tree_work_item.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 bool)); | 110 bool)); |
110 MOCK_METHOD3(AddSelfRegWorkItem, WorkItem* (const std::wstring&, | 111 MOCK_METHOD3(AddSelfRegWorkItem, WorkItem* (const std::wstring&, |
111 bool, | 112 bool, |
112 bool)); | 113 bool)); |
113 }; | 114 }; |
114 | 115 |
115 class MockProductState : public ProductState { | 116 class MockProductState : public ProductState { |
116 public: | 117 public: |
117 // Takes ownership of |version|. | 118 // Takes ownership of |version|. |
118 void set_version(base::Version* version) { version_.reset(version); } | 119 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; } | 120 void set_brand(const std::wstring& brand) { brand_ = brand; } |
121 void set_eula_accepted(DWORD eula_accepted) { | 121 void set_eula_accepted(DWORD eula_accepted) { |
122 has_eula_accepted_ = true; | 122 has_eula_accepted_ = true; |
123 eula_accepted_ = eula_accepted; | 123 eula_accepted_ = eula_accepted; |
124 } | 124 } |
125 void clear_eula_accepted() { has_eula_accepted_ = false; } | 125 void clear_eula_accepted() { has_eula_accepted_ = false; } |
126 void set_usagestats(DWORD usagestats) { | 126 void set_usagestats(DWORD usagestats) { |
127 has_usagestats_ = true; | 127 has_usagestats_ = true; |
128 usagestats_ = usagestats; | 128 usagestats_ = usagestats; |
129 } | 129 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 | 163 |
164 void set_operation(Operation operation) { operation_ = operation; } | 164 void set_operation(Operation operation) { operation_ = operation; } |
165 | 165 |
166 void set_state_key(const std::wstring& state_key) { | 166 void set_state_key(const std::wstring& state_key) { |
167 state_key_ = state_key; | 167 state_key_ = state_key; |
168 } | 168 } |
169 | 169 |
170 void set_state_type(BrowserDistribution::Type state_type) { | 170 void set_state_type(BrowserDistribution::Type state_type) { |
171 state_type_ = state_type; | 171 state_type_ = state_type; |
172 } | 172 } |
173 | |
174 void set_package_type(PackageType type) { | |
175 InstallerState::set_package_type(type); | |
176 } | |
177 }; | 173 }; |
178 | 174 |
179 // The test fixture | 175 // The test fixture |
180 //------------------------------------------------------------------------------ | 176 //------------------------------------------------------------------------------ |
181 | 177 |
182 class InstallWorkerTest : public testing::Test { | 178 class InstallWorkerTest : public testing::Test { |
183 public: | 179 public: |
184 void SetUp() override { | 180 void SetUp() override { |
185 current_version_.reset(new base::Version("1.0.0.0")); | 181 current_version_.reset(new base::Version("1.0.0.0")); |
186 new_version_.reset(new base::Version("42.0.0.0")); | 182 new_version_.reset(new base::Version("42.0.0.0")); |
187 | 183 |
188 // Don't bother ensuring that these paths exist. Since we're just | 184 // 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 | 185 // building the work item lists and not running them, they shouldn't |
190 // actually be touched. | 186 // actually be touched. |
191 archive_path_ = | 187 archive_path_ = |
192 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z"); | 188 base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123\\chrome.7z"); |
193 // TODO(robertshield): Take this from the BrowserDistribution once that | 189 // TODO(robertshield): Take this from the BrowserDistribution once that |
194 // no longer depends on MasterPreferences. | 190 // no longer depends on MasterPreferences. |
195 installation_path_ = | 191 installation_path_ = |
196 base::FilePath(L"C:\\Program Files\\Google\\Chrome\\"); | 192 base::FilePath(L"C:\\Program Files\\Google\\Chrome\\"); |
197 src_path_ = base::FilePath( | 193 src_path_ = base::FilePath( |
198 L"C:\\UnlikelyPath\\Temp\\chrome_123\\source\\Chrome-bin"); | 194 L"C:\\UnlikelyPath\\Temp\\chrome_123\\source\\Chrome-bin"); |
199 setup_path_ = base::FilePath( | 195 setup_path_ = base::FilePath( |
200 L"C:\\UnlikelyPath\\Temp\\CR_123.tmp\\setup.exe"); | 196 L"C:\\UnlikelyPath\\Temp\\CR_123.tmp\\setup.exe"); |
201 temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123"); | 197 temp_dir_ = base::FilePath(L"C:\\UnlikelyPath\\Temp\\chrome_123"); |
202 } | 198 } |
203 | 199 |
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( | 200 void AddChromeToInstallationState( |
235 bool system_level, | 201 bool system_level, |
236 bool multi_install, | |
237 MockInstallationState* installation_state) { | 202 MockInstallationState* installation_state) { |
238 if (multi_install) | |
239 MaybeAddBinariesToInstallationState(system_level, installation_state); | |
240 MockProductState product_state; | 203 MockProductState product_state; |
241 product_state.set_version(new base::Version(*current_version_)); | 204 product_state.set_version(new base::Version(*current_version_)); |
242 product_state.set_multi_install(multi_install); | |
243 product_state.set_brand(L"TEST"); | 205 product_state.set_brand(L"TEST"); |
244 product_state.set_eula_accepted(1); | 206 product_state.set_eula_accepted(1); |
245 BrowserDistribution* dist = | 207 BrowserDistribution* dist = |
246 BrowserDistribution::GetSpecificDistribution( | 208 BrowserDistribution::GetSpecificDistribution( |
247 BrowserDistribution::CHROME_BROWSER); | 209 BrowserDistribution::CHROME_BROWSER); |
248 base::FilePath install_path = | 210 base::FilePath install_path = |
249 installer::GetChromeInstallPath(system_level, dist); | 211 installer::GetChromeInstallPath(system_level, dist); |
250 product_state.SetUninstallProgram( | 212 product_state.SetUninstallProgram( |
251 install_path.AppendASCII(current_version_->GetString()) | 213 install_path.AppendASCII(current_version_->GetString()) |
252 .Append(installer::kInstallerDir) | 214 .Append(installer::kInstallerDir) |
253 .Append(installer::kSetupExe)); | 215 .Append(installer::kSetupExe)); |
254 product_state.AddUninstallSwitch(installer::switches::kUninstall); | 216 product_state.AddUninstallSwitch(installer::switches::kUninstall); |
255 if (system_level) | 217 if (system_level) |
256 product_state.AddUninstallSwitch(installer::switches::kSystemLevel); | 218 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 | 219 |
262 installation_state->SetProductState(system_level, | 220 installation_state->SetProductState(system_level, |
263 BrowserDistribution::CHROME_BROWSER, | 221 BrowserDistribution::CHROME_BROWSER, |
264 product_state); | 222 product_state); |
265 } | 223 } |
266 | 224 |
267 void AddChromeFrameToInstallationState( | 225 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( | 226 std::unique_ptr<MockInstallationState> installation_state( |
301 new MockInstallationState()); | 227 new MockInstallationState()); |
302 AddChromeToInstallationState(system_level, multi_install, | 228 AddChromeToInstallationState(system_level, installation_state.get()); |
303 installation_state.get()); | |
304 return installation_state.release(); | 229 return installation_state.release(); |
305 } | 230 } |
306 | 231 |
307 static MockInstallerState* BuildBasicInstallerState( | 232 static MockInstallerState* BuildBasicInstallerState( |
308 bool system_install, | 233 bool system_install, |
309 bool multi_install, | |
310 const InstallationState& machine_state, | 234 const InstallationState& machine_state, |
311 InstallerState::Operation operation) { | 235 InstallerState::Operation operation) { |
312 std::unique_ptr<MockInstallerState> installer_state( | 236 std::unique_ptr<MockInstallerState> installer_state( |
313 new MockInstallerState()); | 237 new MockInstallerState()); |
314 | 238 |
315 InstallerState::Level level = system_install ? | 239 InstallerState::Level level = system_install ? |
316 InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL; | 240 InstallerState::SYSTEM_LEVEL : InstallerState::USER_LEVEL; |
317 installer_state->set_level(level); | 241 installer_state->set_level(level); |
318 installer_state->set_operation(operation); | 242 installer_state->set_operation(operation); |
319 // Hope this next one isn't checked for now. | 243 // Hope this next one isn't checked for now. |
320 installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH"); | 244 installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH"); |
321 installer_state->set_state_type(BrowserDistribution::CHROME_BROWSER); | 245 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(); | 246 return installer_state.release(); |
326 } | 247 } |
327 | 248 |
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( | 249 static void AddChromeToInstallerState( |
356 const InstallationState& machine_state, | 250 const InstallationState& machine_state, |
357 MockInstallerState* installer_state) { | 251 MockInstallerState* installer_state) { |
358 // Fresh install or upgrade? | 252 // Fresh install or upgrade? |
359 const ProductState* chrome = | 253 const ProductState* chrome = |
360 machine_state.GetProductState(installer_state->system_install(), | 254 machine_state.GetProductState(installer_state->system_install(), |
361 BrowserDistribution::CHROME_BROWSER); | 255 BrowserDistribution::CHROME_BROWSER); |
362 if (chrome != NULL && | 256 if (chrome) { |
363 chrome->is_multi_install() == installer_state->is_multi_install()) { | |
364 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, | 257 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, |
365 *chrome); | 258 *chrome); |
366 } else { | 259 } else { |
367 BrowserDistribution* dist = | 260 BrowserDistribution* dist = |
368 BrowserDistribution::GetSpecificDistribution( | 261 BrowserDistribution::GetSpecificDistribution( |
369 BrowserDistribution::CHROME_BROWSER); | 262 BrowserDistribution::CHROME_BROWSER); |
370 std::unique_ptr<Product> product(new Product(dist)); | 263 std::unique_ptr<Product> product(new 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); | 264 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 |