1 // Copyright 2014 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/prefs/tracked/tracked_preferences_migration.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/values.h"
15 #include "chrome/browser/prefs/interceptable_pref_filter.h"
16 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h"
17 #include "testing/gtest/include/gtest/gtest.h"
21 // An unprotected pref.
22 const char kUnprotectedPref[] = "unprotected";
24 const char kProtectedPref[] = "protected";
25 // A protected pref which is initially stored in the unprotected store.
26 const char kPreviouslyUnprotectedPref[] = "previously.unprotected";
27 // An unprotected pref which is initially stored in the protected store.
28 const char kPreviouslyProtectedPref[] = "previously.protected";
30 const char kUnprotectedPrefValue[] = "unprotected_value";
31 const char kProtectedPrefValue[] = "protected_value";
32 const char kPreviouslyUnprotectedPrefValue[] = "previously_unprotected_value";
33 const char kPreviouslyProtectedPrefValue[] = "previously_protected_value";
35 // A simple InterceptablePrefFilter which doesn't do anything but hand the prefs
36 // back downstream in FinalizeFilterOnLoad.
37 class SimpleInterceptablePrefFilter : public InterceptablePrefFilter {
39 // PrefFilter remaining implementation.
40 virtual void FilterUpdate(const std::string& path) OVERRIDE {
43 virtual void FilterSerializeData(
44 const base::DictionaryValue* pref_store_contents) OVERRIDE {
49 // InterceptablePrefFilter implementation.
50 virtual void FinalizeFilterOnLoad(
51 const PostFilterOnLoadCallback& post_filter_on_load_callback,
52 scoped_ptr<base::DictionaryValue> pref_store_contents,
53 bool prefs_altered) OVERRIDE {
54 post_filter_on_load_callback.Run(pref_store_contents.Pass(), prefs_altered);
58 // A test fixture designed to like this:
59 // 1) Set up initial store prefs with PresetStoreValue().
60 // 2) Hand both sets of prefs to the migrator via HandPrefsToMigrator().
61 // 3) Migration completes synchronously when the second store hands its prefs
63 // 4) Verifications can be made via various methods of this fixture.
64 // This fixture should not be re-used (i.e., only one migration should be
65 // performed per test).
66 class TrackedPreferencesMigrationTest : public testing::Test {
68 enum MockPrefStoreID {
69 MOCK_UNPROTECTED_PREF_STORE,
70 MOCK_PROTECTED_PREF_STORE,
73 TrackedPreferencesMigrationTest()
74 : unprotected_prefs_(new base::DictionaryValue),
75 protected_prefs_(new base::DictionaryValue),
76 migration_modified_unprotected_store_(false),
77 migration_modified_protected_store_(false),
78 unprotected_store_migration_complete_(false),
79 protected_store_migration_complete_(false) {}
81 virtual void SetUp() OVERRIDE {
82 std::set<std::string> unprotected_pref_names;
83 std::set<std::string> protected_pref_names;
84 unprotected_pref_names.insert(kUnprotectedPref);
85 unprotected_pref_names.insert(kPreviouslyProtectedPref);
86 protected_pref_names.insert(kProtectedPref);
87 protected_pref_names.insert(kPreviouslyUnprotectedPref);
89 SetupTrackedPreferencesMigration(
90 unprotected_pref_names,
92 base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore,
93 base::Unretained(this), MOCK_UNPROTECTED_PREF_STORE),
94 base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore,
95 base::Unretained(this), MOCK_PROTECTED_PREF_STORE),
97 &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
98 base::Unretained(this), MOCK_UNPROTECTED_PREF_STORE),
100 &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
101 base::Unretained(this), MOCK_PROTECTED_PREF_STORE),
102 &mock_unprotected_pref_filter_,
103 &mock_protected_pref_filter_);
105 // Verify initial expectations are met.
106 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
107 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
109 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
111 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
113 std::vector<std::pair<std::string, std::string> > no_prefs_stored;
114 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, no_prefs_stored);
115 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, no_prefs_stored);
119 // Sets |key| to |value| in the test store identified by |store_id| before
121 void PresetStoreValue(MockPrefStoreID store_id,
122 const std::string& key,
123 const std::string value) {
124 base::DictionaryValue* store = NULL;
126 case MOCK_UNPROTECTED_PREF_STORE:
127 store = unprotected_prefs_.get();
129 case MOCK_PROTECTED_PREF_STORE:
130 store = protected_prefs_.get();
135 store->SetString(key, value);
138 // Returns true if the store opposite to |store_id| is observed for its next
140 bool WasOnSuccessfulWriteCallbackRegistered(MockPrefStoreID store_id) {
142 case MOCK_UNPROTECTED_PREF_STORE:
143 return !protected_store_successful_write_callback_.is_null();
144 case MOCK_PROTECTED_PREF_STORE:
145 return !unprotected_store_successful_write_callback_.is_null();
151 // Verifies that the (key, value) pairs in |expected_prefs_in_store| are found
152 // in the store identified by |store_id|.
153 void VerifyValuesStored(
154 MockPrefStoreID store_id,
155 const std::vector<std::pair<std::string, std::string> >&
156 expected_prefs_in_store) {
157 base::DictionaryValue* store = NULL;
159 case MOCK_UNPROTECTED_PREF_STORE:
160 store = unprotected_prefs_.get();
162 case MOCK_PROTECTED_PREF_STORE:
163 store = protected_prefs_.get();
168 for (std::vector<std::pair<std::string, std::string> >::const_iterator it =
169 expected_prefs_in_store.begin();
170 it != expected_prefs_in_store.end(); ++it) {
172 EXPECT_TRUE(store->GetString(it->first, &val));
173 EXPECT_EQ(it->second, val);
177 // Both stores need to hand their prefs over in order for migration to kick
179 void HandPrefsToMigrator(MockPrefStoreID store_id) {
181 case MOCK_UNPROTECTED_PREF_STORE:
182 mock_unprotected_pref_filter_.FilterOnLoad(
183 base::Bind(&TrackedPreferencesMigrationTest::GetPrefsBack,
184 base::Unretained(this),
185 MOCK_UNPROTECTED_PREF_STORE),
186 unprotected_prefs_.Pass());
188 case MOCK_PROTECTED_PREF_STORE:
189 mock_protected_pref_filter_.FilterOnLoad(
190 base::Bind(&TrackedPreferencesMigrationTest::GetPrefsBack,
191 base::Unretained(this),
192 MOCK_PROTECTED_PREF_STORE),
193 protected_prefs_.Pass());
198 bool HasPrefs(MockPrefStoreID store_id) {
200 case MOCK_UNPROTECTED_PREF_STORE:
201 return unprotected_prefs_;
202 case MOCK_PROTECTED_PREF_STORE:
203 return protected_prefs_;
209 bool StoreModifiedByMigration(MockPrefStoreID store_id) {
211 case MOCK_UNPROTECTED_PREF_STORE:
212 return migration_modified_unprotected_store_;
213 case MOCK_PROTECTED_PREF_STORE:
214 return migration_modified_protected_store_;
220 bool MigrationCompleted() {
221 return unprotected_store_migration_complete_ &&
222 protected_store_migration_complete_;
225 void SimulateSuccessfulWrite(MockPrefStoreID store_id) {
227 case MOCK_UNPROTECTED_PREF_STORE:
228 EXPECT_FALSE(unprotected_store_successful_write_callback_.is_null());
229 unprotected_store_successful_write_callback_.Run();
230 unprotected_store_successful_write_callback_.Reset();
232 case MOCK_PROTECTED_PREF_STORE:
233 EXPECT_FALSE(protected_store_successful_write_callback_.is_null());
234 protected_store_successful_write_callback_.Run();
235 protected_store_successful_write_callback_.Reset();
241 void RegisterSuccessfulWriteClosure(
242 MockPrefStoreID store_id,
243 const base::Closure& successful_write_closure) {
245 case MOCK_UNPROTECTED_PREF_STORE:
246 EXPECT_TRUE(unprotected_store_successful_write_callback_.is_null());
247 unprotected_store_successful_write_callback_ = successful_write_closure;
249 case MOCK_PROTECTED_PREF_STORE:
250 EXPECT_TRUE(protected_store_successful_write_callback_.is_null());
251 protected_store_successful_write_callback_ = successful_write_closure;
256 // Helper given as an InterceptablePrefFilter::FinalizeFilterOnLoadCallback
257 // to the migrator to be invoked when it's done.
258 void GetPrefsBack(MockPrefStoreID store_id,
259 scoped_ptr<base::DictionaryValue> prefs,
260 bool prefs_altered) {
262 case MOCK_UNPROTECTED_PREF_STORE:
263 EXPECT_FALSE(unprotected_prefs_);
264 unprotected_prefs_ = prefs.Pass();
265 migration_modified_unprotected_store_ = prefs_altered;
266 unprotected_store_migration_complete_ = true;
268 case MOCK_PROTECTED_PREF_STORE:
269 EXPECT_FALSE(protected_prefs_);
270 protected_prefs_ = prefs.Pass();
271 migration_modified_protected_store_ = prefs_altered;
272 protected_store_migration_complete_ = true;
277 // Helper given as a cleaning callback to the migrator.
278 void RemovePathFromStore(MockPrefStoreID store_id, const std::string& key) {
280 case MOCK_UNPROTECTED_PREF_STORE:
281 ASSERT_TRUE(unprotected_prefs_);
282 unprotected_prefs_->RemovePath(key, NULL);
284 case MOCK_PROTECTED_PREF_STORE:
285 ASSERT_TRUE(protected_prefs_);
286 protected_prefs_->RemovePath(key, NULL);
291 scoped_ptr<base::DictionaryValue> unprotected_prefs_;
292 scoped_ptr<base::DictionaryValue> protected_prefs_;
294 SimpleInterceptablePrefFilter mock_unprotected_pref_filter_;
295 SimpleInterceptablePrefFilter mock_protected_pref_filter_;
297 base::Closure unprotected_store_successful_write_callback_;
298 base::Closure protected_store_successful_write_callback_;
300 bool migration_modified_unprotected_store_;
301 bool migration_modified_protected_store_;
303 bool unprotected_store_migration_complete_;
304 bool protected_store_migration_complete_;
309 TEST_F(TrackedPreferencesMigrationTest, NoMigrationRequired) {
310 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref,
311 kUnprotectedPrefValue);
312 PresetStoreValue(MOCK_PROTECTED_PREF_STORE, kProtectedPref,
313 kProtectedPrefValue);
315 // Hand unprotected prefs to the migrator which should wait for the protected
317 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
318 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
319 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
320 EXPECT_FALSE(MigrationCompleted());
322 // Hand protected prefs to the migrator which should proceed with the
323 // migration synchronously.
324 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
325 EXPECT_TRUE(MigrationCompleted());
327 // Prefs should have been handed back over.
328 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
329 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
331 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
333 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
334 EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
335 EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
337 std::vector<std::pair<std::string, std::string> > expected_unprotected_values;
338 expected_unprotected_values.push_back(
339 std::make_pair(kUnprotectedPref, kUnprotectedPrefValue));
340 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values);
342 std::vector<std::pair<std::string, std::string> > expected_protected_values;
343 expected_protected_values.push_back(
344 std::make_pair(kProtectedPref, kProtectedPrefValue));
345 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
348 TEST_F(TrackedPreferencesMigrationTest, FullMigration) {
350 MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
351 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
352 kPreviouslyUnprotectedPref,
353 kPreviouslyUnprotectedPrefValue);
355 MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
356 PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
357 kPreviouslyProtectedPref,
358 kPreviouslyProtectedPrefValue);
360 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
361 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
362 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
363 EXPECT_FALSE(MigrationCompleted());
365 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
366 EXPECT_TRUE(MigrationCompleted());
368 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
369 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
371 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
373 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
374 EXPECT_TRUE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
375 EXPECT_TRUE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
377 // Values should have been migrated to their store, but migrated values should
378 // still remain in the source store until cleanup tasks are later invoked.
380 std::vector<std::pair<std::string, std::string> >
381 expected_unprotected_values;
382 expected_unprotected_values.push_back(std::make_pair(
383 kUnprotectedPref, kUnprotectedPrefValue));
384 expected_unprotected_values.push_back(std::make_pair(
385 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
386 expected_unprotected_values.push_back(std::make_pair(
387 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
388 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
389 expected_unprotected_values);
391 std::vector<std::pair<std::string, std::string> > expected_protected_values;
392 expected_protected_values.push_back(std::make_pair(
393 kProtectedPref, kProtectedPrefValue));
394 expected_protected_values.push_back(std::make_pair(
395 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
396 expected_unprotected_values.push_back(std::make_pair(
397 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
398 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
401 // A successful write of the protected pref store should result in a clean up
402 // of the unprotected store.
403 SimulateSuccessfulWrite(MOCK_PROTECTED_PREF_STORE);
406 std::vector<std::pair<std::string, std::string> >
407 expected_unprotected_values;
408 expected_unprotected_values.push_back(std::make_pair(
409 kUnprotectedPref, kUnprotectedPrefValue));
410 expected_unprotected_values.push_back(std::make_pair(
411 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
412 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
413 expected_unprotected_values);
415 std::vector<std::pair<std::string, std::string> > expected_protected_values;
416 expected_protected_values.push_back(std::make_pair(
417 kProtectedPref, kProtectedPrefValue));
418 expected_protected_values.push_back(std::make_pair(
419 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
420 expected_unprotected_values.push_back(std::make_pair(
421 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
422 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
425 SimulateSuccessfulWrite(MOCK_UNPROTECTED_PREF_STORE);
428 std::vector<std::pair<std::string, std::string> >
429 expected_unprotected_values;
430 expected_unprotected_values.push_back(std::make_pair(
431 kUnprotectedPref, kUnprotectedPrefValue));
432 expected_unprotected_values.push_back(std::make_pair(
433 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
434 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
435 expected_unprotected_values);
437 std::vector<std::pair<std::string, std::string> > expected_protected_values;
438 expected_protected_values.push_back(std::make_pair(
439 kProtectedPref, kProtectedPrefValue));
440 expected_protected_values.push_back(std::make_pair(
441 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
442 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
446 TEST_F(TrackedPreferencesMigrationTest, CleanupOnly) {
447 // Already migrated; only cleanup needed.
449 MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
450 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
451 kPreviouslyProtectedPref,
452 kPreviouslyProtectedPrefValue);
453 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
454 kPreviouslyUnprotectedPref,
455 kPreviouslyUnprotectedPrefValue);
457 MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
458 PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
459 kPreviouslyProtectedPref,
460 kPreviouslyProtectedPrefValue);
461 PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
462 kPreviouslyUnprotectedPref,
463 kPreviouslyUnprotectedPrefValue);
465 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
466 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
467 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
468 EXPECT_FALSE(MigrationCompleted());
470 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
471 EXPECT_TRUE(MigrationCompleted());
473 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
474 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
476 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
478 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
479 EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
480 EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
482 // Cleanup should happen synchronously if the values were already present in
483 // their destination stores.
485 std::vector<std::pair<std::string, std::string> >
486 expected_unprotected_values;
487 expected_unprotected_values.push_back(std::make_pair(
488 kUnprotectedPref, kUnprotectedPrefValue));
489 expected_unprotected_values.push_back(std::make_pair(
490 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
491 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
492 expected_unprotected_values);
494 std::vector<std::pair<std::string, std::string> > expected_protected_values;
495 expected_protected_values.push_back(std::make_pair(
496 kProtectedPref, kProtectedPrefValue));
497 expected_protected_values.push_back(std::make_pair(
498 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
499 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);