1 // Copyright 2015 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.
5 #include "chrome/browser/safe_browsing/incident_reporting/state_store.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/values.h"
15 #include "chrome/browser/prefs/browser_prefs.h"
16 #include "chrome/browser/prefs/pref_service_syncable.h"
17 #include "chrome/browser/prefs/pref_service_syncable_factory.h"
18 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
19 #include "chrome/browser/safe_browsing/incident_reporting/platform_state_store.h"
20 #include "chrome/common/pref_names.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chrome/test/base/testing_profile_manager.h"
24 #include "components/pref_registry/pref_registry_syncable.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 #include "base/test/test_reg_util_win.h"
31 namespace safe_browsing
{
35 // A base test fixture that redirects HKCU for testing the platform state store
36 // backed by the Windows registry to prevent interference with existing Chrome
37 // installs or other tests.
38 class PlatformStateStoreTestBase
: public ::testing::Test
{
40 PlatformStateStoreTestBase() {}
42 void SetUp() override
{
43 ::testing::Test::SetUp();
44 registry_override_manager_
.OverrideRegistry(HKEY_CURRENT_USER
);
48 registry_util::RegistryOverrideManager registry_override_manager_
;
50 DISALLOW_COPY_AND_ASSIGN(PlatformStateStoreTestBase
);
55 using PlatformStateStoreTestBase
= ::testing::Test
;
59 // A test fixture with a testing profile that writes its user prefs to a json
61 class StateStoreTest
: public PlatformStateStoreTestBase
{
71 task_runner_(new base::TestSimpleTaskRunner()),
72 thread_task_runner_handle_(task_runner_
),
73 profile_manager_(TestingBrowserProcess::GetGlobal()) {}
75 void SetUp() override
{
76 PlatformStateStoreTestBase::SetUp();
77 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
78 ASSERT_TRUE(profile_manager_
.SetUp());
82 void DeleteProfile() {
85 profile_manager_
.DeleteTestingProfile(kProfileName_
);
89 // Removes the safebrowsing.incidents_sent preference from the profile's pref
92 ASSERT_EQ(nullptr, profile_
);
93 scoped_ptr
<base::Value
> prefs(JSONFileValueDeserializer(GetPrefsPath())
94 .Deserialize(nullptr, nullptr));
95 ASSERT_NE(nullptr, prefs
.get());
96 base::DictionaryValue
* dict
= nullptr;
97 ASSERT_TRUE(prefs
->GetAsDictionary(&dict
));
98 ASSERT_TRUE(dict
->Remove(prefs::kSafeBrowsingIncidentsSent
, nullptr));
99 ASSERT_TRUE(JSONFileValueSerializer(GetPrefsPath()).Serialize(*dict
));
102 void CreateProfile() {
103 ASSERT_EQ(nullptr, profile_
);
104 // Create the testing profile with a file-backed user pref store.
105 PrefServiceSyncableFactory factory
;
106 factory
.SetUserPrefsFile(GetPrefsPath(), task_runner_
.get());
107 user_prefs::PrefRegistrySyncable
* pref_registry
=
108 new user_prefs::PrefRegistrySyncable();
109 chrome::RegisterUserProfilePrefs(pref_registry
);
110 profile_
= profile_manager_
.CreateTestingProfile(
111 kProfileName_
, factory
.CreateSyncable(pref_registry
).Pass(),
112 base::UTF8ToUTF16(kProfileName_
), 0, std::string(),
113 TestingProfile::TestingFactories());
116 static const char kProfileName_
[];
117 static const TestData kTestData_
[];
118 TestingProfile
* profile_
;
119 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
122 base::FilePath
GetPrefsPath() {
123 return temp_dir_
.path().AppendASCII("prefs");
126 base::ScopedTempDir temp_dir_
;
127 base::ThreadTaskRunnerHandle thread_task_runner_handle_
;
128 TestingProfileManager profile_manager_
;
130 DISALLOW_COPY_AND_ASSIGN(StateStoreTest
);
134 const char StateStoreTest::kProfileName_
[] = "test_profile";
135 const StateStoreTest::TestData
StateStoreTest::kTestData_
[] = {
136 {IncidentType::TRACKED_PREFERENCE
, "tp_one", 1},
137 {IncidentType::TRACKED_PREFERENCE
, "tp_two", 2},
138 {IncidentType::TRACKED_PREFERENCE
, "tp_three", 3},
139 {IncidentType::BINARY_INTEGRITY
, "bi", 0},
140 {IncidentType::BLACKLIST_LOAD
, "bl", 0x47},
143 TEST_F(StateStoreTest
, MarkAsAndHasBeenReported
) {
144 StateStore
state_store(profile_
);
146 for (const auto& data
: kTestData_
)
147 ASSERT_FALSE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
150 StateStore::Transaction
transaction(&state_store
);
151 for (const auto& data
: kTestData_
) {
152 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
154 state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
158 for (const auto& data
: kTestData_
)
159 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
162 TEST_F(StateStoreTest
, ClearForType
) {
163 StateStore
state_store(profile_
);
166 StateStore::Transaction
transaction(&state_store
);
167 for (const auto& data
: kTestData_
)
168 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
171 for (const auto& data
: kTestData_
)
172 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
174 const IncidentType removed_type
= IncidentType::TRACKED_PREFERENCE
;
175 StateStore::Transaction(&state_store
).ClearForType(removed_type
);
177 for (const auto& data
: kTestData_
) {
178 if (data
.type
== removed_type
) {
180 state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
183 state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
188 TEST_F(StateStoreTest
, Persistence
) {
189 // Write some state to the store.
191 StateStore
state_store(profile_
);
192 StateStore::Transaction
transaction(&state_store
);
193 for (const auto& data
: kTestData_
)
194 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
197 // Run tasks to write prefs out to the JsonPrefStore.
198 task_runner_
->RunUntilIdle();
200 // Delete the profile.
203 // Recreate the profile.
206 // Verify that the state survived.
207 StateStore
state_store(profile_
);
208 for (const auto& data
: kTestData_
)
209 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
212 TEST_F(StateStoreTest
, PersistenceWithStoreDelete
) {
213 // Write some state to the store.
215 StateStore
state_store(profile_
);
216 StateStore::Transaction
transaction(&state_store
);
217 for (const auto& data
: kTestData_
)
218 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
221 // Run tasks to write prefs out to the JsonPrefStore.
222 task_runner_
->RunUntilIdle();
224 // Delete the profile.
227 // Delete the state pref.
230 // Recreate the profile.
233 StateStore
state_store(profile_
);
234 for (const auto& data
: kTestData_
) {
235 #if defined(USE_PLATFORM_STATE_STORE)
236 // Verify that the state survived.
237 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
239 // Verify that the state did not survive.
240 ASSERT_FALSE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
245 } // namespace safe_browsing