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/safe_browsing/incident_reporting/incident.h"
17 #include "chrome/browser/safe_browsing/incident_reporting/platform_state_store.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
22 #include "components/pref_registry/pref_registry_syncable.h"
23 #include "components/syncable_prefs/pref_service_syncable.h"
24 #include "components/syncable_prefs/pref_service_syncable_factory.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 syncable_prefs::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
, ClearAll
) {
189 StateStore
state_store(profile_
);
190 // Write some state to the store.
192 StateStore::Transaction
transaction(&state_store
);
193 for (const auto& data
: kTestData_
)
194 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
197 StateStore::Transaction(&state_store
).ClearAll();
199 for (const auto& data
: kTestData_
) {
200 ASSERT_FALSE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
203 // Run tasks to write prefs out to the JsonPrefStore.
204 task_runner_
->RunUntilIdle();
206 // Delete the profile.
209 // Recreate the profile.
212 StateStore
store_2(profile_
);
213 for (const auto& data
: kTestData_
) {
214 // Verify that the state did not survive through the Platform State Store.
215 ASSERT_FALSE(store_2
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
219 TEST_F(StateStoreTest
, Persistence
) {
220 // Write some state to the store.
222 StateStore
state_store(profile_
);
223 StateStore::Transaction
transaction(&state_store
);
224 for (const auto& data
: kTestData_
)
225 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
228 // Run tasks to write prefs out to the JsonPrefStore.
229 task_runner_
->RunUntilIdle();
231 // Delete the profile.
234 // Recreate the profile.
237 // Verify that the state survived.
238 StateStore
state_store(profile_
);
239 for (const auto& data
: kTestData_
)
240 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
243 TEST_F(StateStoreTest
, PersistenceWithStoreDelete
) {
244 // Write some state to the store.
246 StateStore
state_store(profile_
);
247 StateStore::Transaction
transaction(&state_store
);
248 for (const auto& data
: kTestData_
)
249 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
252 // Run tasks to write prefs out to the JsonPrefStore.
253 task_runner_
->RunUntilIdle();
255 // Delete the profile.
258 // Delete the state pref.
261 // Recreate the profile.
264 StateStore
state_store(profile_
);
265 for (const auto& data
: kTestData_
) {
266 #if defined(USE_PLATFORM_STATE_STORE)
267 // Verify that the state survived.
268 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
270 // Verify that the state did not survive.
271 ASSERT_FALSE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
276 } // namespace safe_browsing