Chromium Code Reviews| Index: chrome/installer/util/work_item_list_unittest.cc |
| diff --git a/chrome/installer/util/work_item_list_unittest.cc b/chrome/installer/util/work_item_list_unittest.cc |
| index 1a2eb3d3060e9b7316061070c476ff7cdfc9884e..d00f4089c1a1601c6643a866828738ef12ab6919 100644 |
| --- a/chrome/installer/util/work_item_list_unittest.cc |
| +++ b/chrome/installer/util/work_item_list_unittest.cc |
| @@ -2,284 +2,198 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include <windows.h> |
| +#include "chrome/installer/util/work_item_list.h" |
| + |
| +#include <memory> |
| -#include "base/base_paths.h" |
| -#include "base/files/file_util.h" |
| +#include "base/files/file_path.h" |
| #include "base/files/scoped_temp_dir.h" |
| -#include "base/memory/scoped_ptr.h" |
| -#include "base/strings/string_util.h" |
| -#include "base/test/test_reg_util_win.h" |
| -#include "base/win/registry.h" |
| +#include "base/macros.h" |
| #include "chrome/installer/util/conditional_work_item_list.h" |
| #include "chrome/installer/util/work_item.h" |
| -#include "chrome/installer/util/work_item_list.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| -using base::win::RegKey; |
| - |
| namespace { |
| -const wchar_t kTestRoot[] = L"ListList"; |
| -const wchar_t kDataStr[] = L"data_111"; |
| -const wchar_t kName[] = L"name"; |
| +class MockWorkItem : public WorkItem { |
| + public: |
| + MockWorkItem() = default; |
| -class WorkItemListTest : public testing::Test { |
| - protected: |
| - void SetUp() override { |
| - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| - registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER); |
| - } |
| + MOCK_METHOD0(Do, bool()); |
| + MOCK_METHOD0(Rollback, void()); |
| - void TearDown() override { logging::CloseLogFile(); } |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MockWorkItem); |
| +}; |
| + |
| +class AlwaysTrueCondition : public WorkItem::Condition { |
|
grt (UTC plus 2)
2016/04/13 18:08:51
why not use a Mock for this so that the trueness a
fdoray
2016/04/13 18:57:16
Done.
|
| + public: |
| + bool ShouldRun() const override { return true; } |
| +}; |
| - base::ScopedTempDir temp_dir_; |
| - registry_util::RegistryOverrideManager registry_override_manager_; |
| +class AlwaysFalseCondition : public WorkItem::Condition { |
| + public: |
| + bool ShouldRun() const override { return false; } |
| }; |
| +using StrictMockWorkItem = testing::StrictMock<MockWorkItem>; |
| +using testing::InSequence; |
| +using testing::Return; |
| + |
| } // namespace |
| -// 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; |
| - |
| - base::FilePath top_dir_to_create(temp_dir_.path()); |
| - top_dir_to_create = top_dir_to_create.AppendASCII("a"); |
| - base::FilePath dir_to_create(top_dir_to_create); |
| - dir_to_create = dir_to_create.AppendASCII("b"); |
| - ASSERT_FALSE(base::PathExists(dir_to_create)); |
| - |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateCreateDirWorkItem(dir_to_create))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - std::wstring key_to_create(kTestRoot); |
| - key_to_create.push_back(base::FilePath::kSeparators[0]); |
| - key_to_create.append(L"ExecutionSuccess"); |
| - |
| - work_item.reset( |
| - reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( |
| - HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - std::wstring name(kName); |
| - std::wstring data(kDataStr); |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, |
| - key_to_create, |
| - WorkItem::kWow64Default, |
| - name, |
| - data, |
| - false))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - EXPECT_TRUE(work_item_list->Do()); |
| - |
| - // Verify all WorkItems have been executed. |
| - RegKey key; |
| - EXPECT_EQ(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - std::wstring read_out; |
| - EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out)); |
| - EXPECT_EQ(0, read_out.compare(kDataStr)); |
| - key.Close(); |
| - EXPECT_TRUE(base::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_NE(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - EXPECT_FALSE(base::PathExists(top_dir_to_create)); |
| +// Execute a WorkItemList successfully and then rollback. |
| +TEST(WorkItemListTest, ExecutionSuccess) { |
| + std::unique_ptr<WorkItemList> list(WorkItem::CreateWorkItemList()); |
| + |
| + // Create the mock work items. |
| + std::unique_ptr<StrictMockWorkItem> item1(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item2(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item3(new StrictMockWorkItem); |
| + |
| + { |
| + // Expect all three items to be done in order then undone. |
| + InSequence s; |
| + |
| + EXPECT_CALL(*item1, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item2, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item3, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item3, Rollback()); |
| + EXPECT_CALL(*item2, Rollback()); |
| + EXPECT_CALL(*item1, Rollback()); |
| + } |
| + |
| + // Add the items to the list. |
| + list->AddWorkItem(item1.release()); |
| + list->AddWorkItem(item2.release()); |
| + list->AddWorkItem(item3.release()); |
| + |
| + // Do and rollback the list. |
| + EXPECT_TRUE(list->Do()); |
| + list->Rollback(); |
| } |
| -// 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; |
| - |
| - base::FilePath top_dir_to_create(temp_dir_.path()); |
| - top_dir_to_create = top_dir_to_create.AppendASCII("a"); |
| - base::FilePath dir_to_create(top_dir_to_create); |
| - dir_to_create = dir_to_create.AppendASCII("b"); |
| - ASSERT_FALSE(base::PathExists(dir_to_create)); |
| - |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateCreateDirWorkItem(dir_to_create))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - std::wstring key_to_create(kTestRoot); |
| - key_to_create.push_back(base::FilePath::kSeparators[0]); |
| - key_to_create.append(L"ExecutionFail"); |
| - |
| - work_item.reset( |
| - reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( |
| - HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - std::wstring not_created_key(kTestRoot); |
| - not_created_key.push_back(base::FilePath::kSeparators[0]); |
| - not_created_key.append(L"NotCreated"); |
| - std::wstring name(kName); |
| - std::wstring data(kDataStr); |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, |
| - not_created_key, |
| - WorkItem::kWow64Default, |
| - name, |
| - data, |
| - false))); |
| - 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, WorkItem::kWow64Default))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - EXPECT_FALSE(work_item_list->Do()); |
| - |
| - // Verify the first 2 WorkItems have been executed. |
| - RegKey key; |
| - EXPECT_EQ(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - key.Close(); |
| - EXPECT_TRUE(base::PathExists(dir_to_create)); |
| - // The last one should not be there. |
| - EXPECT_NE(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, not_created_key.c_str(), KEY_READ)); |
| - |
| - work_item_list->Rollback(); |
| - |
| - // Verify everything is rolled back. |
| - EXPECT_NE(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - EXPECT_FALSE(base::PathExists(top_dir_to_create)); |
| +// Execute a WorkItemList. Fail in the middle. Rollback what has been done. |
| +TEST(WorkItemListTest, ExecutionFailAndRollback) { |
| + std::unique_ptr<WorkItemList> list(WorkItem::CreateWorkItemList()); |
| + |
| + // Create the mock work items. |
| + std::unique_ptr<StrictMockWorkItem> item1(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item2(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item3(new StrictMockWorkItem); |
| + |
| + { |
| + // Expect the two first work items to be done in order then undone. |
| + InSequence s; |
| + |
| + EXPECT_CALL(*item1, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item2, Do()).WillOnce(Return(false)); |
| + EXPECT_CALL(*item2, Rollback()); |
| + EXPECT_CALL(*item1, Rollback()); |
| + } |
| + |
| + // Add the items to the list. |
| + list->AddWorkItem(item1.release()); |
| + list->AddWorkItem(item2.release()); |
| + list->AddWorkItem(item3.release()); |
| + |
| + // Do and rollback the list. |
| + EXPECT_FALSE(list->Do()); |
| + list->Rollback(); |
| +} |
| + |
| +// Execute a ConditionalWorkItemList whose condition is met and then rollback. |
| +TEST(WorkItemListTest, ConditionalExecutionSuccess) { |
| + std::unique_ptr<WorkItemList> list( |
| + WorkItem::CreateConditionalWorkItemList(new AlwaysTrueCondition())); |
| + |
| + // Create the mock work items. |
| + std::unique_ptr<StrictMockWorkItem> item1(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item2(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item3(new StrictMockWorkItem); |
| + |
| + { |
| + // Expect all three items to be done in order then undone. |
| + InSequence s; |
| + |
| + EXPECT_CALL(*item1, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item2, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item3, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item3, Rollback()); |
| + EXPECT_CALL(*item2, Rollback()); |
| + EXPECT_CALL(*item1, Rollback()); |
| + } |
| + |
| + // Add the items to the list. |
| + list->AddWorkItem(item1.release()); |
| + list->AddWorkItem(item2.release()); |
| + list->AddWorkItem(item3.release()); |
| + |
| + // Do and rollback the list. |
| + EXPECT_TRUE(list->Do()); |
| + list->Rollback(); |
| +} |
| + |
| +// Execute a ConditionalWorkItemList whose condition is met. Fail in the middle. |
| +// Rollback what has been done. |
| +TEST(WorkItemListTest, ConditionalExecutionFailAndRollback) { |
| + std::unique_ptr<WorkItemList> list( |
| + WorkItem::CreateConditionalWorkItemList(new AlwaysTrueCondition())); |
| + |
| + // Create the mock work items. |
| + std::unique_ptr<StrictMockWorkItem> item1(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item2(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item3(new StrictMockWorkItem); |
| + |
| + { |
| + // Expect the two first work items to be done in order then undone. |
| + InSequence s; |
| + |
| + EXPECT_CALL(*item1, Do()).WillOnce(Return(true)); |
| + EXPECT_CALL(*item2, Do()).WillOnce(Return(false)); |
| + EXPECT_CALL(*item2, Rollback()); |
| + EXPECT_CALL(*item1, Rollback()); |
| + } |
| + |
| + // Add the items to the list. |
| + list->AddWorkItem(item1.release()); |
| + list->AddWorkItem(item2.release()); |
| + list->AddWorkItem(item3.release()); |
| + |
| + // Do and rollback the list. |
| + EXPECT_FALSE(list->Do()); |
| + list->Rollback(); |
| } |
| -TEST_F(WorkItemListTest, ConditionalExecutionSuccess) { |
| - scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); |
| - scoped_ptr<WorkItem> work_item; |
| - |
| - base::FilePath top_dir_to_create(temp_dir_.path()); |
| - top_dir_to_create = top_dir_to_create.AppendASCII("a"); |
| - base::FilePath dir_to_create(top_dir_to_create); |
| - dir_to_create = dir_to_create.AppendASCII("b"); |
| - ASSERT_FALSE(base::PathExists(dir_to_create)); |
| - |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateCreateDirWorkItem(dir_to_create))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - scoped_ptr<WorkItemList> conditional_work_item_list( |
| - WorkItem::CreateConditionalWorkItemList( |
| - new ConditionRunIfFileExists(dir_to_create))); |
| - |
| - std::wstring key_to_create(kTestRoot); |
| - key_to_create.push_back(base::FilePath::kSeparators[0]); |
| - key_to_create.append(L"ExecutionSuccess"); |
| - work_item.reset( |
| - reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( |
| - HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); |
| - conditional_work_item_list->AddWorkItem(work_item.release()); |
| - |
| - std::wstring name(kName); |
| - std::wstring data(kDataStr); |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, |
| - key_to_create, |
| - WorkItem::kWow64Default, |
| - name, |
| - data, |
| - false))); |
| - conditional_work_item_list->AddWorkItem(work_item.release()); |
| - |
| - work_item_list->AddWorkItem(conditional_work_item_list.release()); |
| - |
| - EXPECT_TRUE(work_item_list->Do()); |
| - |
| - // Verify all WorkItems have been executed. |
| - RegKey key; |
| - EXPECT_EQ(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - std::wstring read_out; |
| - EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out)); |
| - EXPECT_EQ(0, read_out.compare(kDataStr)); |
| - key.Close(); |
| - EXPECT_TRUE(base::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_NE(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - EXPECT_FALSE(base::PathExists(top_dir_to_create)); |
| +// Execute a ConditionalWorkItemList whose condition isn't met. |
| +TEST(WorkItemListTest, ConditionalExecutionConditionFailure) { |
| + std::unique_ptr<WorkItemList> list( |
| + WorkItem::CreateConditionalWorkItemList(new AlwaysFalseCondition)); |
| + |
| + // Create the mock work items. |
| + std::unique_ptr<StrictMockWorkItem> item1(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item2(new StrictMockWorkItem); |
| + std::unique_ptr<StrictMockWorkItem> item3(new StrictMockWorkItem); |
| + |
| + // Don't expect any call to the methods of the work items. |
| + |
| + // Add the items to the list. |
| + list->AddWorkItem(item1.release()); |
| + list->AddWorkItem(item2.release()); |
| + list->AddWorkItem(item3.release()); |
| + |
| + // Do and rollback the list. |
| + EXPECT_TRUE(list->Do()); |
| + list->Rollback(); |
| } |
| -TEST_F(WorkItemListTest, ConditionalExecutionConditionFailure) { |
| - scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); |
| - scoped_ptr<WorkItem> work_item; |
| - |
| - base::FilePath top_dir_to_create(temp_dir_.path()); |
| - top_dir_to_create = top_dir_to_create.AppendASCII("a"); |
| - base::FilePath dir_to_create(top_dir_to_create); |
| - dir_to_create = dir_to_create.AppendASCII("b"); |
| - ASSERT_FALSE(base::PathExists(dir_to_create)); |
| - |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateCreateDirWorkItem(dir_to_create))); |
| - work_item_list->AddWorkItem(work_item.release()); |
| - |
| - scoped_ptr<WorkItemList> conditional_work_item_list( |
| - WorkItem::CreateConditionalWorkItemList( |
| - new ConditionRunIfFileExists(dir_to_create.AppendASCII("c")))); |
| - |
| - std::wstring key_to_create(kTestRoot); |
| - key_to_create.push_back(base::FilePath::kSeparators[0]); |
| - key_to_create.append(L"ExecutionSuccess"); |
| - work_item.reset( |
| - reinterpret_cast<WorkItem*>(WorkItem::CreateCreateRegKeyWorkItem( |
| - HKEY_CURRENT_USER, key_to_create, WorkItem::kWow64Default))); |
| - conditional_work_item_list->AddWorkItem(work_item.release()); |
| - |
| - std::wstring name(kName); |
| - std::wstring data(kDataStr); |
| - work_item.reset(reinterpret_cast<WorkItem*>( |
| - WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, |
| - key_to_create, |
| - WorkItem::kWow64Default, |
| - name, |
| - data, |
| - false))); |
| - conditional_work_item_list->AddWorkItem(work_item.release()); |
| - |
| - work_item_list->AddWorkItem(conditional_work_item_list.release()); |
| - |
| - EXPECT_TRUE(work_item_list->Do()); |
| - |
| - // Verify that the WorkItems added as part of the conditional list have NOT |
| - // been executed. |
| - RegKey key; |
| - EXPECT_NE(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - std::wstring read_out; |
| - EXPECT_NE(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out)); |
| - key.Close(); |
| - |
| - // Verify that the other work item was executed. |
| - EXPECT_TRUE(base::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_NE(ERROR_SUCCESS, |
| - key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ)); |
| - EXPECT_FALSE(base::PathExists(top_dir_to_create)); |
| +TEST(WorkItemListTest, ConditionRunIfFileExists) { |
| + base::ScopedTempDir temp_dir; |
| + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| + |
| + EXPECT_TRUE(ConditionRunIfFileExists(temp_dir.path()).ShouldRun()); |
| + EXPECT_FALSE(ConditionRunIfFileExists( |
| + temp_dir.path().Append(FILE_PATH_LITERAL("DoesNotExist"))) |
| + .ShouldRun()); |
| } |