set_reg_value_work_item_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/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, parent_key,
62                                          name_str, data_str, false));
63
64  std::wstring name_dword(kNameDword);
65  scoped_ptr<SetRegValueWorkItem> work_item2(
66      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
67                                          name_dword, dword1, false));
68
69  EXPECT_TRUE(work_item1->Do());
70  EXPECT_TRUE(work_item2->Do());
71
72  std::wstring read_out;
73  DWORD read_dword;
74  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
75  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
76  EXPECT_EQ(read_out, kDataStr1);
77  EXPECT_EQ(read_dword, dword1);
78
79  work_item1->Rollback();
80  work_item2->Rollback();
81
82  // Rollback should delete the value.
83  EXPECT_FALSE(key.HasValue(name_str.c_str()));
84  EXPECT_FALSE(key.HasValue(name_dword.c_str()));
85}
86
87// Write a new value with overwrite flag. The value should be set.
88TEST_F(SetRegValueWorkItemTest, WriteNewOverwrite) {
89  RegKey key;
90
91  std::wstring parent_key(kTestRoot);
92  parent_key.append(&base::FilePath::kSeparators[0], 1);
93  parent_key.append(L"WriteNewOverwrite");
94  ASSERT_EQ(ERROR_SUCCESS,
95      key.Create(HKEY_CURRENT_USER, parent_key.c_str(), KEY_READ));
96
97  std::wstring name_str(kNameStr);
98  std::wstring data_str(kDataStr1);
99  scoped_ptr<SetRegValueWorkItem> work_item1(
100      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
101                                          name_str, data_str, true));
102
103  std::wstring name_dword(kNameDword);
104  scoped_ptr<SetRegValueWorkItem> work_item2(
105      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
106                                          name_dword, dword1, true));
107
108  EXPECT_TRUE(work_item1->Do());
109  EXPECT_TRUE(work_item2->Do());
110
111  std::wstring read_out;
112  DWORD read_dword;
113  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
114  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
115  EXPECT_EQ(read_out, kDataStr1);
116  EXPECT_EQ(read_dword, dword1);
117
118  work_item1->Rollback();
119  work_item2->Rollback();
120
121  // Rollback should delete the value.
122  EXPECT_FALSE(key.HasValue(name_str.c_str()));
123  EXPECT_FALSE(key.HasValue(name_dword.c_str()));
124}
125
126// Write to an existing value without overwrite flag. There should be
127// no change.
128TEST_F(SetRegValueWorkItemTest, WriteExistingNonOverwrite) {
129  RegKey key;
130
131  std::wstring parent_key(kTestRoot);
132  parent_key.append(&base::FilePath::kSeparators[0], 1);
133  parent_key.append(L"WriteExistingNonOverwrite");
134  ASSERT_EQ(ERROR_SUCCESS,
135      key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
136                 KEY_READ | KEY_SET_VALUE));
137
138  // First test REG_SZ value.
139  // Write data to the value we are going to set.
140  std::wstring name(kNameStr);
141  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
142
143  std::wstring data(kDataStr2);
144  scoped_ptr<SetRegValueWorkItem> work_item(
145      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
146                                          name, data, false));
147  EXPECT_TRUE(work_item->Do());
148
149  std::wstring read_out;
150  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
151  EXPECT_EQ(0, read_out.compare(kDataStr1));
152
153  work_item->Rollback();
154  EXPECT_TRUE(key.HasValue(name.c_str()));
155  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
156  EXPECT_EQ(read_out, kDataStr1);
157
158  // Now test REG_DWORD value.
159  // Write data to the value we are going to set.
160  name.assign(kNameDword);
161  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
162  work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
163      parent_key, name, dword2, false));
164  EXPECT_TRUE(work_item->Do());
165
166  DWORD read_dword;
167  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
168  EXPECT_EQ(read_dword, dword1);
169
170  work_item->Rollback();
171  EXPECT_TRUE(key.HasValue(name.c_str()));
172  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
173  EXPECT_EQ(read_dword, dword1);
174}
175
176// Write to an existing value with overwrite flag. The value should be
177// overwritten.
178TEST_F(SetRegValueWorkItemTest, WriteExistingOverwrite) {
179  RegKey key;
180
181  std::wstring parent_key(kTestRoot);
182  parent_key.append(&base::FilePath::kSeparators[0], 1);
183  parent_key.append(L"WriteExistingOverwrite");
184  ASSERT_EQ(ERROR_SUCCESS,
185      key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
186                 KEY_READ | KEY_SET_VALUE));
187
188  // First test REG_SZ value.
189  // Write data to the value we are going to set.
190  std::wstring name(kNameStr);
191  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
192
193  std::wstring name_empty(L"name_empty");
194  ASSERT_EQ(ERROR_SUCCESS, RegSetValueEx(key.Handle(), name_empty.c_str(), NULL,
195                                         REG_SZ, NULL, 0));
196
197  std::wstring data(kDataStr2);
198  scoped_ptr<SetRegValueWorkItem> work_item1(
199      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
200                                          name, data, true));
201  scoped_ptr<SetRegValueWorkItem> work_item2(
202      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
203                                          name_empty, data, true));
204
205  EXPECT_TRUE(work_item1->Do());
206  EXPECT_TRUE(work_item2->Do());
207
208  std::wstring read_out;
209  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
210  EXPECT_EQ(0, read_out.compare(kDataStr2));
211
212  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), &read_out));
213  EXPECT_EQ(0, read_out.compare(kDataStr2));
214
215  work_item1->Rollback();
216  work_item2->Rollback();
217
218  EXPECT_TRUE(key.HasValue(name.c_str()));
219  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
220  EXPECT_EQ(read_out, kDataStr1);
221
222  DWORD type = 0;
223  DWORD size = 0;
224  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), NULL, &size,
225                                         &type));
226  EXPECT_EQ(REG_SZ, type);
227  EXPECT_EQ(0, size);
228
229  // Now test REG_DWORD value.
230  // Write data to the value we are going to set.
231  name.assign(kNameDword);
232  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
233  scoped_ptr<SetRegValueWorkItem> work_item3(
234      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, name,
235                                          dword2, true));
236  EXPECT_TRUE(work_item3->Do());
237
238  DWORD read_dword;
239  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
240  EXPECT_EQ(read_dword, dword2);
241
242  work_item3->Rollback();
243  EXPECT_TRUE(key.HasValue(name.c_str()));
244  EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
245  EXPECT_EQ(read_dword, dword1);
246}
247
248// Write a value to a non-existing key. This should fail.
249TEST_F(SetRegValueWorkItemTest, WriteNonExistingKey) {
250  RegKey key;
251
252  std::wstring parent_key(kTestRoot);
253  parent_key.append(&base::FilePath::kSeparators[0], 1);
254  parent_key.append(L"WriteNonExistingKey");
255
256  std::wstring name(L"name");
257  std::wstring data(kDataStr1);
258  scoped_ptr<SetRegValueWorkItem> work_item(
259      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
260                                          name, data, false));
261  EXPECT_FALSE(work_item->Do());
262
263  work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
264      parent_key, name, dword1, false));
265  EXPECT_FALSE(work_item->Do());
266}
267