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