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.
10 #include "base/files/file_path.h"
11 #include "base/macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_util.h"
14 #include "base/test/test_reg_util_win.h"
15 #include "base/win/registry.h"
16 #include "chrome/installer/util/set_reg_value_work_item.h"
17 #include "chrome/installer/util/work_item.h"
18 #include "testing/gtest/include/gtest/gtest.h"
22 const wchar_t kTestKey
[] = L
"TempTemp";
23 const wchar_t kDataStr1
[] = L
"data_111";
24 const wchar_t kDataStr2
[] = L
"data_222";
25 const wchar_t kNameStr
[] = L
"name_str";
26 const wchar_t kNameDword
[] = L
"name_dword";
28 const DWORD kDword1
= 12345;
29 const DWORD kDword2
= 6789;
31 class SetRegValueWorkItemTest
: public testing::Test
{
33 SetRegValueWorkItemTest() {}
35 void SetUp() override
{
36 registry_override_manager_
.OverrideRegistry(HKEY_CURRENT_USER
);
38 // Create a temporary key for testing.
39 ASSERT_NE(ERROR_SUCCESS
,
40 test_key_
.Open(HKEY_CURRENT_USER
, kTestKey
, KEY_READ
));
41 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.Create(HKEY_CURRENT_USER
, kTestKey
,
42 KEY_READ
| KEY_SET_VALUE
));
45 base::win::RegKey test_key_
;
48 registry_util::RegistryOverrideManager registry_override_manager_
;
50 DISALLOW_COPY_AND_ASSIGN(SetRegValueWorkItemTest
);
55 // Write a new value without overwrite flag. The value should be set.
56 TEST_F(SetRegValueWorkItemTest
, WriteNewNonOverwrite
) {
57 scoped_ptr
<SetRegValueWorkItem
> work_item1(
58 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
60 WorkItem::kWow64Default
,
65 scoped_ptr
<SetRegValueWorkItem
> work_item2(
66 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
68 WorkItem::kWow64Default
,
73 ASSERT_TRUE(work_item1
->Do());
74 ASSERT_TRUE(work_item2
->Do());
76 std::wstring read_out
;
78 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
79 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameDword
, &read_dword
));
80 EXPECT_EQ(read_out
, kDataStr1
);
81 EXPECT_EQ(read_dword
, kDword1
);
83 work_item1
->Rollback();
84 work_item2
->Rollback();
86 // Rollback should delete the value.
87 EXPECT_FALSE(test_key_
.HasValue(kNameStr
));
88 EXPECT_FALSE(test_key_
.HasValue(kNameDword
));
91 // Write a new value with overwrite flag. The value should be set.
92 TEST_F(SetRegValueWorkItemTest
, WriteNewOverwrite
) {
93 scoped_ptr
<SetRegValueWorkItem
> work_item1(
94 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
96 WorkItem::kWow64Default
,
101 scoped_ptr
<SetRegValueWorkItem
> work_item2(
102 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
104 WorkItem::kWow64Default
,
109 ASSERT_TRUE(work_item1
->Do());
110 ASSERT_TRUE(work_item2
->Do());
112 std::wstring read_out
;
114 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
115 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameDword
, &read_dword
));
116 EXPECT_EQ(read_out
, kDataStr1
);
117 EXPECT_EQ(read_dword
, kDword1
);
119 work_item1
->Rollback();
120 work_item2
->Rollback();
122 // Rollback should delete the value.
123 EXPECT_FALSE(test_key_
.HasValue(kNameStr
));
124 EXPECT_FALSE(test_key_
.HasValue(kNameDword
));
127 // Write to an existing value without overwrite flag. There should be
129 TEST_F(SetRegValueWorkItemTest
, WriteExistingNonOverwrite
) {
130 // First test REG_SZ value.
131 // Write data to the value we are going to set.
132 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.WriteValue(kNameStr
, kDataStr1
));
134 scoped_ptr
<SetRegValueWorkItem
> work_item(
135 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
137 WorkItem::kWow64Default
,
141 ASSERT_TRUE(work_item
->Do());
143 std::wstring read_out
;
144 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
145 EXPECT_EQ(read_out
, kDataStr1
);
147 work_item
->Rollback();
148 EXPECT_TRUE(test_key_
.HasValue(kNameStr
));
149 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
150 EXPECT_EQ(read_out
, kDataStr1
);
152 // Now test REG_DWORD value.
153 // Write data to the value we are going to set.
154 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.WriteValue(kNameDword
, kDword1
));
155 work_item
.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
157 WorkItem::kWow64Default
,
161 ASSERT_TRUE(work_item
->Do());
164 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameDword
, &read_dword
));
165 EXPECT_EQ(read_dword
, kDword1
);
167 work_item
->Rollback();
168 EXPECT_TRUE(test_key_
.HasValue(kNameDword
));
169 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameDword
, &read_dword
));
170 EXPECT_EQ(read_dword
, kDword1
);
173 // Write to an existing value with overwrite flag. The value should be
175 TEST_F(SetRegValueWorkItemTest
, WriteExistingOverwrite
) {
176 // First test REG_SZ value.
177 // Write data to the value we are going to set.
178 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.WriteValue(kNameStr
, kDataStr1
));
180 const wchar_t kNameEmpty
[] = L
"name_empty";
181 ASSERT_EQ(ERROR_SUCCESS
, RegSetValueEx(test_key_
.Handle(), kNameEmpty
, NULL
,
184 scoped_ptr
<SetRegValueWorkItem
> work_item1(
185 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
187 WorkItem::kWow64Default
,
191 scoped_ptr
<SetRegValueWorkItem
> work_item2(
192 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
194 WorkItem::kWow64Default
,
199 ASSERT_TRUE(work_item1
->Do());
200 ASSERT_TRUE(work_item2
->Do());
202 std::wstring read_out
;
203 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
204 EXPECT_EQ(read_out
, kDataStr2
);
206 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameEmpty
, &read_out
));
207 EXPECT_EQ(read_out
, kDataStr2
);
209 work_item1
->Rollback();
210 work_item2
->Rollback();
212 EXPECT_TRUE(test_key_
.HasValue(kNameStr
));
213 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
214 EXPECT_EQ(read_out
, kDataStr1
);
218 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameEmpty
, NULL
, &size
, &type
));
219 EXPECT_EQ(REG_SZ
, type
);
222 // Now test REG_DWORD value.
223 // Write data to the value we are going to set.
224 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.WriteValue(kNameDword
, kDword1
));
225 scoped_ptr
<SetRegValueWorkItem
> work_item3(
226 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
228 WorkItem::kWow64Default
,
232 ASSERT_TRUE(work_item3
->Do());
235 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameDword
, &read_dword
));
236 EXPECT_EQ(read_dword
, kDword2
);
238 work_item3
->Rollback();
239 EXPECT_TRUE(test_key_
.HasValue(kNameDword
));
240 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameDword
, &read_dword
));
241 EXPECT_EQ(read_dword
, kDword1
);
244 // Write a value to a non-existing key. This should fail.
245 TEST_F(SetRegValueWorkItemTest
, WriteNonExistingKey
) {
246 std::wstring
non_existing(kTestKey
);
247 non_existing
.append(&base::FilePath::kSeparators
[0], 1);
248 non_existing
.append(L
"NonExistingKey");
250 scoped_ptr
<SetRegValueWorkItem
> work_item(
251 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
252 non_existing
.c_str(),
253 WorkItem::kWow64Default
,
257 EXPECT_FALSE(work_item
->Do());
259 work_item
.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
260 non_existing
.c_str(),
261 WorkItem::kWow64Default
,
265 EXPECT_FALSE(work_item
->Do());
268 // Verifies that |actual_previous_value| is |expected_previous_value| and
269 // returns |desired_new_value| to replace it. Unconditionally increments
270 // |invocation_count| to allow tests to assert correctness of the callee's
272 std::wstring
VerifyPreviousValueAndReplace(
273 int* invocation_count
,
274 const std::wstring
& expected_previous_value
,
275 const std::wstring
& desired_new_value
,
276 const std::wstring
& actual_previous_value
) {
277 ++(*invocation_count
);
278 EXPECT_EQ(expected_previous_value
, actual_previous_value
);
279 return desired_new_value
;
282 // Modify an existing value with the callback API.
283 TEST_F(SetRegValueWorkItemTest
, ModifyExistingWithCallback
) {
284 // Write |kDataStr1| to the value we are going to modify.
285 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.WriteValue(kNameStr
, kDataStr1
));
287 int callback_invocation_count
= 0;
289 scoped_ptr
<SetRegValueWorkItem
> work_item(
290 WorkItem::CreateSetRegValueWorkItem(
293 WorkItem::kWow64Default
,
295 base::Bind(&VerifyPreviousValueAndReplace
, &callback_invocation_count
,
296 kDataStr1
, kDataStr2
)));
298 // The callback should not be used until the item is executed.
299 EXPECT_EQ(0, callback_invocation_count
);
301 ASSERT_TRUE(work_item
->Do());
303 std::wstring read_out
;
304 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
305 EXPECT_EQ(read_out
, kDataStr2
);
307 // The callback should have been used only once to achieve this result.
308 EXPECT_EQ(1, callback_invocation_count
);
310 work_item
->Rollback();
312 EXPECT_TRUE(test_key_
.HasValue(kNameStr
));
313 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
314 EXPECT_EQ(read_out
, kDataStr1
);
316 // The callback should not have been used again for the rollback.
317 EXPECT_EQ(1, callback_invocation_count
);
320 // Modify a non-existing value with the callback API.
321 TEST_F(SetRegValueWorkItemTest
, ModifyNonExistingWithCallback
) {
322 int callback_invocation_count
= 0;
324 scoped_ptr
<SetRegValueWorkItem
> work_item(
325 WorkItem::CreateSetRegValueWorkItem(
328 WorkItem::kWow64Default
,
330 base::Bind(&VerifyPreviousValueAndReplace
, &callback_invocation_count
,
333 EXPECT_EQ(0, callback_invocation_count
);
335 ASSERT_TRUE(work_item
->Do());
337 std::wstring read_out
;
338 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_out
));
339 EXPECT_EQ(read_out
, kDataStr1
);
341 EXPECT_EQ(1, callback_invocation_count
);
343 work_item
->Rollback();
345 EXPECT_FALSE(test_key_
.HasValue(kNameStr
));
347 EXPECT_EQ(1, callback_invocation_count
);
350 // Modify an existing value which is not a string (REG_SZ) with the string
352 TEST_F(SetRegValueWorkItemTest
, ModifyExistingNonStringWithStringCallback
) {
353 // Write |kDword1| to the value we are going to modify.
354 ASSERT_EQ(ERROR_SUCCESS
, test_key_
.WriteValue(kNameStr
, kDword1
));
356 int callback_invocation_count
= 0;
358 scoped_ptr
<SetRegValueWorkItem
> work_item(
359 WorkItem::CreateSetRegValueWorkItem(
362 WorkItem::kWow64Default
,
364 base::Bind(&VerifyPreviousValueAndReplace
, &callback_invocation_count
,
367 EXPECT_EQ(0, callback_invocation_count
);
369 ASSERT_TRUE(work_item
->Do());
371 std::wstring read_str_out
;
372 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValue(kNameStr
, &read_str_out
));
373 EXPECT_EQ(read_str_out
, kDataStr1
);
375 EXPECT_EQ(1, callback_invocation_count
);
377 work_item
->Rollback();
379 DWORD read_dword_out
= 0;
380 EXPECT_TRUE(test_key_
.HasValue(kNameStr
));
381 EXPECT_EQ(ERROR_SUCCESS
, test_key_
.ReadValueDW(kNameStr
, &read_dword_out
));
382 EXPECT_EQ(read_dword_out
, kDword1
);
384 EXPECT_EQ(1, callback_invocation_count
);