create_reg_key_work_item_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2011 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/file_util.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/create_reg_key_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
19wchar_t test_root[] = L"TmpTmp";
20
21class CreateRegKeyWorkItemTest : public testing::Test {
22 protected:
23  virtual void SetUp() {
24    // Create a temporary key for testing
25    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
26    key.DeleteKey(test_root);
27    ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, test_root, KEY_READ));
28    ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, test_root,
29                                        KEY_READ));
30  }
31  virtual void TearDown() {
32    logging::CloseLogFile();
33    // Clean up the temporary key
34    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
35    ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(test_root));
36  }
37};
38
39}  // namespace
40
41TEST_F(CreateRegKeyWorkItemTest, CreateKey) {
42  RegKey key;
43
44  base::FilePath parent_key(test_root);
45  parent_key = parent_key.AppendASCII("a");
46  ASSERT_EQ(ERROR_SUCCESS,
47      key.Create(HKEY_CURRENT_USER, parent_key.value().c_str(), KEY_READ));
48
49  base::FilePath top_key_to_create(parent_key);
50  top_key_to_create = top_key_to_create.AppendASCII("b");
51
52  base::FilePath key_to_create(top_key_to_create);
53  key_to_create = key_to_create.AppendASCII("c");
54  key_to_create = key_to_create.AppendASCII("d");
55
56  scoped_ptr<CreateRegKeyWorkItem> work_item(
57      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
58                                           key_to_create.value()));
59
60  EXPECT_TRUE(work_item->Do());
61
62  EXPECT_EQ(ERROR_SUCCESS,
63      key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
64
65  work_item->Rollback();
66
67  // Rollback should delete all the keys up to top_key_to_create.
68  EXPECT_NE(ERROR_SUCCESS,
69      key.Open(HKEY_CURRENT_USER, top_key_to_create.value().c_str(), KEY_READ));
70  EXPECT_EQ(ERROR_SUCCESS,
71      key.Open(HKEY_CURRENT_USER, parent_key.value().c_str(), KEY_READ));
72}
73
74TEST_F(CreateRegKeyWorkItemTest, CreateExistingKey) {
75  RegKey key;
76
77  base::FilePath key_to_create(test_root);
78  key_to_create = key_to_create.AppendASCII("aa");
79  ASSERT_EQ(ERROR_SUCCESS,
80      key.Create(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
81
82  scoped_ptr<CreateRegKeyWorkItem> work_item(
83      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
84                                           key_to_create.value()));
85
86  EXPECT_TRUE(work_item->Do());
87
88  EXPECT_EQ(ERROR_SUCCESS,
89      key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
90
91  work_item->Rollback();
92
93  // Rollback should not remove the key since it exists before
94  // the CreateRegKeyWorkItem is called.
95  EXPECT_EQ(ERROR_SUCCESS,
96      key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
97}
98
99TEST_F(CreateRegKeyWorkItemTest, CreateSharedKey) {
100  RegKey key;
101  base::FilePath key_to_create_1(test_root);
102  key_to_create_1 = key_to_create_1.AppendASCII("aaa");
103
104  base::FilePath key_to_create_2(key_to_create_1);
105  key_to_create_2 = key_to_create_2.AppendASCII("bbb");
106
107  base::FilePath key_to_create_3(key_to_create_2);
108  key_to_create_3 = key_to_create_3.AppendASCII("ccc");
109
110  scoped_ptr<CreateRegKeyWorkItem> work_item(
111      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
112                                           key_to_create_3.value()));
113
114  EXPECT_TRUE(work_item->Do());
115
116  EXPECT_EQ(ERROR_SUCCESS,
117      key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
118
119  // Create another key under key_to_create_2
120  base::FilePath key_to_create_4(key_to_create_2);
121  key_to_create_4 = key_to_create_4.AppendASCII("ddd");
122  ASSERT_EQ(ERROR_SUCCESS,
123      key.Create(HKEY_CURRENT_USER, key_to_create_4.value().c_str(), KEY_READ));
124
125  work_item->Rollback();
126
127  // Rollback should delete key_to_create_3.
128  EXPECT_NE(ERROR_SUCCESS,
129      key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
130
131  // Rollback should not delete key_to_create_2 as it is shared.
132  EXPECT_EQ(ERROR_SUCCESS,
133      key.Open(HKEY_CURRENT_USER, key_to_create_2.value().c_str(), KEY_READ));
134  EXPECT_EQ(ERROR_SUCCESS,
135      key.Open(HKEY_CURRENT_USER, key_to_create_4.value().c_str(), KEY_READ));
136}
137
138TEST_F(CreateRegKeyWorkItemTest, RollbackWithMissingKey) {
139  RegKey key;
140  base::FilePath key_to_create_1(test_root);
141  key_to_create_1 = key_to_create_1.AppendASCII("aaaa");
142
143  base::FilePath key_to_create_2(key_to_create_1);
144  key_to_create_2 = key_to_create_2.AppendASCII("bbbb");
145
146  base::FilePath key_to_create_3(key_to_create_2);
147  key_to_create_3 = key_to_create_3.AppendASCII("cccc");
148
149  scoped_ptr<CreateRegKeyWorkItem> work_item(
150      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
151                                           key_to_create_3.value()));
152
153  EXPECT_TRUE(work_item->Do());
154
155  EXPECT_EQ(ERROR_SUCCESS,
156      key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
157  key.Close();
158
159  // now delete key_to_create_3
160  ASSERT_EQ(ERROR_SUCCESS,
161      RegDeleteKey(HKEY_CURRENT_USER, key_to_create_3.value().c_str()));
162  ASSERT_NE(ERROR_SUCCESS,
163      key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
164
165  work_item->Rollback();
166
167  // key_to_create_3 has already been deleted, Rollback should delete
168  // the rest.
169  ASSERT_NE(ERROR_SUCCESS,
170      key.Open(HKEY_CURRENT_USER, key_to_create_1.value().c_str(), KEY_READ));
171}
172
173TEST_F(CreateRegKeyWorkItemTest, RollbackWithSetValue) {
174  RegKey key;
175
176  base::FilePath key_to_create(test_root);
177  key_to_create = key_to_create.AppendASCII("aaaaa");
178
179  scoped_ptr<CreateRegKeyWorkItem> work_item(
180      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
181                                           key_to_create.value()));
182
183  EXPECT_TRUE(work_item->Do());
184
185  // Write a value under the key we just created.
186  EXPECT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER,
187      key_to_create.value().c_str(), KEY_READ | KEY_SET_VALUE));
188  EXPECT_EQ(ERROR_SUCCESS, key.WriteValue(L"name", L"value"));
189  key.Close();
190
191  work_item->Rollback();
192
193  // Rollback should not remove the key.
194  EXPECT_EQ(ERROR_SUCCESS,
195      key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
196}
197