Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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 #include <shlwapi.h> // NOLINT | |
| 7 | |
| 8 #include "base/logging.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/win/registry.h" | |
| 11 #include "chrome/installer/util/copy_reg_key_work_item.h" | |
| 12 #include "chrome/installer/util/work_item.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 using base::win::RegKey; | |
| 16 | |
| 17 // Test fixture for CopyRegKeyWorkItem. The fixture sets up some data in the | |
| 18 // registry during setup. Each test runs | |
|
erikwright (departed)
2011/09/15 18:38:57
incomplete comment?
grt (UTC plus 2)
2011/09/16 17:45:45
Done.
| |
| 19 class CopyRegKeyWorkItemTest : public testing::Test { | |
| 20 protected: | |
| 21 static const HKEY kRootKey; | |
| 22 | |
| 23 static void SetUpTestCase() { | |
|
erikwright (departed)
2011/09/15 18:38:57
Unless there's a reason to use SetUpTestCase, I wo
grt (UTC plus 2)
2011/09/16 17:45:45
It's a little more work and IO for each test to do
| |
| 24 // Make some strings that we'll use. | |
| 25 temp_key_path_ = new std::wstring(L"SOFTWARE\\TmpTmp"); | |
| 26 dest_key_path_ = new std::wstring(*temp_key_path_ + L"\\Destination"); | |
| 27 empty_key_path_ = new std::wstring(*temp_key_path_ + L"\\EmptyKey"); | |
| 28 non_empty_key_path_ = new std::wstring(*temp_key_path_ + L"\\NonEmptyKey"); | |
| 29 | |
| 30 // Create a temporary key for testing | |
| 31 RegKey key(kRootKey, L"", KEY_QUERY_VALUE); | |
|
erikwright (departed)
2011/09/15 18:38:57
This appears to be a common setup/teardown behavio
grt (UTC plus 2)
2011/09/16 17:45:45
Done.
| |
| 32 key.DeleteKey(temp_key_path_->c_str()); | |
| 33 ASSERT_NE(ERROR_SUCCESS, | |
| 34 key.Open(kRootKey, temp_key_path_->c_str(), KEY_READ)); | |
| 35 ASSERT_EQ(ERROR_SUCCESS, | |
| 36 key.Create(kRootKey, temp_key_path_->c_str(), KEY_READ)); | |
| 37 | |
| 38 // Put some data in the registry | |
| 39 ASSERT_EQ(ERROR_SUCCESS, | |
| 40 key.Create(kRootKey, empty_key_path_->c_str(), KEY_READ)); | |
| 41 ASSERT_EQ(ERROR_SUCCESS, | |
| 42 key.Create(kRootKey, non_empty_key_path_->c_str(), KEY_WRITE)); | |
| 43 ASSERT_EQ(ERROR_SUCCESS, | |
| 44 key.WriteValue(NULL, non_empty_key_path_->c_str())); | |
| 45 ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Subkey", KEY_WRITE)); | |
| 46 ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(L"SomeValue", 1U)); | |
| 47 } | |
| 48 | |
| 49 static void TearDownTestCase() { | |
| 50 // Clean up the temporary key | |
| 51 RegKey key(kRootKey, L"", KEY_QUERY_VALUE); | |
| 52 ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(temp_key_path_->c_str())); | |
| 53 | |
| 54 delete non_empty_key_path_; | |
|
erikwright (departed)
2011/09/15 18:38:57
All of these would go away if you used SetUp/TearD
grt (UTC plus 2)
2011/09/16 17:45:45
Done.
| |
| 55 non_empty_key_path_ = NULL; | |
| 56 delete empty_key_path_; | |
| 57 empty_key_path_ = NULL; | |
| 58 delete dest_key_path_; | |
| 59 dest_key_path_ = NULL; | |
| 60 delete temp_key_path_; | |
| 61 temp_key_path_ = NULL; | |
| 62 | |
| 63 logging::CloseLogFile(); | |
|
erikwright (departed)
2011/09/15 18:38:57
Why is this here?
grt (UTC plus 2)
2011/09/16 17:45:45
Beats the hell out of me. It's all over the unit
| |
| 64 } | |
| 65 | |
| 66 virtual void SetUp() { | |
| 67 } | |
| 68 | |
| 69 virtual void TearDown() { | |
| 70 // Delete the destination for the next test. | |
| 71 RegKey key(kRootKey, L"", KEY_QUERY_VALUE); | |
| 72 LONG result = key.DeleteKey(dest_key_path_->c_str()); | |
| 73 ASSERT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND); | |
| 74 } | |
| 75 | |
| 76 static std::wstring* temp_key_path_; | |
| 77 static std::wstring* dest_key_path_; | |
| 78 static std::wstring* empty_key_path_; | |
| 79 static std::wstring* non_empty_key_path_; | |
| 80 }; | |
| 81 | |
| 82 const HKEY CopyRegKeyWorkItemTest::kRootKey = HKEY_CURRENT_USER; | |
| 83 std::wstring* CopyRegKeyWorkItemTest::temp_key_path_ = NULL; | |
| 84 std::wstring* CopyRegKeyWorkItemTest::dest_key_path_ = NULL; | |
| 85 std::wstring* CopyRegKeyWorkItemTest::empty_key_path_ = NULL; | |
| 86 std::wstring* CopyRegKeyWorkItemTest::non_empty_key_path_ = NULL; | |
| 87 | |
| 88 // Test that copying a key that doesn't exist succeeds, and that rollback does | |
| 89 // nothing. | |
| 90 TEST_F(CopyRegKeyWorkItemTest, TestNoKey) { | |
| 91 const std::wstring key_paths[] = { | |
| 92 std::wstring(*temp_key_path_ + L"\\NoKeyHere"), | |
| 93 std::wstring(*temp_key_path_ + L"\\NoKeyHere\\OrHere") | |
| 94 }; | |
| 95 RegKey key; | |
| 96 for (size_t i = 0; i < arraysize(key_paths); ++i) { | |
| 97 const std::wstring& key_path = key_paths[i]; | |
| 98 scoped_ptr<CopyRegKeyWorkItem> item( | |
| 99 WorkItem::CreateCopyRegKeyWorkItem(kRootKey, key_path, | |
| 100 *dest_key_path_)); | |
| 101 EXPECT_TRUE(item->Do()); | |
| 102 EXPECT_NE(ERROR_SUCCESS, | |
| 103 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 104 item->Rollback(); | |
| 105 item.reset(); | |
| 106 EXPECT_NE(ERROR_SUCCESS, | |
| 107 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 // Test that copying an empty key succeeds, and that rollback removes the copy. | |
| 112 TEST_F(CopyRegKeyWorkItemTest, TestEmptyKey) { | |
| 113 RegKey key; | |
| 114 scoped_ptr<CopyRegKeyWorkItem> item( | |
| 115 WorkItem::CreateCopyRegKeyWorkItem(kRootKey, *empty_key_path_, | |
| 116 *dest_key_path_)); | |
| 117 EXPECT_TRUE(item->Do()); | |
| 118 EXPECT_EQ(ERROR_SUCCESS, | |
| 119 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 120 item->Rollback(); | |
| 121 item.reset(); | |
| 122 EXPECT_NE(ERROR_SUCCESS, | |
| 123 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 124 } | |
| 125 | |
| 126 // Test that copying a key with subkeys and values succeeds, and that rollback | |
| 127 // removes the copy. | |
| 128 TEST_F(CopyRegKeyWorkItemTest, TestNonEmptyKey) { | |
| 129 RegKey key; | |
| 130 scoped_ptr<CopyRegKeyWorkItem> item( | |
| 131 WorkItem::CreateCopyRegKeyWorkItem(kRootKey, *non_empty_key_path_, | |
| 132 *dest_key_path_)); | |
| 133 EXPECT_TRUE(item->Do()); | |
| 134 EXPECT_EQ(ERROR_SUCCESS, | |
| 135 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 136 std::wstring str_value; | |
| 137 EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(NULL, &str_value)); | |
| 138 EXPECT_EQ(*non_empty_key_path_, str_value); | |
| 139 EXPECT_EQ(ERROR_SUCCESS, key.OpenKey(L"Subkey", KEY_READ)); | |
| 140 DWORD dw_value = 0; | |
| 141 EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"SomeValue", &dw_value)); | |
| 142 EXPECT_EQ(1U, dw_value); | |
| 143 item->Rollback(); | |
| 144 item.reset(); | |
| 145 EXPECT_NE(ERROR_SUCCESS, | |
| 146 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 147 } | |
| 148 | |
| 149 // Test that copying an empty key over a key with data succeeds, and that | |
| 150 // rollback restores the original data. | |
| 151 TEST_F(CopyRegKeyWorkItemTest, TestOverwriteAndRestore) { | |
| 152 RegKey key; | |
| 153 // First copy the data into the dest. | |
| 154 EXPECT_EQ(ERROR_SUCCESS, | |
| 155 key.Create(kRootKey, dest_key_path_->c_str(), KEY_WRITE)); | |
| 156 EXPECT_EQ(ERROR_SUCCESS, | |
| 157 SHCopyKey(kRootKey, non_empty_key_path_->c_str(), key.Handle(), 0)); | |
| 158 key.Close(); | |
| 159 | |
| 160 // Now copy the empty key into the dest. | |
| 161 scoped_ptr<CopyRegKeyWorkItem> item( | |
| 162 WorkItem::CreateCopyRegKeyWorkItem(kRootKey, *empty_key_path_, | |
| 163 *dest_key_path_)); | |
| 164 EXPECT_TRUE(item->Do()); | |
| 165 | |
| 166 // Make sure the dest is now empty. | |
| 167 DWORD num_subkeys = 0; | |
| 168 DWORD num_values = 0; | |
| 169 EXPECT_EQ(ERROR_SUCCESS, | |
| 170 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 171 EXPECT_EQ(ERROR_SUCCESS, | |
| 172 RegQueryInfoKey(key.Handle(), NULL, NULL, NULL, &num_subkeys, | |
| 173 NULL, NULL, &num_values, NULL, NULL, NULL, NULL)); | |
| 174 EXPECT_EQ(0UL, num_subkeys); | |
| 175 EXPECT_EQ(0UL, num_values); | |
| 176 key.Close(); | |
| 177 | |
| 178 // Restore the data. | |
| 179 item->Rollback(); | |
| 180 item.reset(); | |
| 181 | |
| 182 EXPECT_EQ(ERROR_SUCCESS, | |
| 183 key.Open(kRootKey, dest_key_path_->c_str(), KEY_READ)); | |
| 184 std::wstring str_value; | |
| 185 EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(NULL, &str_value)); | |
| 186 EXPECT_EQ(*non_empty_key_path_, str_value); | |
| 187 EXPECT_EQ(ERROR_SUCCESS, key.OpenKey(L"Subkey", KEY_READ)); | |
| 188 DWORD dw_value = 0; | |
| 189 EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"SomeValue", &dw_value)); | |
| 190 EXPECT_EQ(1U, dw_value); | |
| 191 } | |
|
erikwright (departed)
2011/09/15 18:38:57
I suppose completeness would dictate a test for Ro
grt (UTC plus 2)
2011/09/16 17:45:45
Done.
| |
| OLD | NEW |