Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefs / tracked / tracked_preferences_migration_unittest.cc
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.
4
5 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h"
6
7 #include <set>
8 #include <string>
9 #include <vector>
10
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"
18
19 namespace {
20
21 // An unprotected pref.
22 const char kUnprotectedPref[] = "unprotected";
23 // A protected pref.
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";
29
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";
34
35 // A simple InterceptablePrefFilter which doesn't do anything but hand the prefs
36 // back downstream in FinalizeFilterOnLoad.
37 class SimpleInterceptablePrefFilter : public InterceptablePrefFilter {
38  public:
39   // PrefFilter remaining implementation.
40   virtual void FilterUpdate(const std::string& path) OVERRIDE {
41     ADD_FAILURE();
42   }
43   virtual void FilterSerializeData(
44       const base::DictionaryValue* pref_store_contents) OVERRIDE {
45     ADD_FAILURE();
46   }
47
48  private:
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);
55   }
56 };
57
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
62 //     over.
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 {
67  public:
68   enum MockPrefStoreID {
69     MOCK_UNPROTECTED_PREF_STORE,
70     MOCK_PROTECTED_PREF_STORE,
71   };
72
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) {}
80
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);
88
89     SetupTrackedPreferencesMigration(
90         unprotected_pref_names,
91         protected_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),
96         base::Bind(
97             &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
98             base::Unretained(this), MOCK_UNPROTECTED_PREF_STORE),
99         base::Bind(
100             &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
101             base::Unretained(this), MOCK_PROTECTED_PREF_STORE),
102         &mock_unprotected_pref_filter_,
103         &mock_protected_pref_filter_);
104
105     // Verify initial expectations are met.
106     EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
107     EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
108     EXPECT_FALSE(
109         WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
110     EXPECT_FALSE(
111         WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
112
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);
116   }
117
118  protected:
119   // Sets |key| to |value| in the test store identified by |store_id| before
120   // migration begins.
121   void PresetStoreValue(MockPrefStoreID store_id,
122                         const std::string& key,
123                         const std::string value) {
124     base::DictionaryValue* store = NULL;
125     switch (store_id) {
126       case MOCK_UNPROTECTED_PREF_STORE:
127         store = unprotected_prefs_.get();
128         break;
129       case MOCK_PROTECTED_PREF_STORE:
130         store = protected_prefs_.get();
131         break;
132     }
133     DCHECK(store);
134
135     store->SetString(key, value);
136   }
137
138   // Returns true if the store opposite to |store_id| is observed for its next
139   // successful write.
140   bool WasOnSuccessfulWriteCallbackRegistered(MockPrefStoreID store_id) {
141     switch (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();
146     }
147     NOTREACHED();
148     return false;
149   }
150
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;
158     switch (store_id) {
159       case MOCK_UNPROTECTED_PREF_STORE:
160         store = unprotected_prefs_.get();
161         break;
162       case MOCK_PROTECTED_PREF_STORE:
163         store = protected_prefs_.get();
164         break;
165     }
166     DCHECK(store);
167
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) {
171       std::string val;
172       EXPECT_TRUE(store->GetString(it->first, &val));
173       EXPECT_EQ(it->second, val);
174     }
175   }
176
177   // Both stores need to hand their prefs over in order for migration to kick
178   // in.
179   void HandPrefsToMigrator(MockPrefStoreID store_id) {
180     switch (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());
187         break;
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());
194         break;
195     }
196   }
197
198   bool HasPrefs(MockPrefStoreID store_id) {
199     switch (store_id) {
200       case MOCK_UNPROTECTED_PREF_STORE:
201         return unprotected_prefs_;
202       case MOCK_PROTECTED_PREF_STORE:
203         return protected_prefs_;
204     }
205     NOTREACHED();
206     return false;
207   }
208
209   bool StoreModifiedByMigration(MockPrefStoreID store_id) {
210     switch (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_;
215     }
216     NOTREACHED();
217     return false;
218   }
219
220   bool MigrationCompleted() {
221     return unprotected_store_migration_complete_ &&
222         protected_store_migration_complete_;
223   }
224
225   void SimulateSuccessfulWrite(MockPrefStoreID store_id) {
226     switch (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();
231         break;
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();
236         break;
237     }
238   }
239
240  private:
241   void RegisterSuccessfulWriteClosure(
242       MockPrefStoreID store_id,
243       const base::Closure& successful_write_closure) {
244     switch (store_id) {
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;
248         break;
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;
252         break;
253     }
254   }
255
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) {
261     switch (store_id) {
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;
267         break;
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;
273         break;
274     }
275   }
276
277   // Helper given as a cleaning callback to the migrator.
278   void RemovePathFromStore(MockPrefStoreID store_id, const std::string& key) {
279     switch (store_id) {
280       case MOCK_UNPROTECTED_PREF_STORE:
281         ASSERT_TRUE(unprotected_prefs_);
282         unprotected_prefs_->RemovePath(key, NULL);
283         break;
284       case MOCK_PROTECTED_PREF_STORE:
285         ASSERT_TRUE(protected_prefs_);
286         protected_prefs_->RemovePath(key, NULL);
287         break;
288     }
289   }
290
291   scoped_ptr<base::DictionaryValue> unprotected_prefs_;
292   scoped_ptr<base::DictionaryValue> protected_prefs_;
293
294   SimpleInterceptablePrefFilter mock_unprotected_pref_filter_;
295   SimpleInterceptablePrefFilter mock_protected_pref_filter_;
296
297   base::Closure unprotected_store_successful_write_callback_;
298   base::Closure protected_store_successful_write_callback_;
299
300   bool migration_modified_unprotected_store_;
301   bool migration_modified_protected_store_;
302
303   bool unprotected_store_migration_complete_;
304   bool protected_store_migration_complete_;
305 };
306
307 }  // namespace
308
309 TEST_F(TrackedPreferencesMigrationTest, NoMigrationRequired) {
310   PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref,
311                    kUnprotectedPrefValue);
312   PresetStoreValue(MOCK_PROTECTED_PREF_STORE, kProtectedPref,
313                    kProtectedPrefValue);
314
315   // Hand unprotected prefs to the migrator which should wait for the protected
316   // prefs.
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());
321
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());
326
327   // Prefs should have been handed back over.
328   EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
329   EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
330   EXPECT_FALSE(
331       WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
332   EXPECT_FALSE(
333       WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
334   EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
335   EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
336
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);
341
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);
346 }
347
348 TEST_F(TrackedPreferencesMigrationTest, FullMigration) {
349   PresetStoreValue(
350       MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
351   PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
352                    kPreviouslyUnprotectedPref,
353                    kPreviouslyUnprotectedPrefValue);
354   PresetStoreValue(
355       MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
356   PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
357                    kPreviouslyProtectedPref,
358                    kPreviouslyProtectedPrefValue);
359
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());
364
365   HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
366   EXPECT_TRUE(MigrationCompleted());
367
368   EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
369   EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
370   EXPECT_TRUE(
371       WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
372   EXPECT_TRUE(
373       WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
374   EXPECT_TRUE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
375   EXPECT_TRUE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
376
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.
379   {
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);
390
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);
399   }
400
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);
404
405   {
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);
414
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);
423   }
424
425   SimulateSuccessfulWrite(MOCK_UNPROTECTED_PREF_STORE);
426
427   {
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);
436
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);
443   }
444 }
445
446 TEST_F(TrackedPreferencesMigrationTest, CleanupOnly) {
447   // Already migrated; only cleanup needed.
448   PresetStoreValue(
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);
456   PresetStoreValue(
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);
464
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());
469
470   HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
471   EXPECT_TRUE(MigrationCompleted());
472
473   EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
474   EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
475   EXPECT_FALSE(
476       WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
477   EXPECT_FALSE(
478       WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
479   EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
480   EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
481
482   // Cleanup should happen synchronously if the values were already present in
483   // their destination stores.
484   {
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);
493
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);
500   }
501 }