1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include "base/base_paths.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/registry.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "chrome/installer/util/work_item.h"
#include "chrome/installer/util/work_item_list.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
wchar_t test_root[] = L"ListList";
wchar_t data_str[] = L"data_111";
class WorkItemListTest : public testing::Test {
protected:
virtual void SetUp() {
// Create a temporary key for testing
RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
key.DeleteKey(test_root);
ASSERT_FALSE(key.Open(HKEY_CURRENT_USER, test_root, KEY_READ));
ASSERT_TRUE(key.Create(HKEY_CURRENT_USER, test_root, KEY_READ));
// Create a temp directory for test.
ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_dir_));
test_dir_ = test_dir_.AppendASCII("WorkItemListTest");
file_util::Delete(test_dir_, true);
ASSERT_FALSE(file_util::PathExists(test_dir_));
file_util::CreateDirectoryW(test_dir_);
ASSERT_TRUE(file_util::PathExists(test_dir_));
}
virtual void TearDown() {
logging::CloseLogFile();
// Clean up test directory
ASSERT_TRUE(file_util::Delete(test_dir_, true));
ASSERT_FALSE(file_util::PathExists(test_dir_));
// Clean up the temporary key
RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
ASSERT_TRUE(key.DeleteKey(test_root));
}
FilePath test_dir_;
};
};
// Execute a WorkItem list successfully and then rollback.
TEST_F(WorkItemListTest, ExecutionSuccess) {
scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
scoped_ptr<WorkItem> work_item;
FilePath top_dir_to_create(test_dir_);
top_dir_to_create = top_dir_to_create.AppendASCII("a");
FilePath dir_to_create(top_dir_to_create);
dir_to_create = dir_to_create.AppendASCII("b");
ASSERT_FALSE(file_util::PathExists(dir_to_create));
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateCreateDirWorkItem(dir_to_create)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
std::wstring key_to_create(test_root);
file_util::AppendToPath(&key_to_create, L"ExecutionSuccess");
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
std::wstring name(L"name");
std::wstring data(data_str);
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create,
name, data, false)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
EXPECT_TRUE(work_item_list->Do());
// Verify all WorkItems have been executed.
RegKey key;
EXPECT_TRUE(key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
std::wstring read_out;
EXPECT_TRUE(key.ReadValue(name.c_str(), &read_out));
EXPECT_EQ(0, read_out.compare(data_str));
key.Close();
EXPECT_TRUE(file_util::PathExists(dir_to_create));
work_item_list->Rollback();
// Verify everything is rolled back.
// The value must have been deleted first in roll back otherwise the key
// can not be deleted.
EXPECT_FALSE(key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
EXPECT_FALSE(file_util::PathExists(top_dir_to_create));
}
// Execute a WorkItem list. Fail in the middle. Rollback what has been done.
TEST_F(WorkItemListTest, ExecutionFailAndRollback) {
scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
scoped_ptr<WorkItem> work_item;
FilePath top_dir_to_create(test_dir_);
top_dir_to_create = top_dir_to_create.AppendASCII("a");
FilePath dir_to_create(top_dir_to_create);
dir_to_create = dir_to_create.AppendASCII("b");
ASSERT_FALSE(file_util::PathExists(dir_to_create));
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateCreateDirWorkItem(dir_to_create)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
std::wstring key_to_create(test_root);
file_util::AppendToPath(&key_to_create, L"ExecutionFail");
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
std::wstring not_created_key(test_root);
file_util::AppendToPath(¬_created_key, L"NotCreated");
std::wstring name(L"name");
std::wstring data(data_str);
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, not_created_key,
name, data, false)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
// This one will not be executed because we will fail early.
work_item.reset(reinterpret_cast<WorkItem*>(
WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
not_created_key)));
EXPECT_TRUE(work_item_list->AddWorkItem(work_item.release()));
EXPECT_FALSE(work_item_list->Do());
// Verify the first 2 WorkItems have been executed.
RegKey key;
EXPECT_TRUE(key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
key.Close();
EXPECT_TRUE(file_util::PathExists(dir_to_create));
// The last one should not be there.
EXPECT_FALSE(key.Open(HKEY_CURRENT_USER, not_created_key.c_str(),
KEY_READ));
work_item_list->Rollback();
// Verify everything is rolled back.
EXPECT_FALSE(key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
EXPECT_FALSE(file_util::PathExists(top_dir_to_create));
}
|