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.
7 #include "base/base_paths.h"
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/path_service.h"
12 #include "base/strings/string_util.h"
13 #include "base/win/registry.h"
14 #include "chrome/installer/util/conditional_work_item_list.h"
15 #include "chrome/installer/util/work_item.h"
16 #include "chrome/installer/util/work_item_list.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using base::win::RegKey;
23 const wchar_t kTestRoot[] = L"ListList";
24 const wchar_t kDataStr[] = L"data_111";
25 const wchar_t kName[] = L"name";
27 class WorkItemListTest : public testing::Test {
29 virtual void SetUp() {
30 // Create a temporary key for testing
31 RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
32 key.DeleteKey(kTestRoot);
33 ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
34 ASSERT_EQ(ERROR_SUCCESS,
35 key.Create(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
37 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
40 virtual void TearDown() {
41 logging::CloseLogFile();
43 // Clean up the temporary key
44 RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
45 ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kTestRoot));
48 base::ScopedTempDir temp_dir_;
53 // Execute a WorkItem list successfully and then rollback.
54 TEST_F(WorkItemListTest, ExecutionSuccess) {
55 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
56 scoped_ptr<WorkItem> work_item;
58 base::FilePath top_dir_to_create(temp_dir_.path());
59 top_dir_to_create = top_dir_to_create.AppendASCII("a");
60 base::FilePath dir_to_create(top_dir_to_create);
61 dir_to_create = dir_to_create.AppendASCII("b");
62 ASSERT_FALSE(base::PathExists(dir_to_create));
64 work_item.reset(reinterpret_cast<WorkItem*>(
65 WorkItem::CreateCreateDirWorkItem(dir_to_create)));
66 work_item_list->AddWorkItem(work_item.release());
68 std::wstring key_to_create(kTestRoot);
69 key_to_create.push_back(base::FilePath::kSeparators[0]);
70 key_to_create.append(L"ExecutionSuccess");
73 reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
74 HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
75 work_item_list->AddWorkItem(work_item.release());
77 std::wstring name(kName);
78 std::wstring data(kDataStr);
79 work_item.reset(reinterpret_cast<WorkItem*>(
80 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
82 WorkItem::kWow64Default,
86 work_item_list->AddWorkItem(work_item.release());
88 EXPECT_TRUE(work_item_list->Do());
90 // Verify all WorkItems have been executed.
92 EXPECT_EQ(ERROR_SUCCESS,
93 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
94 std::wstring read_out;
95 EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
96 EXPECT_EQ(0, read_out.compare(kDataStr));
98 EXPECT_TRUE(base::PathExists(dir_to_create));
100 work_item_list->Rollback();
102 // Verify everything is rolled back.
103 // The value must have been deleted first in roll back otherwise the key
104 // can not be deleted.
105 EXPECT_NE(ERROR_SUCCESS,
106 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
107 EXPECT_FALSE(base::PathExists(top_dir_to_create));
110 // Execute a WorkItem list. Fail in the middle. Rollback what has been done.
111 TEST_F(WorkItemListTest, ExecutionFailAndRollback) {
112 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
113 scoped_ptr<WorkItem> work_item;
115 base::FilePath top_dir_to_create(temp_dir_.path());
116 top_dir_to_create = top_dir_to_create.AppendASCII("a");
117 base::FilePath dir_to_create(top_dir_to_create);
118 dir_to_create = dir_to_create.AppendASCII("b");
119 ASSERT_FALSE(base::PathExists(dir_to_create));
121 work_item.reset(reinterpret_cast<WorkItem*>(
122 WorkItem::CreateCreateDirWorkItem(dir_to_create)));
123 work_item_list->AddWorkItem(work_item.release());
125 std::wstring key_to_create(kTestRoot);
126 key_to_create.push_back(base::FilePath::kSeparators[0]);
127 key_to_create.append(L"ExecutionFail");
130 reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
131 HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
132 work_item_list->AddWorkItem(work_item.release());
134 std::wstring not_created_key(kTestRoot);
135 not_created_key.push_back(base::FilePath::kSeparators[0]);
136 not_created_key.append(L"NotCreated");
137 std::wstring name(kName);
138 std::wstring data(kDataStr);
139 work_item.reset(reinterpret_cast<WorkItem*>(
140 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
142 WorkItem::kWow64Default,
146 work_item_list->AddWorkItem(work_item.release());
148 // This one will not be executed because we will fail early.
150 reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
151 HKEY_CURRENT_USER, not_created_key, WorkItem::kWow64Default)));
152 work_item_list->AddWorkItem(work_item.release());
154 EXPECT_FALSE(work_item_list->Do());
156 // Verify the first 2 WorkItems have been executed.
158 EXPECT_EQ(ERROR_SUCCESS,
159 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
161 EXPECT_TRUE(base::PathExists(dir_to_create));
162 // The last one should not be there.
163 EXPECT_NE(ERROR_SUCCESS,
164 key.Open(HKEY_CURRENT_USER, not_created_key.c_str(), KEY_READ));
166 work_item_list->Rollback();
168 // Verify everything is rolled back.
169 EXPECT_NE(ERROR_SUCCESS,
170 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
171 EXPECT_FALSE(base::PathExists(top_dir_to_create));
174 TEST_F(WorkItemListTest, ConditionalExecutionSuccess) {
175 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
176 scoped_ptr<WorkItem> work_item;
178 base::FilePath top_dir_to_create(temp_dir_.path());
179 top_dir_to_create = top_dir_to_create.AppendASCII("a");
180 base::FilePath dir_to_create(top_dir_to_create);
181 dir_to_create = dir_to_create.AppendASCII("b");
182 ASSERT_FALSE(base::PathExists(dir_to_create));
184 work_item.reset(reinterpret_cast<WorkItem*>(
185 WorkItem::CreateCreateDirWorkItem(dir_to_create)));
186 work_item_list->AddWorkItem(work_item.release());
188 scoped_ptr<WorkItemList> conditional_work_item_list(
189 WorkItem::CreateConditionalWorkItemList(
190 new ConditionRunIfFileExists(dir_to_create)));
192 std::wstring key_to_create(kTestRoot);
193 key_to_create.push_back(base::FilePath::kSeparators[0]);
194 key_to_create.append(L"ExecutionSuccess");
196 reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
197 HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
198 conditional_work_item_list->AddWorkItem(work_item.release());
200 std::wstring name(kName);
201 std::wstring data(kDataStr);
202 work_item.reset(reinterpret_cast<WorkItem*>(
203 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
205 WorkItem::kWow64Default,
209 conditional_work_item_list->AddWorkItem(work_item.release());
211 work_item_list->AddWorkItem(conditional_work_item_list.release());
213 EXPECT_TRUE(work_item_list->Do());
215 // Verify all WorkItems have been executed.
217 EXPECT_EQ(ERROR_SUCCESS,
218 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
219 std::wstring read_out;
220 EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
221 EXPECT_EQ(0, read_out.compare(kDataStr));
223 EXPECT_TRUE(base::PathExists(dir_to_create));
225 work_item_list->Rollback();
227 // Verify everything is rolled back.
228 // The value must have been deleted first in roll back otherwise the key
229 // can not be deleted.
230 EXPECT_NE(ERROR_SUCCESS,
231 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
232 EXPECT_FALSE(base::PathExists(top_dir_to_create));
235 TEST_F(WorkItemListTest, ConditionalExecutionConditionFailure) {
236 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
237 scoped_ptr<WorkItem> work_item;
239 base::FilePath top_dir_to_create(temp_dir_.path());
240 top_dir_to_create = top_dir_to_create.AppendASCII("a");
241 base::FilePath dir_to_create(top_dir_to_create);
242 dir_to_create = dir_to_create.AppendASCII("b");
243 ASSERT_FALSE(base::PathExists(dir_to_create));
245 work_item.reset(reinterpret_cast<WorkItem*>(
246 WorkItem::CreateCreateDirWorkItem(dir_to_create)));
247 work_item_list->AddWorkItem(work_item.release());
249 scoped_ptr<WorkItemList> conditional_work_item_list(
250 WorkItem::CreateConditionalWorkItemList(
251 new ConditionRunIfFileExists(dir_to_create.AppendASCII("c"))));
253 std::wstring key_to_create(kTestRoot);
254 key_to_create.push_back(base::FilePath::kSeparators[0]);
255 key_to_create.append(L"ExecutionSuccess");
257 reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
258 HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
259 conditional_work_item_list->AddWorkItem(work_item.release());
261 std::wstring name(kName);
262 std::wstring data(kDataStr);
263 work_item.reset(reinterpret_cast<WorkItem*>(
264 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
266 WorkItem::kWow64Default,
270 conditional_work_item_list->AddWorkItem(work_item.release());
272 work_item_list->AddWorkItem(conditional_work_item_list.release());
274 EXPECT_TRUE(work_item_list->Do());
276 // Verify that the WorkItems added as part of the conditional list have NOT
279 EXPECT_NE(ERROR_SUCCESS,
280 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
281 std::wstring read_out;
282 EXPECT_NE(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
285 // Verify that the other work item was executed.
286 EXPECT_TRUE(base::PathExists(dir_to_create));
288 work_item_list->Rollback();
290 // Verify everything is rolled back.
291 // The value must have been deleted first in roll back otherwise the key
292 // can not be deleted.
293 EXPECT_NE(ERROR_SUCCESS,
294 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
295 EXPECT_FALSE(base::PathExists(top_dir_to_create));