work_item_list_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/memory/scoped_ptr.h" 10#include "base/path_service.h" 11#include "base/scoped_temp_dir.h" 12#include "base/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 19using base::win::RegKey; 20 21namespace { 22 23const wchar_t kTestRoot[] = L"ListList"; 24const wchar_t kDataStr[] = L"data_111"; 25const wchar_t kName[] = L"name"; 26 27class 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 ScopedTempDir temp_dir_; 49}; 50 51} // namespace 52 53// Execute a WorkItem list successfully and then rollback. 54TEST_F(WorkItemListTest, ExecutionSuccess) { 55 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); 56 scoped_ptr<WorkItem> work_item; 57 58 FilePath top_dir_to_create(temp_dir_.path()); 59 top_dir_to_create = top_dir_to_create.AppendASCII("a"); 60 FilePath dir_to_create(top_dir_to_create); 61 dir_to_create = dir_to_create.AppendASCII("b"); 62 ASSERT_FALSE(file_util::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(FilePath::kSeparators[0]); 70 key_to_create.append(L"ExecutionSuccess"); 71 72 work_item.reset(reinterpret_cast<WorkItem*>( 73 WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); 74 work_item_list->AddWorkItem(work_item.release()); 75 76 std::wstring name(kName); 77 std::wstring data(kDataStr); 78 work_item.reset(reinterpret_cast<WorkItem*>( 79 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create, 80 name, data, false))); 81 work_item_list->AddWorkItem(work_item.release()); 82 83 EXPECT_TRUE(work_item_list->Do()); 84 85 // Verify all WorkItems have been executed. 86 RegKey key; 87 EXPECT_EQ(ERROR_SUCCESS, 88 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 89 std::wstring read_out; 90 EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out)); 91 EXPECT_EQ(0, read_out.compare(kDataStr)); 92 key.Close(); 93 EXPECT_TRUE(file_util::PathExists(dir_to_create)); 94 95 work_item_list->Rollback(); 96 97 // Verify everything is rolled back. 98 // The value must have been deleted first in roll back otherwise the key 99 // can not be deleted. 100 EXPECT_NE(ERROR_SUCCESS, 101 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 102 EXPECT_FALSE(file_util::PathExists(top_dir_to_create)); 103} 104 105// Execute a WorkItem list. Fail in the middle. Rollback what has been done. 106TEST_F(WorkItemListTest, ExecutionFailAndRollback) { 107 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); 108 scoped_ptr<WorkItem> work_item; 109 110 FilePath top_dir_to_create(temp_dir_.path()); 111 top_dir_to_create = top_dir_to_create.AppendASCII("a"); 112 FilePath dir_to_create(top_dir_to_create); 113 dir_to_create = dir_to_create.AppendASCII("b"); 114 ASSERT_FALSE(file_util::PathExists(dir_to_create)); 115 116 work_item.reset(reinterpret_cast<WorkItem*>( 117 WorkItem::CreateCreateDirWorkItem(dir_to_create))); 118 work_item_list->AddWorkItem(work_item.release()); 119 120 std::wstring key_to_create(kTestRoot); 121 key_to_create.push_back(FilePath::kSeparators[0]); 122 key_to_create.append(L"ExecutionFail"); 123 124 work_item.reset(reinterpret_cast<WorkItem*>( 125 WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); 126 work_item_list->AddWorkItem(work_item.release()); 127 128 std::wstring not_created_key(kTestRoot); 129 not_created_key.push_back(FilePath::kSeparators[0]); 130 not_created_key.append(L"NotCreated"); 131 std::wstring name(kName); 132 std::wstring data(kDataStr); 133 work_item.reset(reinterpret_cast<WorkItem*>( 134 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, not_created_key, 135 name, data, false))); 136 work_item_list->AddWorkItem(work_item.release()); 137 138 // This one will not be executed because we will fail early. 139 work_item.reset(reinterpret_cast<WorkItem*>( 140 WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, 141 not_created_key))); 142 work_item_list->AddWorkItem(work_item.release()); 143 144 EXPECT_FALSE(work_item_list->Do()); 145 146 // Verify the first 2 WorkItems have been executed. 147 RegKey key; 148 EXPECT_EQ(ERROR_SUCCESS, 149 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 150 key.Close(); 151 EXPECT_TRUE(file_util::PathExists(dir_to_create)); 152 // The last one should not be there. 153 EXPECT_NE(ERROR_SUCCESS, 154 key.Open(HKEY_CURRENT_USER, not_created_key.c_str(), KEY_READ)); 155 156 work_item_list->Rollback(); 157 158 // Verify everything is rolled back. 159 EXPECT_NE(ERROR_SUCCESS, 160 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 161 EXPECT_FALSE(file_util::PathExists(top_dir_to_create)); 162} 163 164TEST_F(WorkItemListTest, ConditionalExecutionSuccess) { 165 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); 166 scoped_ptr<WorkItem> work_item; 167 168 FilePath top_dir_to_create(temp_dir_.path()); 169 top_dir_to_create = top_dir_to_create.AppendASCII("a"); 170 FilePath dir_to_create(top_dir_to_create); 171 dir_to_create = dir_to_create.AppendASCII("b"); 172 ASSERT_FALSE(file_util::PathExists(dir_to_create)); 173 174 work_item.reset(reinterpret_cast<WorkItem*>( 175 WorkItem::CreateCreateDirWorkItem(dir_to_create))); 176 work_item_list->AddWorkItem(work_item.release()); 177 178 scoped_ptr<WorkItemList> conditional_work_item_list( 179 WorkItem::CreateConditionalWorkItemList( 180 new ConditionRunIfFileExists(dir_to_create))); 181 182 std::wstring key_to_create(kTestRoot); 183 key_to_create.push_back(FilePath::kSeparators[0]); 184 key_to_create.append(L"ExecutionSuccess"); 185 work_item.reset(reinterpret_cast<WorkItem*>( 186 WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); 187 conditional_work_item_list->AddWorkItem(work_item.release()); 188 189 std::wstring name(kName); 190 std::wstring data(kDataStr); 191 work_item.reset(reinterpret_cast<WorkItem*>( 192 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create, 193 name, data, false))); 194 conditional_work_item_list->AddWorkItem(work_item.release()); 195 196 work_item_list->AddWorkItem(conditional_work_item_list.release()); 197 198 EXPECT_TRUE(work_item_list->Do()); 199 200 // Verify all WorkItems have been executed. 201 RegKey key; 202 EXPECT_EQ(ERROR_SUCCESS, 203 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 204 std::wstring read_out; 205 EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out)); 206 EXPECT_EQ(0, read_out.compare(kDataStr)); 207 key.Close(); 208 EXPECT_TRUE(file_util::PathExists(dir_to_create)); 209 210 work_item_list->Rollback(); 211 212 // Verify everything is rolled back. 213 // The value must have been deleted first in roll back otherwise the key 214 // can not be deleted. 215 EXPECT_NE(ERROR_SUCCESS, 216 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 217 EXPECT_FALSE(file_util::PathExists(top_dir_to_create)); 218} 219 220TEST_F(WorkItemListTest, ConditionalExecutionConditionFailure) { 221 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); 222 scoped_ptr<WorkItem> work_item; 223 224 FilePath top_dir_to_create(temp_dir_.path()); 225 top_dir_to_create = top_dir_to_create.AppendASCII("a"); 226 FilePath dir_to_create(top_dir_to_create); 227 dir_to_create = dir_to_create.AppendASCII("b"); 228 ASSERT_FALSE(file_util::PathExists(dir_to_create)); 229 230 work_item.reset(reinterpret_cast<WorkItem*>( 231 WorkItem::CreateCreateDirWorkItem(dir_to_create))); 232 work_item_list->AddWorkItem(work_item.release()); 233 234 scoped_ptr<WorkItemList> conditional_work_item_list( 235 WorkItem::CreateConditionalWorkItemList( 236 new ConditionRunIfFileExists(dir_to_create.AppendASCII("c")))); 237 238 std::wstring key_to_create(kTestRoot); 239 key_to_create.push_back(FilePath::kSeparators[0]); 240 key_to_create.append(L"ExecutionSuccess"); 241 work_item.reset(reinterpret_cast<WorkItem*>( 242 WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create))); 243 conditional_work_item_list->AddWorkItem(work_item.release()); 244 245 std::wstring name(kName); 246 std::wstring data(kDataStr); 247 work_item.reset(reinterpret_cast<WorkItem*>( 248 WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create, 249 name, data, false))); 250 conditional_work_item_list->AddWorkItem(work_item.release()); 251 252 work_item_list->AddWorkItem(conditional_work_item_list.release()); 253 254 EXPECT_TRUE(work_item_list->Do()); 255 256 // Verify that the WorkItems added as part of the conditional list have NOT 257 // been executed. 258 RegKey key; 259 EXPECT_NE(ERROR_SUCCESS, 260 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 261 std::wstring read_out; 262 EXPECT_NE(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out)); 263 key.Close(); 264 265 // Verify that the other work item was executed. 266 EXPECT_TRUE(file_util::PathExists(dir_to_create)); 267 268 work_item_list->Rollback(); 269 270 // Verify everything is rolled back. 271 // The value must have been deleted first in roll back otherwise the key 272 // can not be deleted. 273 EXPECT_NE(ERROR_SUCCESS, 274 key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); 275 EXPECT_FALSE(file_util::PathExists(top_dir_to_create)); 276} 277