1 // Copyright 2013 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 "base/test/test_reg_util_win.h"
6
7 #include <memory>
8
9 #include "base/compiler_specific.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace registry_util {
17
18 namespace {
19 const wchar_t kTestKeyPath[] = L"Software\\Chromium\\Foo\\Baz\\TestKey";
20 const wchar_t kTestValueName[] = L"TestValue";
21 } // namespace
22
23 class RegistryOverrideManagerTest : public testing::Test {
24 protected:
RegistryOverrideManagerTest()25 RegistryOverrideManagerTest() {
26 // We assign a fake test key path to our test RegistryOverrideManager
27 // so we don't interfere with any actual RegistryOverrideManagers running
28 // on the system. This fake path will be auto-deleted by other
29 // RegistryOverrideManagers in case we crash.
30 fake_test_key_root_ = registry_util::GenerateTempKeyPath();
31
32 // Ensure a clean test environment.
33 base::win::RegKey key(HKEY_CURRENT_USER);
34 key.DeleteKey(fake_test_key_root_.c_str());
35 key.DeleteKey(kTestKeyPath);
36 }
37
~RegistryOverrideManagerTest()38 ~RegistryOverrideManagerTest() override {
39 base::win::RegKey key(HKEY_CURRENT_USER);
40 key.DeleteKey(fake_test_key_root_.c_str());
41 }
42
AssertKeyExists(const std::wstring & key_path)43 void AssertKeyExists(const std::wstring& key_path) {
44 base::win::RegKey key;
45 ASSERT_EQ(ERROR_SUCCESS,
46 key.Open(HKEY_CURRENT_USER, key_path.c_str(), KEY_READ))
47 << key_path << " does not exist.";
48 }
49
AssertKeyAbsent(const std::wstring & key_path)50 void AssertKeyAbsent(const std::wstring& key_path) {
51 base::win::RegKey key;
52 ASSERT_NE(ERROR_SUCCESS,
53 key.Open(HKEY_CURRENT_USER, key_path.c_str(), KEY_READ))
54 << key_path << " exists but it should not.";
55 }
56
CreateKey(const std::wstring & key_path)57 void CreateKey(const std::wstring& key_path) {
58 base::win::RegKey key;
59 ASSERT_EQ(ERROR_SUCCESS,
60 key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_ALL_ACCESS));
61 }
62
FakeOverrideManagerPath(const base::Time & time)63 std::wstring FakeOverrideManagerPath(const base::Time& time) {
64 return fake_test_key_root_ + L"\\" +
65 base::AsWString(base::NumberToString16(time.ToInternalValue()));
66 }
67
CreateManager(const base::Time & timestamp)68 void CreateManager(const base::Time& timestamp) {
69 manager_.reset(new RegistryOverrideManager(timestamp, fake_test_key_root_));
70 manager_->OverrideRegistry(HKEY_CURRENT_USER);
71 }
72
73 std::wstring fake_test_key_root_;
74 std::unique_ptr<RegistryOverrideManager> manager_;
75 };
76
TEST_F(RegistryOverrideManagerTest,Basic)77 TEST_F(RegistryOverrideManagerTest, Basic) {
78 ASSERT_NO_FATAL_FAILURE(CreateManager(base::Time::Now()));
79
80 base::win::RegKey create_key;
81 EXPECT_EQ(ERROR_SUCCESS,
82 create_key.Create(HKEY_CURRENT_USER, kTestKeyPath, KEY_ALL_ACCESS));
83 EXPECT_TRUE(create_key.Valid());
84 EXPECT_EQ(ERROR_SUCCESS, create_key.WriteValue(kTestValueName, 42));
85 create_key.Close();
86
87 ASSERT_NO_FATAL_FAILURE(AssertKeyExists(kTestKeyPath));
88
89 DWORD value;
90 base::win::RegKey read_key;
91 EXPECT_EQ(ERROR_SUCCESS,
92 read_key.Open(HKEY_CURRENT_USER, kTestKeyPath, KEY_READ));
93 EXPECT_TRUE(read_key.Valid());
94 EXPECT_EQ(ERROR_SUCCESS, read_key.ReadValueDW(kTestValueName, &value));
95 EXPECT_EQ(42u, value);
96 read_key.Close();
97
98 manager_.reset();
99
100 ASSERT_NO_FATAL_FAILURE(AssertKeyAbsent(kTestKeyPath));
101 }
102
TEST_F(RegistryOverrideManagerTest,DeleteStaleKeys)103 TEST_F(RegistryOverrideManagerTest, DeleteStaleKeys) {
104 base::Time::Exploded kTestTimeExploded = {2013, 11, 1, 4, 0, 0, 0, 0};
105 base::Time kTestTime;
106 EXPECT_TRUE(base::Time::FromUTCExploded(kTestTimeExploded, &kTestTime));
107
108 std::wstring path_garbage = fake_test_key_root_ + L"\\Blah";
109 std::wstring path_very_stale =
110 FakeOverrideManagerPath(kTestTime - base::TimeDelta::FromDays(100));
111 std::wstring path_stale =
112 FakeOverrideManagerPath(kTestTime - base::TimeDelta::FromDays(5));
113 std::wstring path_current =
114 FakeOverrideManagerPath(kTestTime - base::TimeDelta::FromMinutes(1));
115 std::wstring path_future =
116 FakeOverrideManagerPath(kTestTime + base::TimeDelta::FromMinutes(1));
117
118 ASSERT_NO_FATAL_FAILURE(CreateKey(path_garbage));
119 ASSERT_NO_FATAL_FAILURE(CreateKey(path_very_stale));
120 ASSERT_NO_FATAL_FAILURE(CreateKey(path_stale));
121 ASSERT_NO_FATAL_FAILURE(CreateKey(path_current));
122 ASSERT_NO_FATAL_FAILURE(CreateKey(path_future));
123
124 ASSERT_NO_FATAL_FAILURE(CreateManager(kTestTime));
125 manager_.reset();
126
127 ASSERT_NO_FATAL_FAILURE(AssertKeyAbsent(path_garbage));
128 ASSERT_NO_FATAL_FAILURE(AssertKeyAbsent(path_very_stale));
129 ASSERT_NO_FATAL_FAILURE(AssertKeyAbsent(path_stale));
130 ASSERT_NO_FATAL_FAILURE(AssertKeyExists(path_current));
131 ASSERT_NO_FATAL_FAILURE(AssertKeyExists(path_future));
132 }
133
134 } // namespace registry_util
135