1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/command_line.h"
9 #include "base/files/file_util.h"
10 #include "base/strings/string_util.h"
11 #include "base/test/test_reg_util_win.h"
12 #include "base/win/registry.h"
13 #include "chrome/installer/util/google_update_constants.h"
14 #include "chrome/installer/util/install_util.h"
15 #include "chrome/installer/util/product_unittest.h"
16 #include "chrome/installer/util/work_item.h"
17 #include "testing/gmock/include/gmock/gmock.h"
19 using base::win::RegKey
;
20 using registry_util::RegistryOverrideManager
;
22 using ::testing::Return
;
23 using ::testing::StrEq
;
25 class MockRegistryValuePredicate
: public InstallUtil::RegistryValuePredicate
{
27 MOCK_CONST_METHOD1(Evaluate
, bool(const std::wstring
&));
30 class InstallUtilTest
: public TestWithTempDirAndDeleteTempOverrideKeys
{
34 TEST_F(InstallUtilTest
, MakeUninstallCommand
) {
35 CommandLine
command_line(CommandLine::NO_PROGRAM
);
37 std::pair
<std::wstring
, std::wstring
> params
[] = {
38 std::make_pair(std::wstring(L
""), std::wstring(L
"")),
39 std::make_pair(std::wstring(L
""), std::wstring(L
"--do-something --silly")),
40 std::make_pair(std::wstring(L
"spam.exe"), std::wstring(L
"")),
41 std::make_pair(std::wstring(L
"spam.exe"),
42 std::wstring(L
"--do-something --silly")),
44 for (int i
= 0; i
< arraysize(params
); ++i
) {
45 std::pair
<std::wstring
, std::wstring
>& param
= params
[i
];
46 InstallUtil::MakeUninstallCommand(param
.first
, param
.second
, &command_line
);
47 EXPECT_EQ(param
.first
, command_line
.GetProgram().value());
48 if (param
.second
.empty()) {
49 EXPECT_TRUE(command_line
.GetSwitches().empty());
51 EXPECT_EQ(2U, command_line
.GetSwitches().size());
52 EXPECT_TRUE(command_line
.HasSwitch("do-something"));
53 EXPECT_TRUE(command_line
.HasSwitch("silly"));
58 TEST_F(InstallUtilTest
, GetCurrentDate
) {
59 std::wstring
date(InstallUtil::GetCurrentDate());
60 EXPECT_EQ(8, date
.length());
61 if (date
.length() == 8) {
62 // For an invalid date value, SystemTimeToFileTime will fail.
63 // We use this to validate that we have a correct date string.
64 SYSTEMTIME systime
= {0};
66 // Just to make sure our assumption holds.
67 EXPECT_FALSE(SystemTimeToFileTime(&systime
, &ft
));
68 // Now fill in the values from our string.
69 systime
.wYear
= _wtoi(date
.substr(0, 4).c_str());
70 systime
.wMonth
= _wtoi(date
.substr(4, 2).c_str());
71 systime
.wDay
= _wtoi(date
.substr(6, 2).c_str());
72 // Check if they make sense.
73 EXPECT_TRUE(SystemTimeToFileTime(&systime
, &ft
));
77 TEST_F(InstallUtilTest
, UpdateInstallerStageAP
) {
78 const bool system_level
= false;
79 const HKEY root
= system_level
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
;
80 std::wstring
state_key_path(L
"PhonyClientState");
82 // Update the stage when there's no "ap" value.
84 RegistryOverrideManager override_manager
;
85 override_manager
.OverrideRegistry(root
);
86 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
);
87 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
90 EXPECT_EQ(ERROR_SUCCESS
,
91 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
92 .ReadValue(google_update::kRegApField
, &value
));
93 EXPECT_EQ(L
"-stage:building", value
);
96 // Update the stage when there is an "ap" value.
98 RegistryOverrideManager override_manager
;
99 override_manager
.OverrideRegistry(root
);
100 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
101 .WriteValue(google_update::kRegApField
, L
"2.0-dev");
102 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
103 installer::BUILDING
);
105 EXPECT_EQ(ERROR_SUCCESS
,
106 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
107 .ReadValue(google_update::kRegApField
, &value
));
108 EXPECT_EQ(L
"2.0-dev-stage:building", value
);
113 RegistryOverrideManager override_manager
;
114 override_manager
.OverrideRegistry(root
);
115 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
116 .WriteValue(google_update::kRegApField
, L
"2.0-dev-stage:building");
117 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
118 installer::NO_STAGE
);
120 EXPECT_EQ(ERROR_SUCCESS
,
121 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
122 .ReadValue(google_update::kRegApField
, &value
));
123 EXPECT_EQ(L
"2.0-dev", value
);
127 TEST_F(InstallUtilTest
, UpdateInstallerStage
) {
128 const bool system_level
= false;
129 const HKEY root
= system_level
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
;
130 std::wstring
state_key_path(L
"PhonyClientState");
132 // Update the stage when there's no "InstallerExtraCode1" value.
134 RegistryOverrideManager override_manager
;
135 override_manager
.OverrideRegistry(root
);
136 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
137 .DeleteValue(installer::kInstallerExtraCode1
);
138 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
139 installer::BUILDING
);
141 EXPECT_EQ(ERROR_SUCCESS
,
142 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
143 .ReadValueDW(installer::kInstallerExtraCode1
, &value
));
144 EXPECT_EQ(static_cast<DWORD
>(installer::BUILDING
), value
);
147 // Update the stage when there is an "InstallerExtraCode1" value.
149 RegistryOverrideManager override_manager
;
150 override_manager
.OverrideRegistry(root
);
151 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
152 .WriteValue(installer::kInstallerExtraCode1
,
153 static_cast<DWORD
>(installer::UNPACKING
));
154 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
155 installer::BUILDING
);
157 EXPECT_EQ(ERROR_SUCCESS
,
158 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
159 .ReadValueDW(installer::kInstallerExtraCode1
, &value
));
160 EXPECT_EQ(static_cast<DWORD
>(installer::BUILDING
), value
);
165 RegistryOverrideManager override_manager
;
166 override_manager
.OverrideRegistry(root
);
167 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
168 .WriteValue(installer::kInstallerExtraCode1
, static_cast<DWORD
>(5));
169 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
170 installer::NO_STAGE
);
172 EXPECT_EQ(ERROR_FILE_NOT_FOUND
,
173 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
174 .ReadValueDW(installer::kInstallerExtraCode1
, &value
));
178 TEST_F(InstallUtilTest
, DeleteRegistryKeyIf
) {
179 const HKEY root
= HKEY_CURRENT_USER
;
180 std::wstring
parent_key_path(L
"SomeKey\\ToDelete");
181 std::wstring
child_key_path(parent_key_path
);
182 child_key_path
.append(L
"\\ChildKey\\WithAValue");
183 const wchar_t value_name
[] = L
"some_value_name";
184 const wchar_t value
[] = L
"hi mom";
187 RegistryOverrideManager override_manager
;
188 override_manager
.OverrideRegistry(root
);
189 // Nothing to delete if the keys aren't even there.
191 MockRegistryValuePredicate pred
;
193 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
194 ASSERT_FALSE(RegKey(root
, parent_key_path
.c_str(),
195 KEY_QUERY_VALUE
).Valid());
196 EXPECT_EQ(InstallUtil::NOT_FOUND
,
197 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
199 WorkItem::kWow64Default
,
201 EXPECT_FALSE(RegKey(root
, parent_key_path
.c_str(),
202 KEY_QUERY_VALUE
).Valid());
205 // Parent exists, but not child: no delete.
207 MockRegistryValuePredicate pred
;
209 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
210 ASSERT_TRUE(RegKey(root
, parent_key_path
.c_str(), KEY_SET_VALUE
).Valid());
211 EXPECT_EQ(InstallUtil::NOT_FOUND
,
212 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
214 WorkItem::kWow64Default
,
216 EXPECT_TRUE(RegKey(root
, parent_key_path
.c_str(),
217 KEY_QUERY_VALUE
).Valid());
220 // Child exists, but no value: no delete.
222 MockRegistryValuePredicate pred
;
224 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
225 ASSERT_TRUE(RegKey(root
, child_key_path
.c_str(), KEY_SET_VALUE
).Valid());
226 EXPECT_EQ(InstallUtil::NOT_FOUND
,
227 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
229 WorkItem::kWow64Default
,
231 EXPECT_TRUE(RegKey(root
, parent_key_path
.c_str(),
232 KEY_QUERY_VALUE
).Valid());
235 // Value exists, but doesn't match: no delete.
237 MockRegistryValuePredicate pred
;
239 EXPECT_CALL(pred
, Evaluate(StrEq(L
"foosball!"))).WillOnce(Return(false));
240 ASSERT_EQ(ERROR_SUCCESS
,
241 RegKey(root
, child_key_path
.c_str(),
242 KEY_SET_VALUE
).WriteValue(value_name
, L
"foosball!"));
243 EXPECT_EQ(InstallUtil::NOT_FOUND
,
244 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
246 WorkItem::kWow64Default
,
248 EXPECT_TRUE(RegKey(root
, parent_key_path
.c_str(),
249 KEY_QUERY_VALUE
).Valid());
252 // Value exists, and matches: delete.
254 MockRegistryValuePredicate pred
;
256 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
257 ASSERT_EQ(ERROR_SUCCESS
,
258 RegKey(root
, child_key_path
.c_str(),
259 KEY_SET_VALUE
).WriteValue(value_name
, value
));
260 EXPECT_EQ(InstallUtil::DELETED
,
261 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
263 WorkItem::kWow64Default
,
265 EXPECT_FALSE(RegKey(root
, parent_key_path
.c_str(),
266 KEY_QUERY_VALUE
).Valid());
269 // Default value exists and matches: delete.
271 MockRegistryValuePredicate pred
;
273 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
274 ASSERT_EQ(ERROR_SUCCESS
,
275 RegKey(root
, child_key_path
.c_str(),
276 KEY_SET_VALUE
).WriteValue(NULL
, value
));
277 EXPECT_EQ(InstallUtil::DELETED
,
278 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
280 WorkItem::kWow64Default
,
282 EXPECT_FALSE(RegKey(root
, parent_key_path
.c_str(),
283 KEY_QUERY_VALUE
).Valid());
288 TEST_F(InstallUtilTest
, DeleteRegistryValueIf
) {
289 const HKEY root
= HKEY_CURRENT_USER
;
290 std::wstring
key_path(L
"SomeKey\\ToDelete");
291 const wchar_t value_name
[] = L
"some_value_name";
292 const wchar_t value
[] = L
"hi mom";
295 RegistryOverrideManager override_manager
;
296 override_manager
.OverrideRegistry(root
);
297 // Nothing to delete if the key isn't even there.
299 MockRegistryValuePredicate pred
;
301 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
302 ASSERT_FALSE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
303 EXPECT_EQ(InstallUtil::NOT_FOUND
,
304 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
305 WorkItem::kWow64Default
,
307 EXPECT_FALSE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
310 // Key exists, but no value: no delete.
312 MockRegistryValuePredicate pred
;
314 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
315 ASSERT_TRUE(RegKey(root
, key_path
.c_str(), KEY_SET_VALUE
).Valid());
316 EXPECT_EQ(InstallUtil::NOT_FOUND
,
317 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
318 WorkItem::kWow64Default
,
320 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
323 // Value exists, but doesn't match: no delete.
325 MockRegistryValuePredicate pred
;
327 EXPECT_CALL(pred
, Evaluate(StrEq(L
"foosball!"))).WillOnce(Return(false));
328 ASSERT_EQ(ERROR_SUCCESS
,
329 RegKey(root
, key_path
.c_str(),
330 KEY_SET_VALUE
).WriteValue(value_name
, L
"foosball!"));
331 EXPECT_EQ(InstallUtil::NOT_FOUND
,
332 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
333 WorkItem::kWow64Default
,
335 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
336 EXPECT_TRUE(RegKey(root
, key_path
.c_str(),
337 KEY_QUERY_VALUE
).HasValue(value_name
));
340 // Value exists, and matches: delete.
342 MockRegistryValuePredicate pred
;
344 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
345 ASSERT_EQ(ERROR_SUCCESS
,
346 RegKey(root
, key_path
.c_str(),
347 KEY_SET_VALUE
).WriteValue(value_name
, value
));
348 EXPECT_EQ(InstallUtil::DELETED
,
349 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
350 WorkItem::kWow64Default
,
352 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
353 EXPECT_FALSE(RegKey(root
, key_path
.c_str(),
354 KEY_QUERY_VALUE
).HasValue(value_name
));
359 RegistryOverrideManager override_manager
;
360 override_manager
.OverrideRegistry(root
);
361 // Default value matches: delete using empty string.
363 MockRegistryValuePredicate pred
;
365 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
366 ASSERT_EQ(ERROR_SUCCESS
,
367 RegKey(root
, key_path
.c_str(),
368 KEY_SET_VALUE
).WriteValue(L
"", value
));
369 EXPECT_EQ(InstallUtil::DELETED
,
370 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
371 WorkItem::kWow64Default
, L
"",
373 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
374 EXPECT_FALSE(RegKey(root
, key_path
.c_str(),
375 KEY_QUERY_VALUE
).HasValue(L
""));
380 RegistryOverrideManager override_manager
;
381 override_manager
.OverrideRegistry(root
);
382 // Default value matches: delete using NULL.
384 MockRegistryValuePredicate pred
;
386 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
387 ASSERT_EQ(ERROR_SUCCESS
,
388 RegKey(root
, key_path
.c_str(),
389 KEY_SET_VALUE
).WriteValue(L
"", value
));
390 EXPECT_EQ(InstallUtil::DELETED
,
391 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
392 WorkItem::kWow64Default
,
394 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
395 EXPECT_FALSE(RegKey(root
, key_path
.c_str(),
396 KEY_QUERY_VALUE
).HasValue(L
""));
401 TEST_F(InstallUtilTest
, ValueEquals
) {
402 InstallUtil::ValueEquals
pred(L
"howdy");
404 EXPECT_FALSE(pred
.Evaluate(L
""));
405 EXPECT_FALSE(pred
.Evaluate(L
"Howdy"));
406 EXPECT_FALSE(pred
.Evaluate(L
"howdy!"));
407 EXPECT_FALSE(pred
.Evaluate(L
"!howdy"));
408 EXPECT_TRUE(pred
.Evaluate(L
"howdy"));
411 TEST_F(InstallUtilTest
, ProgramCompare
) {
412 base::FilePath
some_long_dir(
413 test_dir_
.path().Append(L
"Some Long Directory Name"));
414 base::FilePath
expect(some_long_dir
.Append(L
"file.txt"));
415 base::FilePath
expect_upcase(some_long_dir
.Append(L
"FILE.txt"));
416 base::FilePath
other(some_long_dir
.Append(L
"otherfile.txt"));
418 // Tests where the expected file doesn't exist.
420 // Paths don't match.
421 EXPECT_FALSE(InstallUtil::ProgramCompare(expect
).Evaluate(
422 L
"\"" + other
.value() + L
"\""));
423 // Paths match exactly.
424 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
425 L
"\"" + expect
.value() + L
"\""));
426 // Paths differ by case.
427 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
428 L
"\"" + expect_upcase
.value() + L
"\""));
430 // Tests where the expected file exists.
431 static const char data
[] = "data";
432 ASSERT_TRUE(base::CreateDirectory(some_long_dir
));
433 ASSERT_NE(-1, base::WriteFile(expect
, data
, arraysize(data
) - 1));
434 // Paths don't match.
435 EXPECT_FALSE(InstallUtil::ProgramCompare(expect
).Evaluate(
436 L
"\"" + other
.value() + L
"\""));
437 // Paths match exactly.
438 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
439 L
"\"" + expect
.value() + L
"\""));
440 // Paths differ by case.
441 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
442 L
"\"" + expect_upcase
.value() + L
"\""));
444 // Test where strings don't match, but the same file is indicated.
445 std::wstring short_expect
;
446 DWORD short_len
= GetShortPathName(expect
.value().c_str(),
447 WriteInto(&short_expect
, MAX_PATH
),
449 ASSERT_NE(static_cast<DWORD
>(0), short_len
);
450 ASSERT_GT(static_cast<DWORD
>(MAX_PATH
), short_len
);
451 short_expect
.resize(short_len
);
452 ASSERT_FALSE(base::FilePath::CompareEqualIgnoreCase(expect
.value(),
454 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
455 L
"\"" + short_expect
+ L
"\""));