set_reg_value_work_item_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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.
4
5#include <windows.h>
6
7#include "base/files/file_path.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/strings/string_util.h"
10#include "base/win/registry.h"
11#include "chrome/installer/util/set_reg_value_work_item.h"
12#include "chrome/installer/util/work_item.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using base::win::RegKey;
16
17namespace {
18
19const wchar_t kTestRoot[] = L"TempTemp";
20const wchar_t kDataStr1[] = L"data_111";
21const wchar_t kDataStr2[] = L"data_222";
22const wchar_t kNameStr[] = L"name_str";
23const wchar_t kNameDword[] = L"name_dword";
24
25const DWORD dword1 = 0;
26const DWORD dword2 = 1;
27
28class SetRegValueWorkItemTest : public testing::Test {
29 protected:
30  virtual void SetUp() {
31    // Create a temporary key for testing
32    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
33    key.DeleteKey(kTestRoot);
34    ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
35    ASSERT_EQ(ERROR_SUCCESS,
36        key.Create(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
37  }
38  virtual void TearDown() {
39    logging::CloseLogFile();
40    // Clean up the temporary key
41    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
42    ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kTestRoot));
43  }
44};
45
46}  // namespace
47
48// Write a new value without overwrite flag. The value should be set.
49TEST_F(SetRegValueWorkItemTest, WriteNewNonOverwrite) {
50  RegKey key;
51
52  std::wstring parent_key(kTestRoot);
53  parent_key.append(&base::FilePath::kSeparators[0], 1);
54  parent_key.append(L"WriteNewNonOverwrite");
55  ASSERT_EQ(ERROR_SUCCESS,
56      key.Create(HKEY_CURRENT_USER, parent_key.c_str(), KEY_READ));
57
58  std::wstring name_str(kNameStr);
59  std::wstring data_str(kDataStr1);
60  scoped_ptr<SetRegValueWorkItem> work_item1(
61      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
62                                          parent_key,
63                                          WorkItem::kWow64Default,
64                                          name_str,
65                                          data_str,
66                                          false));
67
68  std::wstring name_dword(kNameDword);
69  scoped_ptr<SetRegValueWorkItem> work_item2(
70      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
71                                          parent_key,
72                                          WorkItem::kWow64Default,
73                                          name_dword,
74                                          dword1,
75                                          false));
76
77  EXPECT_TRUE(work_item1->Do());
78  EXPECT_TRUE(work_item2->Do());
79
80  std::wstring read_out;
81  DWORD read_dword;
82  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
83  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
84  EXPECT_EQ(read_out, kDataStr1);
85  EXPECT_EQ(read_dword, dword1);
86
87  work_item1->Rollback();
88  work_item2->Rollback();
89
90  // Rollback should delete the value.
91  EXPECT_FALSE(key.HasValue(name_str.c_str()));
92  EXPECT_FALSE(key.HasValue(name_dword.c_str()));
93}
94
95// Write a new value with overwrite flag. The value should be set.
96TEST_F(SetRegValueWorkItemTest, WriteNewOverwrite) {
97  RegKey key;
98
99  std::wstring parent_key(kTestRoot);
100  parent_key.append(&base::FilePath::kSeparators[0], 1);
101  parent_key.append(L"WriteNewOverwrite");
102  ASSERT_EQ(ERROR_SUCCESS,
103      key.Create(HKEY_CURRENT_USER, parent_key.c_str(), KEY_READ));
104
105  std::wstring name_str(kNameStr);
106  std::wstring data_str(kDataStr1);
107  scoped_ptr<SetRegValueWorkItem> work_item1(
108      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
109                                          parent_key,
110                                          WorkItem::kWow64Default,
111                                          name_str,
112                                          data_str,
113                                          true));
114
115  std::wstring name_dword(kNameDword);
116  scoped_ptr<SetRegValueWorkItem> work_item2(
117      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
118                                          parent_key,
119                                          WorkItem::kWow64Default,
120                                          name_dword,
121                                          dword1,
122                                          true));
123
124  EXPECT_TRUE(work_item1->Do());
125  EXPECT_TRUE(work_item2->Do());
126
127  std::wstring read_out;
128  DWORD read_dword;
129  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
130  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
131  EXPECT_EQ(read_out, kDataStr1);
132  EXPECT_EQ(read_dword, dword1);
133
134  work_item1->Rollback();
135  work_item2->Rollback();
136
137  // Rollback should delete the value.
138  EXPECT_FALSE(key.HasValue(name_str.c_str()));
139  EXPECT_FALSE(key.HasValue(name_dword.c_str()));
140}
141
142// Write to an existing value without overwrite flag. There should be
143// no change.
144TEST_F(SetRegValueWorkItemTest, WriteExistingNonOverwrite) {
145  RegKey key;
146
147  std::wstring parent_key(kTestRoot);
148  parent_key.append(&base::FilePath::kSeparators[0], 1);
149  parent_key.append(L"WriteExistingNonOverwrite");
150  ASSERT_EQ(ERROR_SUCCESS,
151      key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
152                 KEY_READ | KEY_SET_VALUE));
153
154  // First test REG_SZ value.
155  // Write data to the value we are going to set.
156  std::wstring name(kNameStr);
157  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
158
159  std::wstring data(kDataStr2);
160  scoped_ptr<SetRegValueWorkItem> work_item(
161      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
162                                          parent_key,
163                                          WorkItem::kWow64Default,
164                                          name,
165                                          data,
166                                          false));
167  EXPECT_TRUE(work_item->Do());
168
169  std::wstring read_out;
170  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
171  EXPECT_EQ(0, read_out.compare(kDataStr1));
172
173  work_item->Rollback();
174  EXPECT_TRUE(key.HasValue(name.c_str()));
175  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
176  EXPECT_EQ(read_out, kDataStr1);
177
178  // Now test REG_DWORD value.
179  // Write data to the value we are going to set.
180  name.assign(kNameDword);
181  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
182  work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
183                                                      parent_key,
184                                                      WorkItem::kWow64Default,
185                                                      name,
186                                                      dword2,
187                                                      false));
188  EXPECT_TRUE(work_item->Do());
189
190  DWORD read_dword;
191  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
192  EXPECT_EQ(read_dword, dword1);
193
194  work_item->Rollback();
195  EXPECT_TRUE(key.HasValue(name.c_str()));
196  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
197  EXPECT_EQ(read_dword, dword1);
198}
199
200// Write to an existing value with overwrite flag. The value should be
201// overwritten.
202TEST_F(SetRegValueWorkItemTest, WriteExistingOverwrite) {
203  RegKey key;
204
205  std::wstring parent_key(kTestRoot);
206  parent_key.append(&base::FilePath::kSeparators[0], 1);
207  parent_key.append(L"WriteExistingOverwrite");
208  ASSERT_EQ(ERROR_SUCCESS,
209      key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
210                 KEY_READ | KEY_SET_VALUE));
211
212  // First test REG_SZ value.
213  // Write data to the value we are going to set.
214  std::wstring name(kNameStr);
215  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
216
217  std::wstring name_empty(L"name_empty");
218  ASSERT_EQ(ERROR_SUCCESS, RegSetValueEx(key.Handle(), name_empty.c_str(), NULL,
219                                         REG_SZ, NULL, 0));
220
221  std::wstring data(kDataStr2);
222  scoped_ptr<SetRegValueWorkItem> work_item1(
223      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
224                                          parent_key,
225                                          WorkItem::kWow64Default,
226                                          name,
227                                          data,
228                                          true));
229  scoped_ptr<SetRegValueWorkItem> work_item2(
230      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
231                                          parent_key,
232                                          WorkItem::kWow64Default,
233                                          name_empty,
234                                          data,
235                                          true));
236
237  EXPECT_TRUE(work_item1->Do());
238  EXPECT_TRUE(work_item2->Do());
239
240  std::wstring read_out;
241  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
242  EXPECT_EQ(0, read_out.compare(kDataStr2));
243
244  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), &read_out));
245  EXPECT_EQ(0, read_out.compare(kDataStr2));
246
247  work_item1->Rollback();
248  work_item2->Rollback();
249
250  EXPECT_TRUE(key.HasValue(name.c_str()));
251  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
252  EXPECT_EQ(read_out, kDataStr1);
253
254  DWORD type = 0;
255  DWORD size = 0;
256  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), NULL, &size,
257                                         &type));
258  EXPECT_EQ(REG_SZ, type);
259  EXPECT_EQ(0, size);
260
261  // Now test REG_DWORD value.
262  // Write data to the value we are going to set.
263  name.assign(kNameDword);
264  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
265  scoped_ptr<SetRegValueWorkItem> work_item3(
266      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
267                                          parent_key,
268                                          WorkItem::kWow64Default,
269                                          name,
270                                          dword2,
271                                          true));
272  EXPECT_TRUE(work_item3->Do());
273
274  DWORD read_dword;
275  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
276  EXPECT_EQ(read_dword, dword2);
277
278  work_item3->Rollback();
279  EXPECT_TRUE(key.HasValue(name.c_str()));
280  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
281  EXPECT_EQ(read_dword, dword1);
282}
283
284// Write a value to a non-existing key. This should fail.
285TEST_F(SetRegValueWorkItemTest, WriteNonExistingKey) {
286  RegKey key;
287
288  std::wstring parent_key(kTestRoot);
289  parent_key.append(&base::FilePath::kSeparators[0], 1);
290  parent_key.append(L"WriteNonExistingKey");
291
292  std::wstring name(L"name");
293  std::wstring data(kDataStr1);
294  scoped_ptr<SetRegValueWorkItem> work_item(
295      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
296                                          parent_key,
297                                          WorkItem::kWow64Default,
298                                          name,
299                                          data,
300                                          false));
301  EXPECT_FALSE(work_item->Do());
302
303  work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
304                                                      parent_key,
305                                                      WorkItem::kWow64Default,
306                                                      name,
307                                                      dword1,
308                                                      false));
309  EXPECT_FALSE(work_item->Do());
310}
311