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/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 "testing/gmock/include/gmock/gmock.h"
18 using base::win::RegKey
;
19 using registry_util::RegistryOverrideManager
;
21 using ::testing::Return
;
22 using ::testing::StrEq
;
24 class MockRegistryValuePredicate
: public InstallUtil::RegistryValuePredicate
{
26 MOCK_CONST_METHOD1(Evaluate
, bool(const std::wstring
&));
29 class InstallUtilTest
: public TestWithTempDirAndDeleteTempOverrideKeys
{
33 TEST_F(InstallUtilTest
, MakeUninstallCommand
) {
34 CommandLine
command_line(CommandLine::NO_PROGRAM
);
36 std::pair
<std::wstring
, std::wstring
> params
[] = {
37 std::make_pair(std::wstring(L
""), std::wstring(L
"")),
38 std::make_pair(std::wstring(L
""), std::wstring(L
"--do-something --silly")),
39 std::make_pair(std::wstring(L
"spam.exe"), std::wstring(L
"")),
40 std::make_pair(std::wstring(L
"spam.exe"),
41 std::wstring(L
"--do-something --silly")),
43 for (int i
= 0; i
< arraysize(params
); ++i
) {
44 std::pair
<std::wstring
, std::wstring
>& param
= params
[i
];
45 InstallUtil::MakeUninstallCommand(param
.first
, param
.second
, &command_line
);
46 EXPECT_EQ(param
.first
, command_line
.GetProgram().value());
47 if (param
.second
.empty()) {
48 EXPECT_TRUE(command_line
.GetSwitches().empty());
50 EXPECT_EQ(2U, command_line
.GetSwitches().size());
51 EXPECT_TRUE(command_line
.HasSwitch("do-something"));
52 EXPECT_TRUE(command_line
.HasSwitch("silly"));
57 TEST_F(InstallUtilTest
, GetCurrentDate
) {
58 std::wstring
date(InstallUtil::GetCurrentDate());
59 EXPECT_EQ(8, date
.length());
60 if (date
.length() == 8) {
61 // For an invalid date value, SystemTimeToFileTime will fail.
62 // We use this to validate that we have a correct date string.
63 SYSTEMTIME systime
= {0};
65 // Just to make sure our assumption holds.
66 EXPECT_FALSE(SystemTimeToFileTime(&systime
, &ft
));
67 // Now fill in the values from our string.
68 systime
.wYear
= _wtoi(date
.substr(0, 4).c_str());
69 systime
.wMonth
= _wtoi(date
.substr(4, 2).c_str());
70 systime
.wDay
= _wtoi(date
.substr(6, 2).c_str());
71 // Check if they make sense.
72 EXPECT_TRUE(SystemTimeToFileTime(&systime
, &ft
));
76 TEST_F(InstallUtilTest
, UpdateInstallerStageAP
) {
77 const bool system_level
= false;
78 const HKEY root
= system_level
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
;
79 std::wstring
state_key_path(L
"PhonyClientState");
81 // Update the stage when there's no "ap" value.
83 RegistryOverrideManager override_manager
;
84 override_manager
.OverrideRegistry(root
, L
"root_inst_res");
85 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
);
86 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
89 EXPECT_EQ(ERROR_SUCCESS
,
90 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
91 .ReadValue(google_update::kRegApField
, &value
));
92 EXPECT_EQ(L
"-stage:building", value
);
95 // Update the stage when there is an "ap" value.
97 RegistryOverrideManager override_manager
;
98 override_manager
.OverrideRegistry(root
, L
"root_inst_res");
99 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
100 .WriteValue(google_update::kRegApField
, L
"2.0-dev");
101 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
102 installer::BUILDING
);
104 EXPECT_EQ(ERROR_SUCCESS
,
105 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
106 .ReadValue(google_update::kRegApField
, &value
));
107 EXPECT_EQ(L
"2.0-dev-stage:building", value
);
112 RegistryOverrideManager override_manager
;
113 override_manager
.OverrideRegistry(root
, L
"root_inst_res");
114 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
115 .WriteValue(google_update::kRegApField
, L
"2.0-dev-stage:building");
116 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
117 installer::NO_STAGE
);
119 EXPECT_EQ(ERROR_SUCCESS
,
120 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
121 .ReadValue(google_update::kRegApField
, &value
));
122 EXPECT_EQ(L
"2.0-dev", value
);
126 TEST_F(InstallUtilTest
, UpdateInstallerStage
) {
127 const bool system_level
= false;
128 const HKEY root
= system_level
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
;
129 std::wstring
state_key_path(L
"PhonyClientState");
131 // Update the stage when there's no "InstallerExtraCode1" value.
133 RegistryOverrideManager override_manager
;
134 override_manager
.OverrideRegistry(root
, L
"root_inst_res");
135 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
136 .DeleteValue(installer::kInstallerExtraCode1
);
137 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
138 installer::BUILDING
);
140 EXPECT_EQ(ERROR_SUCCESS
,
141 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
142 .ReadValueDW(installer::kInstallerExtraCode1
, &value
));
143 EXPECT_EQ(static_cast<DWORD
>(installer::BUILDING
), value
);
146 // Update the stage when there is an "InstallerExtraCode1" value.
148 RegistryOverrideManager override_manager
;
149 override_manager
.OverrideRegistry(root
, L
"root_inst_res");
150 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
151 .WriteValue(installer::kInstallerExtraCode1
,
152 static_cast<DWORD
>(installer::UNPACKING
));
153 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
154 installer::BUILDING
);
156 EXPECT_EQ(ERROR_SUCCESS
,
157 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
158 .ReadValueDW(installer::kInstallerExtraCode1
, &value
));
159 EXPECT_EQ(static_cast<DWORD
>(installer::BUILDING
), value
);
164 RegistryOverrideManager override_manager
;
165 override_manager
.OverrideRegistry(root
, L
"root_inst_res");
166 RegKey(root
, state_key_path
.c_str(), KEY_SET_VALUE
)
167 .WriteValue(installer::kInstallerExtraCode1
, static_cast<DWORD
>(5));
168 InstallUtil::UpdateInstallerStage(system_level
, state_key_path
,
169 installer::NO_STAGE
);
171 EXPECT_EQ(ERROR_FILE_NOT_FOUND
,
172 RegKey(root
, state_key_path
.c_str(), KEY_QUERY_VALUE
)
173 .ReadValueDW(installer::kInstallerExtraCode1
, &value
));
177 TEST_F(InstallUtilTest
, DeleteRegistryKeyIf
) {
178 const HKEY root
= HKEY_CURRENT_USER
;
179 std::wstring
parent_key_path(L
"SomeKey\\ToDelete");
180 std::wstring
child_key_path(parent_key_path
);
181 child_key_path
.append(L
"\\ChildKey\\WithAValue");
182 const wchar_t value_name
[] = L
"some_value_name";
183 const wchar_t value
[] = L
"hi mom";
186 RegistryOverrideManager override_manager
;
187 override_manager
.OverrideRegistry(root
, L
"root_key");
188 // Nothing to delete if the keys aren't even there.
190 MockRegistryValuePredicate pred
;
192 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
193 ASSERT_FALSE(RegKey(root
, parent_key_path
.c_str(),
194 KEY_QUERY_VALUE
).Valid());
195 EXPECT_EQ(InstallUtil::NOT_FOUND
,
196 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
197 child_key_path
, value_name
,
199 EXPECT_FALSE(RegKey(root
, parent_key_path
.c_str(),
200 KEY_QUERY_VALUE
).Valid());
203 // Parent exists, but not child: no delete.
205 MockRegistryValuePredicate pred
;
207 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
208 ASSERT_TRUE(RegKey(root
, parent_key_path
.c_str(), KEY_SET_VALUE
).Valid());
209 EXPECT_EQ(InstallUtil::NOT_FOUND
,
210 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
211 child_key_path
, value_name
,
213 EXPECT_TRUE(RegKey(root
, parent_key_path
.c_str(),
214 KEY_QUERY_VALUE
).Valid());
217 // Child exists, but no value: no delete.
219 MockRegistryValuePredicate pred
;
221 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
222 ASSERT_TRUE(RegKey(root
, child_key_path
.c_str(), KEY_SET_VALUE
).Valid());
223 EXPECT_EQ(InstallUtil::NOT_FOUND
,
224 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
225 child_key_path
, value_name
,
227 EXPECT_TRUE(RegKey(root
, parent_key_path
.c_str(),
228 KEY_QUERY_VALUE
).Valid());
231 // Value exists, but doesn't match: no delete.
233 MockRegistryValuePredicate pred
;
235 EXPECT_CALL(pred
, Evaluate(StrEq(L
"foosball!"))).WillOnce(Return(false));
236 ASSERT_EQ(ERROR_SUCCESS
,
237 RegKey(root
, child_key_path
.c_str(),
238 KEY_SET_VALUE
).WriteValue(value_name
, L
"foosball!"));
239 EXPECT_EQ(InstallUtil::NOT_FOUND
,
240 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
241 child_key_path
, value_name
,
243 EXPECT_TRUE(RegKey(root
, parent_key_path
.c_str(),
244 KEY_QUERY_VALUE
).Valid());
247 // Value exists, and matches: delete.
249 MockRegistryValuePredicate pred
;
251 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
252 ASSERT_EQ(ERROR_SUCCESS
,
253 RegKey(root
, child_key_path
.c_str(),
254 KEY_SET_VALUE
).WriteValue(value_name
, value
));
255 EXPECT_EQ(InstallUtil::DELETED
,
256 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
257 child_key_path
, value_name
,
259 EXPECT_FALSE(RegKey(root
, parent_key_path
.c_str(),
260 KEY_QUERY_VALUE
).Valid());
263 // Default value exists and matches: delete.
265 MockRegistryValuePredicate pred
;
267 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
268 ASSERT_EQ(ERROR_SUCCESS
,
269 RegKey(root
, child_key_path
.c_str(),
270 KEY_SET_VALUE
).WriteValue(NULL
, value
));
271 EXPECT_EQ(InstallUtil::DELETED
,
272 InstallUtil::DeleteRegistryKeyIf(root
, parent_key_path
,
273 child_key_path
, NULL
,
275 EXPECT_FALSE(RegKey(root
, parent_key_path
.c_str(),
276 KEY_QUERY_VALUE
).Valid());
281 TEST_F(InstallUtilTest
, DeleteRegistryValueIf
) {
282 const HKEY root
= HKEY_CURRENT_USER
;
283 std::wstring
key_path(L
"SomeKey\\ToDelete");
284 const wchar_t value_name
[] = L
"some_value_name";
285 const wchar_t value
[] = L
"hi mom";
288 RegistryOverrideManager override_manager
;
289 override_manager
.OverrideRegistry(root
, L
"root_key");
290 // Nothing to delete if the key isn't even there.
292 MockRegistryValuePredicate pred
;
294 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
295 ASSERT_FALSE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
296 EXPECT_EQ(InstallUtil::NOT_FOUND
,
297 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
299 EXPECT_FALSE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
302 // Key exists, but no value: no delete.
304 MockRegistryValuePredicate pred
;
306 EXPECT_CALL(pred
, Evaluate(_
)).Times(0);
307 ASSERT_TRUE(RegKey(root
, key_path
.c_str(), KEY_SET_VALUE
).Valid());
308 EXPECT_EQ(InstallUtil::NOT_FOUND
,
309 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
311 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
314 // Value exists, but doesn't match: no delete.
316 MockRegistryValuePredicate pred
;
318 EXPECT_CALL(pred
, Evaluate(StrEq(L
"foosball!"))).WillOnce(Return(false));
319 ASSERT_EQ(ERROR_SUCCESS
,
320 RegKey(root
, key_path
.c_str(),
321 KEY_SET_VALUE
).WriteValue(value_name
, L
"foosball!"));
322 EXPECT_EQ(InstallUtil::NOT_FOUND
,
323 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
325 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
326 EXPECT_TRUE(RegKey(root
, key_path
.c_str(),
327 KEY_QUERY_VALUE
).HasValue(value_name
));
330 // Value exists, and matches: delete.
332 MockRegistryValuePredicate pred
;
334 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
335 ASSERT_EQ(ERROR_SUCCESS
,
336 RegKey(root
, key_path
.c_str(),
337 KEY_SET_VALUE
).WriteValue(value_name
, value
));
338 EXPECT_EQ(InstallUtil::DELETED
,
339 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
341 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
342 EXPECT_FALSE(RegKey(root
, key_path
.c_str(),
343 KEY_QUERY_VALUE
).HasValue(value_name
));
348 RegistryOverrideManager override_manager
;
349 override_manager
.OverrideRegistry(root
, L
"root_key");
350 // Default value matches: delete using empty string.
352 MockRegistryValuePredicate pred
;
354 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
355 ASSERT_EQ(ERROR_SUCCESS
,
356 RegKey(root
, key_path
.c_str(),
357 KEY_SET_VALUE
).WriteValue(L
"", value
));
358 EXPECT_EQ(InstallUtil::DELETED
,
359 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(), L
"",
361 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
362 EXPECT_FALSE(RegKey(root
, key_path
.c_str(),
363 KEY_QUERY_VALUE
).HasValue(L
""));
368 RegistryOverrideManager override_manager
;
369 override_manager
.OverrideRegistry(root
, L
"root_key");
370 // Default value matches: delete using NULL.
372 MockRegistryValuePredicate pred
;
374 EXPECT_CALL(pred
, Evaluate(StrEq(value
))).WillOnce(Return(true));
375 ASSERT_EQ(ERROR_SUCCESS
,
376 RegKey(root
, key_path
.c_str(),
377 KEY_SET_VALUE
).WriteValue(L
"", value
));
378 EXPECT_EQ(InstallUtil::DELETED
,
379 InstallUtil::DeleteRegistryValueIf(root
, key_path
.c_str(),
381 EXPECT_TRUE(RegKey(root
, key_path
.c_str(), KEY_QUERY_VALUE
).Valid());
382 EXPECT_FALSE(RegKey(root
, key_path
.c_str(),
383 KEY_QUERY_VALUE
).HasValue(L
""));
388 TEST_F(InstallUtilTest
, ValueEquals
) {
389 InstallUtil::ValueEquals
pred(L
"howdy");
391 EXPECT_FALSE(pred
.Evaluate(L
""));
392 EXPECT_FALSE(pred
.Evaluate(L
"Howdy"));
393 EXPECT_FALSE(pred
.Evaluate(L
"howdy!"));
394 EXPECT_FALSE(pred
.Evaluate(L
"!howdy"));
395 EXPECT_TRUE(pred
.Evaluate(L
"howdy"));
398 TEST_F(InstallUtilTest
, ProgramCompare
) {
399 base::FilePath
some_long_dir(
400 test_dir_
.path().Append(L
"Some Long Directory Name"));
401 base::FilePath
expect(some_long_dir
.Append(L
"file.txt"));
402 base::FilePath
expect_upcase(some_long_dir
.Append(L
"FILE.txt"));
403 base::FilePath
other(some_long_dir
.Append(L
"otherfile.txt"));
405 // Tests where the expected file doesn't exist.
407 // Paths don't match.
408 EXPECT_FALSE(InstallUtil::ProgramCompare(expect
).Evaluate(
409 L
"\"" + other
.value() + L
"\""));
410 // Paths match exactly.
411 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
412 L
"\"" + expect
.value() + L
"\""));
413 // Paths differ by case.
414 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
415 L
"\"" + expect_upcase
.value() + L
"\""));
417 // Tests where the expected file exists.
418 static const char data
[] = "data";
419 ASSERT_TRUE(base::CreateDirectory(some_long_dir
));
420 ASSERT_NE(-1, file_util::WriteFile(expect
, data
, arraysize(data
) - 1));
421 // Paths don't match.
422 EXPECT_FALSE(InstallUtil::ProgramCompare(expect
).Evaluate(
423 L
"\"" + other
.value() + L
"\""));
424 // Paths match exactly.
425 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
426 L
"\"" + expect
.value() + L
"\""));
427 // Paths differ by case.
428 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
429 L
"\"" + expect_upcase
.value() + L
"\""));
431 // Test where strings don't match, but the same file is indicated.
432 std::wstring short_expect
;
433 DWORD short_len
= GetShortPathName(expect
.value().c_str(),
434 WriteInto(&short_expect
, MAX_PATH
),
436 ASSERT_NE(static_cast<DWORD
>(0), short_len
);
437 ASSERT_GT(static_cast<DWORD
>(MAX_PATH
), short_len
);
438 short_expect
.resize(short_len
);
439 ASSERT_FALSE(base::FilePath::CompareEqualIgnoreCase(expect
.value(),
441 EXPECT_TRUE(InstallUtil::ProgramCompare(expect
).Evaluate(
442 L
"\"" + short_expect
+ L
"\""));