1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/test/test_reg_util_win.h"
9 #include "base/version.h"
10 #include "base/win/registry.h"
11 #include "chrome/installer/util/browser_distribution.h"
12 #include "chrome/installer/util/google_update_constants.h"
13 #include "chrome/installer/util/installation_state.h"
14 #include "chrome/installer/util/product_unittest.h"
15 #include "chrome/installer/util/util_constants.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using base::win::RegKey
;
19 using installer::ProductState
;
20 using registry_util::RegistryOverrideManager
;
22 class ProductStateTest
: public testing::Test
{
24 static void SetUpTestCase();
25 static void TearDownTestCase();
28 virtual void TearDown();
30 void ApplyUninstallCommand(const wchar_t* exe_path
, const wchar_t* args
);
31 void MinimallyInstallProduct(const wchar_t* version
);
33 static BrowserDistribution
* dist_
;
34 static std::wstring temp_key_path_
;
41 BrowserDistribution
* ProductStateTest::dist_
;
42 std::wstring
ProductStateTest::temp_key_path_
;
45 void ProductStateTest::SetUpTestCase() {
46 testing::Test::SetUpTestCase();
48 // We'll use Chrome as our test subject.
49 dist_
= BrowserDistribution::GetSpecificDistribution(
50 BrowserDistribution::CHROME_BROWSER
);
52 // And we'll play in HKCU here:
53 temp_key_path_
.assign(RegistryOverrideManager::kTempTestKeyPath
)
55 .append(L
"ProductStateTest");
59 void ProductStateTest::TearDownTestCase() {
60 temp_key_path_
.clear();
63 testing::Test::TearDownTestCase();
66 void ProductStateTest::SetUp() {
67 testing::Test::SetUp();
69 // Create/open the keys for the product we'll test.
70 system_install_
= true;
71 overridden_
= (system_install_
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
);
73 // Override for test purposes. We don't use ScopedRegistryKeyOverride
74 // directly because it doesn't suit itself to our use here.
76 EXPECT_EQ(ERROR_SUCCESS
,
77 temp_key
.Create(HKEY_CURRENT_USER
, temp_key_path_
.c_str(),
79 EXPECT_EQ(ERROR_SUCCESS
,
80 ::RegOverridePredefKey(overridden_
, temp_key
.Handle()));
82 EXPECT_EQ(ERROR_SUCCESS
,
83 clients_
.Create(overridden_
, dist_
->GetVersionKey().c_str(),
85 EXPECT_EQ(ERROR_SUCCESS
,
86 client_state_
.Create(overridden_
, dist_
->GetStateKey().c_str(),
90 void ProductStateTest::TearDown() {
91 // Done with the keys.
92 client_state_
.Close();
94 EXPECT_EQ(ERROR_SUCCESS
, ::RegOverridePredefKey(overridden_
, NULL
));
96 system_install_
= false;
98 // Shotgun approach to clearing out data we may have written.
99 RegistryOverrideManager::DeleteAllTempKeys();
101 testing::Test::TearDown();
104 void ProductStateTest::MinimallyInstallProduct(const wchar_t* version
) {
105 EXPECT_EQ(ERROR_SUCCESS
,
106 clients_
.WriteValue(google_update::kRegVersionField
, version
));
109 void ProductStateTest::ApplyUninstallCommand(const wchar_t* exe_path
,
110 const wchar_t* args
) {
111 if (exe_path
== NULL
) {
112 LONG result
= client_state_
.DeleteValue(installer::kUninstallStringField
);
113 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
115 EXPECT_EQ(ERROR_SUCCESS
,
116 client_state_
.WriteValue(installer::kUninstallStringField
,
122 client_state_
.DeleteValue(installer::kUninstallArgumentsField
);
123 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
125 EXPECT_EQ(ERROR_SUCCESS
,
126 client_state_
.WriteValue(installer::kUninstallArgumentsField
,
131 TEST_F(ProductStateTest
, InitializeInstalled
) {
135 LONG result
= clients_
.DeleteValue(google_update::kRegVersionField
);
136 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
137 EXPECT_FALSE(state
.Initialize(system_install_
, dist_
));
143 LONG result
= clients_
.WriteValue(google_update::kRegVersionField
, L
"");
144 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
145 EXPECT_FALSE(state
.Initialize(system_install_
, dist_
));
151 LONG result
= clients_
.WriteValue(google_update::kRegVersionField
,
153 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
154 EXPECT_FALSE(state
.Initialize(system_install_
, dist_
));
160 LONG result
= clients_
.WriteValue(google_update::kRegVersionField
,
162 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
163 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
164 EXPECT_EQ("10.0.47.0", state
.version().GetString());
168 // Test extraction of the "opv" value from the Clients key.
169 TEST_F(ProductStateTest
, InitializeOldVersion
) {
170 MinimallyInstallProduct(L
"10.0.1.1");
175 LONG result
= clients_
.DeleteValue(google_update::kRegOldVersionField
);
176 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
177 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
178 EXPECT_TRUE(state
.old_version() == NULL
);
181 // Empty "opv" value.
184 LONG result
= clients_
.WriteValue(google_update::kRegOldVersionField
, L
"");
185 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
186 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
187 EXPECT_TRUE(state
.old_version() == NULL
);
190 // Bogus "opv" value.
193 LONG result
= clients_
.WriteValue(google_update::kRegOldVersionField
,
195 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
196 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
197 EXPECT_TRUE(state
.old_version() == NULL
);
200 // Valid "opv" value.
203 LONG result
= clients_
.WriteValue(google_update::kRegOldVersionField
,
205 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
206 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
207 EXPECT_TRUE(state
.old_version() != NULL
);
208 EXPECT_EQ("10.0.47.0", state
.old_version()->GetString());
212 // Test extraction of the "cmd" value from the Clients key.
213 TEST_F(ProductStateTest
, InitializeRenameCmd
) {
214 MinimallyInstallProduct(L
"10.0.1.1");
219 LONG result
= clients_
.DeleteValue(google_update::kRegRenameCmdField
);
220 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
221 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
222 EXPECT_TRUE(state
.rename_cmd().empty());
225 // Empty "cmd" value.
228 LONG result
= clients_
.WriteValue(google_update::kRegRenameCmdField
, L
"");
229 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
230 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
231 EXPECT_TRUE(state
.rename_cmd().empty());
234 // Valid "cmd" value.
237 LONG result
= clients_
.WriteValue(google_update::kRegRenameCmdField
,
238 L
"spam.exe --spamalot");
239 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
240 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
241 EXPECT_EQ(L
"spam.exe --spamalot", state
.rename_cmd());
245 // Test extraction of the "ap" value from the ClientState key.
246 TEST_F(ProductStateTest
, InitializeChannelInfo
) {
247 MinimallyInstallProduct(L
"10.0.1.1");
252 LONG result
= client_state_
.DeleteValue(google_update::kRegApField
);
253 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
254 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
255 EXPECT_TRUE(state
.channel().value().empty());
261 LONG result
= client_state_
.WriteValue(google_update::kRegApField
, L
"");
262 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
263 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
264 EXPECT_TRUE(state
.channel().value().empty());
270 LONG result
= client_state_
.WriteValue(google_update::kRegApField
, L
"spam");
271 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
272 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
273 EXPECT_EQ(L
"spam", state
.channel().value());
277 // Test extraction of the uninstall command and arguments from the ClientState
279 TEST_F(ProductStateTest
, InitializeUninstallCommand
) {
280 MinimallyInstallProduct(L
"10.0.1.1");
282 // No uninstall command.
285 ApplyUninstallCommand(NULL
, NULL
);
286 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
287 EXPECT_TRUE(state
.GetSetupPath().empty());
288 EXPECT_TRUE(state
.uninstall_command().GetCommandLineString().empty());
289 EXPECT_TRUE(state
.uninstall_command().GetSwitches().empty());
295 ApplyUninstallCommand(L
"", L
"");
296 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
297 EXPECT_TRUE(state
.GetSetupPath().empty());
298 EXPECT_TRUE(state
.uninstall_command().GetCommandLineString().empty());
299 EXPECT_TRUE(state
.uninstall_command().GetSwitches().empty());
302 // Uninstall command without exe.
305 ApplyUninstallCommand(NULL
, L
"--uninstall");
306 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
307 EXPECT_TRUE(state
.GetSetupPath().empty());
308 EXPECT_EQ(L
" --uninstall",
309 state
.uninstall_command().GetCommandLineString());
310 EXPECT_EQ(1U, state
.uninstall_command().GetSwitches().size());
313 // Uninstall command without args.
316 ApplyUninstallCommand(L
"setup.exe", NULL
);
317 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
318 EXPECT_EQ(L
"setup.exe", state
.GetSetupPath().value());
319 EXPECT_EQ(L
"setup.exe", state
.uninstall_command().GetCommandLineString());
320 EXPECT_TRUE(state
.uninstall_command().GetSwitches().empty());
323 // Uninstall command with exe that requires quoting.
326 ApplyUninstallCommand(L
"set up.exe", NULL
);
327 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
328 EXPECT_EQ(L
"set up.exe", state
.GetSetupPath().value());
329 EXPECT_EQ(L
"\"set up.exe\"",
330 state
.uninstall_command().GetCommandLineString());
331 EXPECT_TRUE(state
.uninstall_command().GetSwitches().empty());
334 // Uninstall command with both exe and args.
337 ApplyUninstallCommand(L
"setup.exe", L
"--uninstall");
338 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
339 EXPECT_EQ(L
"setup.exe", state
.GetSetupPath().value());
340 EXPECT_EQ(L
"setup.exe --uninstall",
341 state
.uninstall_command().GetCommandLineString());
342 EXPECT_EQ(1U, state
.uninstall_command().GetSwitches().size());
346 // Test extraction of the msi marker from the ClientState key.
347 TEST_F(ProductStateTest
, InitializeMsi
) {
348 MinimallyInstallProduct(L
"10.0.1.1");
353 LONG result
= client_state_
.DeleteValue(google_update::kRegMSIField
);
354 EXPECT_TRUE(result
== ERROR_SUCCESS
|| result
== ERROR_FILE_NOT_FOUND
);
355 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
356 EXPECT_FALSE(state
.is_msi());
359 // Msi marker set to zero.
362 EXPECT_EQ(ERROR_SUCCESS
,
363 client_state_
.WriteValue(google_update::kRegMSIField
,
364 static_cast<DWORD
>(0)));
365 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
366 EXPECT_FALSE(state
.is_msi());
369 // Msi marker set to one.
372 EXPECT_EQ(ERROR_SUCCESS
,
373 client_state_
.WriteValue(google_update::kRegMSIField
,
374 static_cast<DWORD
>(1)));
375 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
376 EXPECT_TRUE(state
.is_msi());
379 // Msi marker set to a bogus DWORD.
382 EXPECT_EQ(ERROR_SUCCESS
,
383 client_state_
.WriteValue(google_update::kRegMSIField
,
384 static_cast<DWORD
>(47)));
385 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
386 EXPECT_TRUE(state
.is_msi());
389 // Msi marker set to a bogus string.
392 EXPECT_EQ(ERROR_SUCCESS
,
393 client_state_
.WriteValue(google_update::kRegMSIField
,
395 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
396 EXPECT_FALSE(state
.is_msi());
400 // Test detection of multi-install.
401 TEST_F(ProductStateTest
, InitializeMultiInstall
) {
402 MinimallyInstallProduct(L
"10.0.1.1");
404 // No uninstall command means single install.
407 ApplyUninstallCommand(NULL
, NULL
);
408 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
409 EXPECT_FALSE(state
.is_multi_install());
412 // Uninstall command without --multi-install is single install.
415 ApplyUninstallCommand(L
"setup.exe", L
"--uninstall");
416 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
417 EXPECT_FALSE(state
.is_multi_install());
420 // Uninstall command with --multi-install is multi install.
423 ApplyUninstallCommand(L
"setup.exe",
424 L
"--uninstall --chrome --multi-install");
425 EXPECT_TRUE(state
.Initialize(system_install_
, dist_
));
426 EXPECT_TRUE(state
.is_multi_install());