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/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_util.h"
12 #include "base/test/test_reg_util_win.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 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
31 registry_override_manager_
.OverrideRegistry(HKEY_CURRENT_USER
);
34 virtual void TearDown() {
35 logging::CloseLogFile();
38 base::ScopedTempDir temp_dir_
;
39 registry_util::RegistryOverrideManager registry_override_manager_
;
44 // Execute a WorkItem list successfully and then rollback.
45 TEST_F(WorkItemListTest
, ExecutionSuccess
) {
46 scoped_ptr
<WorkItemList
> work_item_list(WorkItem::CreateWorkItemList());
47 scoped_ptr
<WorkItem
> work_item
;
49 base::FilePath
top_dir_to_create(temp_dir_
.path());
50 top_dir_to_create
= top_dir_to_create
.AppendASCII("a");
51 base::FilePath
dir_to_create(top_dir_to_create
);
52 dir_to_create
= dir_to_create
.AppendASCII("b");
53 ASSERT_FALSE(base::PathExists(dir_to_create
));
55 work_item
.reset(reinterpret_cast<WorkItem
*>(
56 WorkItem::CreateCreateDirWorkItem(dir_to_create
)));
57 work_item_list
->AddWorkItem(work_item
.release());
59 std::wstring
key_to_create(kTestRoot
);
60 key_to_create
.push_back(base::FilePath::kSeparators
[0]);
61 key_to_create
.append(L
"ExecutionSuccess");
64 reinterpret_cast<WorkItem
*>(WorkItem::CreateCreateRegKeyWorkItem(
65 HKEY_CURRENT_USER
, key_to_create
, WorkItem::kWow64Default
)));
66 work_item_list
->AddWorkItem(work_item
.release());
68 std::wstring
name(kName
);
69 std::wstring
data(kDataStr
);
70 work_item
.reset(reinterpret_cast<WorkItem
*>(
71 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
73 WorkItem::kWow64Default
,
77 work_item_list
->AddWorkItem(work_item
.release());
79 EXPECT_TRUE(work_item_list
->Do());
81 // Verify all WorkItems have been executed.
83 EXPECT_EQ(ERROR_SUCCESS
,
84 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
85 std::wstring read_out
;
86 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(name
.c_str(), &read_out
));
87 EXPECT_EQ(0, read_out
.compare(kDataStr
));
89 EXPECT_TRUE(base::PathExists(dir_to_create
));
91 work_item_list
->Rollback();
93 // Verify everything is rolled back.
94 // The value must have been deleted first in roll back otherwise the key
95 // can not be deleted.
96 EXPECT_NE(ERROR_SUCCESS
,
97 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
98 EXPECT_FALSE(base::PathExists(top_dir_to_create
));
101 // Execute a WorkItem list. Fail in the middle. Rollback what has been done.
102 TEST_F(WorkItemListTest
, ExecutionFailAndRollback
) {
103 scoped_ptr
<WorkItemList
> work_item_list(WorkItem::CreateWorkItemList());
104 scoped_ptr
<WorkItem
> work_item
;
106 base::FilePath
top_dir_to_create(temp_dir_
.path());
107 top_dir_to_create
= top_dir_to_create
.AppendASCII("a");
108 base::FilePath
dir_to_create(top_dir_to_create
);
109 dir_to_create
= dir_to_create
.AppendASCII("b");
110 ASSERT_FALSE(base::PathExists(dir_to_create
));
112 work_item
.reset(reinterpret_cast<WorkItem
*>(
113 WorkItem::CreateCreateDirWorkItem(dir_to_create
)));
114 work_item_list
->AddWorkItem(work_item
.release());
116 std::wstring
key_to_create(kTestRoot
);
117 key_to_create
.push_back(base::FilePath::kSeparators
[0]);
118 key_to_create
.append(L
"ExecutionFail");
121 reinterpret_cast<WorkItem
*>(WorkItem::CreateCreateRegKeyWorkItem(
122 HKEY_CURRENT_USER
, key_to_create
, WorkItem::kWow64Default
)));
123 work_item_list
->AddWorkItem(work_item
.release());
125 std::wstring
not_created_key(kTestRoot
);
126 not_created_key
.push_back(base::FilePath::kSeparators
[0]);
127 not_created_key
.append(L
"NotCreated");
128 std::wstring
name(kName
);
129 std::wstring
data(kDataStr
);
130 work_item
.reset(reinterpret_cast<WorkItem
*>(
131 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
133 WorkItem::kWow64Default
,
137 work_item_list
->AddWorkItem(work_item
.release());
139 // This one will not be executed because we will fail early.
141 reinterpret_cast<WorkItem
*>(WorkItem::CreateCreateRegKeyWorkItem(
142 HKEY_CURRENT_USER
, not_created_key
, WorkItem::kWow64Default
)));
143 work_item_list
->AddWorkItem(work_item
.release());
145 EXPECT_FALSE(work_item_list
->Do());
147 // Verify the first 2 WorkItems have been executed.
149 EXPECT_EQ(ERROR_SUCCESS
,
150 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
152 EXPECT_TRUE(base::PathExists(dir_to_create
));
153 // The last one should not be there.
154 EXPECT_NE(ERROR_SUCCESS
,
155 key
.Open(HKEY_CURRENT_USER
, not_created_key
.c_str(), KEY_READ
));
157 work_item_list
->Rollback();
159 // Verify everything is rolled back.
160 EXPECT_NE(ERROR_SUCCESS
,
161 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
162 EXPECT_FALSE(base::PathExists(top_dir_to_create
));
165 TEST_F(WorkItemListTest
, ConditionalExecutionSuccess
) {
166 scoped_ptr
<WorkItemList
> work_item_list(WorkItem::CreateWorkItemList());
167 scoped_ptr
<WorkItem
> work_item
;
169 base::FilePath
top_dir_to_create(temp_dir_
.path());
170 top_dir_to_create
= top_dir_to_create
.AppendASCII("a");
171 base::FilePath
dir_to_create(top_dir_to_create
);
172 dir_to_create
= dir_to_create
.AppendASCII("b");
173 ASSERT_FALSE(base::PathExists(dir_to_create
));
175 work_item
.reset(reinterpret_cast<WorkItem
*>(
176 WorkItem::CreateCreateDirWorkItem(dir_to_create
)));
177 work_item_list
->AddWorkItem(work_item
.release());
179 scoped_ptr
<WorkItemList
> conditional_work_item_list(
180 WorkItem::CreateConditionalWorkItemList(
181 new ConditionRunIfFileExists(dir_to_create
)));
183 std::wstring
key_to_create(kTestRoot
);
184 key_to_create
.push_back(base::FilePath::kSeparators
[0]);
185 key_to_create
.append(L
"ExecutionSuccess");
187 reinterpret_cast<WorkItem
*>(WorkItem::CreateCreateRegKeyWorkItem(
188 HKEY_CURRENT_USER
, key_to_create
, WorkItem::kWow64Default
)));
189 conditional_work_item_list
->AddWorkItem(work_item
.release());
191 std::wstring
name(kName
);
192 std::wstring
data(kDataStr
);
193 work_item
.reset(reinterpret_cast<WorkItem
*>(
194 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
196 WorkItem::kWow64Default
,
200 conditional_work_item_list
->AddWorkItem(work_item
.release());
202 work_item_list
->AddWorkItem(conditional_work_item_list
.release());
204 EXPECT_TRUE(work_item_list
->Do());
206 // Verify all WorkItems have been executed.
208 EXPECT_EQ(ERROR_SUCCESS
,
209 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
210 std::wstring read_out
;
211 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(name
.c_str(), &read_out
));
212 EXPECT_EQ(0, read_out
.compare(kDataStr
));
214 EXPECT_TRUE(base::PathExists(dir_to_create
));
216 work_item_list
->Rollback();
218 // Verify everything is rolled back.
219 // The value must have been deleted first in roll back otherwise the key
220 // can not be deleted.
221 EXPECT_NE(ERROR_SUCCESS
,
222 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
223 EXPECT_FALSE(base::PathExists(top_dir_to_create
));
226 TEST_F(WorkItemListTest
, ConditionalExecutionConditionFailure
) {
227 scoped_ptr
<WorkItemList
> work_item_list(WorkItem::CreateWorkItemList());
228 scoped_ptr
<WorkItem
> work_item
;
230 base::FilePath
top_dir_to_create(temp_dir_
.path());
231 top_dir_to_create
= top_dir_to_create
.AppendASCII("a");
232 base::FilePath
dir_to_create(top_dir_to_create
);
233 dir_to_create
= dir_to_create
.AppendASCII("b");
234 ASSERT_FALSE(base::PathExists(dir_to_create
));
236 work_item
.reset(reinterpret_cast<WorkItem
*>(
237 WorkItem::CreateCreateDirWorkItem(dir_to_create
)));
238 work_item_list
->AddWorkItem(work_item
.release());
240 scoped_ptr
<WorkItemList
> conditional_work_item_list(
241 WorkItem::CreateConditionalWorkItemList(
242 new ConditionRunIfFileExists(dir_to_create
.AppendASCII("c"))));
244 std::wstring
key_to_create(kTestRoot
);
245 key_to_create
.push_back(base::FilePath::kSeparators
[0]);
246 key_to_create
.append(L
"ExecutionSuccess");
248 reinterpret_cast<WorkItem
*>(WorkItem::CreateCreateRegKeyWorkItem(
249 HKEY_CURRENT_USER
, key_to_create
, WorkItem::kWow64Default
)));
250 conditional_work_item_list
->AddWorkItem(work_item
.release());
252 std::wstring
name(kName
);
253 std::wstring
data(kDataStr
);
254 work_item
.reset(reinterpret_cast<WorkItem
*>(
255 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER
,
257 WorkItem::kWow64Default
,
261 conditional_work_item_list
->AddWorkItem(work_item
.release());
263 work_item_list
->AddWorkItem(conditional_work_item_list
.release());
265 EXPECT_TRUE(work_item_list
->Do());
267 // Verify that the WorkItems added as part of the conditional list have NOT
270 EXPECT_NE(ERROR_SUCCESS
,
271 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
272 std::wstring read_out
;
273 EXPECT_NE(ERROR_SUCCESS
, key
.ReadValue(name
.c_str(), &read_out
));
276 // Verify that the other work item was executed.
277 EXPECT_TRUE(base::PathExists(dir_to_create
));
279 work_item_list
->Rollback();
281 // Verify everything is rolled back.
282 // The value must have been deleted first in roll back otherwise the key
283 // can not be deleted.
284 EXPECT_NE(ERROR_SUCCESS
,
285 key
.Open(HKEY_CURRENT_USER
, key_to_create
.c_str(), KEY_READ
));
286 EXPECT_FALSE(base::PathExists(top_dir_to_create
));