Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / chrome / installer / util / work_item_list_unittest.cc
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/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"
18
19 using base::win::RegKey;
20
21 namespace {
22
23 const wchar_t kTestRoot[] = L"ListList";
24 const wchar_t kDataStr[] = L"data_111";
25 const wchar_t kName[] = L"name";
26
27 class WorkItemListTest : public testing::Test {
28  protected:
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));
36
37     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
38   }
39
40   virtual void TearDown() {
41     logging::CloseLogFile();
42
43     // Clean up the temporary key
44     RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
45     ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kTestRoot));
46   }
47
48   base::ScopedTempDir temp_dir_;
49 };
50
51 }  // namespace
52
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;
57
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));
63
64   work_item.reset(reinterpret_cast<WorkItem*>(
65       WorkItem::CreateCreateDirWorkItem(dir_to_create)));
66   work_item_list->AddWorkItem(work_item.release());
67
68   std::wstring key_to_create(kTestRoot);
69   key_to_create.push_back(base::FilePath::kSeparators[0]);
70   key_to_create.append(L"ExecutionSuccess");
71
72   work_item.reset(
73       reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
74           HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
75   work_item_list->AddWorkItem(work_item.release());
76
77   std::wstring name(kName);
78   std::wstring data(kDataStr);
79   work_item.reset(reinterpret_cast<WorkItem*>(
80       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
81                                           key_to_create,
82                                           WorkItem::kWow64Default,
83                                           name,
84                                           data,
85                                           false)));
86   work_item_list->AddWorkItem(work_item.release());
87
88   EXPECT_TRUE(work_item_list->Do());
89
90   // Verify all WorkItems have been executed.
91   RegKey key;
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));
97   key.Close();
98   EXPECT_TRUE(base::PathExists(dir_to_create));
99
100   work_item_list->Rollback();
101
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));
108 }
109
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;
114
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));
120
121   work_item.reset(reinterpret_cast<WorkItem*>(
122       WorkItem::CreateCreateDirWorkItem(dir_to_create)));
123   work_item_list->AddWorkItem(work_item.release());
124
125   std::wstring key_to_create(kTestRoot);
126   key_to_create.push_back(base::FilePath::kSeparators[0]);
127   key_to_create.append(L"ExecutionFail");
128
129   work_item.reset(
130       reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
131           HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
132   work_item_list->AddWorkItem(work_item.release());
133
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,
141                                           not_created_key,
142                                           WorkItem::kWow64Default,
143                                           name,
144                                           data,
145                                           false)));
146   work_item_list->AddWorkItem(work_item.release());
147
148   // This one will not be executed because we will fail early.
149   work_item.reset(
150       reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
151           HKEY_CURRENT_USER, not_created_key, WorkItem::kWow64Default)));
152   work_item_list->AddWorkItem(work_item.release());
153
154   EXPECT_FALSE(work_item_list->Do());
155
156   // Verify the first 2 WorkItems have been executed.
157   RegKey key;
158   EXPECT_EQ(ERROR_SUCCESS,
159       key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
160   key.Close();
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));
165
166   work_item_list->Rollback();
167
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));
172 }
173
174 TEST_F(WorkItemListTest, ConditionalExecutionSuccess) {
175   scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
176   scoped_ptr<WorkItem> work_item;
177
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));
183
184   work_item.reset(reinterpret_cast<WorkItem*>(
185       WorkItem::CreateCreateDirWorkItem(dir_to_create)));
186   work_item_list->AddWorkItem(work_item.release());
187
188   scoped_ptr<WorkItemList> conditional_work_item_list(
189       WorkItem::CreateConditionalWorkItemList(
190           new ConditionRunIfFileExists(dir_to_create)));
191
192   std::wstring key_to_create(kTestRoot);
193   key_to_create.push_back(base::FilePath::kSeparators[0]);
194   key_to_create.append(L"ExecutionSuccess");
195   work_item.reset(
196       reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
197           HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
198   conditional_work_item_list->AddWorkItem(work_item.release());
199
200   std::wstring name(kName);
201   std::wstring data(kDataStr);
202   work_item.reset(reinterpret_cast<WorkItem*>(
203       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
204                                           key_to_create,
205                                           WorkItem::kWow64Default,
206                                           name,
207                                           data,
208                                           false)));
209   conditional_work_item_list->AddWorkItem(work_item.release());
210
211   work_item_list->AddWorkItem(conditional_work_item_list.release());
212
213   EXPECT_TRUE(work_item_list->Do());
214
215   // Verify all WorkItems have been executed.
216   RegKey key;
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));
222   key.Close();
223   EXPECT_TRUE(base::PathExists(dir_to_create));
224
225   work_item_list->Rollback();
226
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));
233 }
234
235 TEST_F(WorkItemListTest, ConditionalExecutionConditionFailure) {
236   scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
237   scoped_ptr<WorkItem> work_item;
238
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));
244
245   work_item.reset(reinterpret_cast<WorkItem*>(
246       WorkItem::CreateCreateDirWorkItem(dir_to_create)));
247   work_item_list->AddWorkItem(work_item.release());
248
249   scoped_ptr<WorkItemList> conditional_work_item_list(
250       WorkItem::CreateConditionalWorkItemList(
251           new ConditionRunIfFileExists(dir_to_create.AppendASCII("c"))));
252
253   std::wstring key_to_create(kTestRoot);
254   key_to_create.push_back(base::FilePath::kSeparators[0]);
255   key_to_create.append(L"ExecutionSuccess");
256   work_item.reset(
257       reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem(
258           HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default)));
259   conditional_work_item_list->AddWorkItem(work_item.release());
260
261   std::wstring name(kName);
262   std::wstring data(kDataStr);
263   work_item.reset(reinterpret_cast<WorkItem*>(
264       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
265                                           key_to_create,
266                                           WorkItem::kWow64Default,
267                                           name,
268                                           data,
269                                           false)));
270   conditional_work_item_list->AddWorkItem(work_item.release());
271
272   work_item_list->AddWorkItem(conditional_work_item_list.release());
273
274   EXPECT_TRUE(work_item_list->Do());
275
276   // Verify that the WorkItems added as part of the conditional list have NOT
277   // been executed.
278   RegKey key;
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));
283   key.Close();
284
285   // Verify that the other work item was executed.
286   EXPECT_TRUE(base::PathExists(dir_to_create));
287
288   work_item_list->Rollback();
289
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));
296 }