Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefs / profile_pref_store_manager_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/profile_pref_store_manager.h"
6
7 #include <vector>
8
9 #include "base/compiler_specific.h"
10 #include "base/files/file_enumerator.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/prefs/json_pref_store.h"
17 #include "base/prefs/persistent_pref_store.h"
18 #include "base/prefs/pref_service.h"
19 #include "base/prefs/pref_service_factory.h"
20 #include "base/prefs/pref_store.h"
21 #include "base/prefs/testing_pref_service.h"
22 #include "base/run_loop.h"
23 #include "base/strings/string_util.h"
24 #include "base/values.h"
25 #include "chrome/browser/prefs/tracked/mock_validation_delegate.h"
26 #include "chrome/browser/prefs/tracked/pref_hash_filter.h"
27 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h"
28 #include "chrome/common/pref_names.h"
29 #include "components/pref_registry/pref_registry_syncable.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 namespace {
33
34 class FirstEqualsPredicate {
35  public:
36   explicit FirstEqualsPredicate(const std::string& expected)
37       : expected_(expected) {}
38   bool operator()(const std::pair<std::string, base::Value*>& pair) {
39     return pair.first == expected_;
40   }
41
42  private:
43   const std::string expected_;
44 };
45
46 // Observes changes to the PrefStore and verifies that only registered prefs are
47 // written.
48 class RegistryVerifier : public PrefStore::Observer {
49  public:
50   explicit RegistryVerifier(PrefRegistry* pref_registry)
51       : pref_registry_(pref_registry) {}
52
53   // PrefStore::Observer implementation
54   void OnPrefValueChanged(const std::string& key) override {
55     EXPECT_TRUE(pref_registry_->end() !=
56                 std::find_if(pref_registry_->begin(),
57                              pref_registry_->end(),
58                              FirstEqualsPredicate(key)))
59         << "Unregistered key " << key << " was changed.";
60   }
61
62   void OnInitializationCompleted(bool succeeded) override {}
63
64  private:
65   scoped_refptr<PrefRegistry> pref_registry_;
66 };
67
68 const char kUnprotectedPref[] = "unprotected_pref";
69 const char kTrackedAtomic[] = "tracked_atomic";
70 const char kProtectedAtomic[] = "protected_atomic";
71
72 const char kFoobar[] = "FOOBAR";
73 const char kBarfoo[] = "BARFOO";
74 const char kHelloWorld[] = "HELLOWORLD";
75 const char kGoodbyeWorld[] = "GOODBYEWORLD";
76
77 const PrefHashFilter::TrackedPreferenceMetadata kConfiguration[] = {
78     {0u, kTrackedAtomic, PrefHashFilter::NO_ENFORCEMENT,
79      PrefHashFilter::TRACKING_STRATEGY_ATOMIC},
80     {1u, kProtectedAtomic, PrefHashFilter::ENFORCE_ON_LOAD,
81      PrefHashFilter::TRACKING_STRATEGY_ATOMIC}};
82
83 const size_t kExtraReportingId = 2u;
84 const size_t kReportingIdCount = 3u;
85
86 }  // namespace
87
88 class ProfilePrefStoreManagerTest : public testing::Test {
89  public:
90   ProfilePrefStoreManagerTest()
91       : configuration_(kConfiguration,
92                        kConfiguration + arraysize(kConfiguration)),
93         profile_pref_registry_(new user_prefs::PrefRegistrySyncable),
94         registry_verifier_(profile_pref_registry_.get()),
95         seed_("seed"),
96         reset_recorded_(false) {}
97
98   void SetUp() override {
99     ProfilePrefStoreManager::RegisterPrefs(local_state_.registry());
100     ProfilePrefStoreManager::RegisterProfilePrefs(profile_pref_registry_.get());
101     for (const PrefHashFilter::TrackedPreferenceMetadata* it = kConfiguration;
102          it != kConfiguration + arraysize(kConfiguration);
103          ++it) {
104       if (it->strategy == PrefHashFilter::TRACKING_STRATEGY_ATOMIC) {
105         profile_pref_registry_->RegisterStringPref(
106             it->name,
107             std::string(),
108             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
109       } else {
110         profile_pref_registry_->RegisterDictionaryPref(
111             it->name, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
112       }
113     }
114     profile_pref_registry_->RegisterStringPref(
115         kUnprotectedPref,
116         std::string(),
117         user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
118
119     // As in chrome_pref_service_factory.cc, kPreferencesResetTime needs to be
120     // declared as protected in order to be read from the proper store by the
121     // SegregatedPrefStore. Only declare it after configured prefs have been
122     // registered above for this test as kPreferenceResetTime is already
123     // registered in ProfilePrefStoreManager::RegisterProfilePrefs.
124     PrefHashFilter::TrackedPreferenceMetadata pref_reset_time_config =
125         {configuration_.rbegin()->reporting_id + 1, prefs::kPreferenceResetTime,
126          PrefHashFilter::ENFORCE_ON_LOAD,
127          PrefHashFilter::TRACKING_STRATEGY_ATOMIC};
128     configuration_.push_back(pref_reset_time_config);
129
130     ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
131     ReloadConfiguration();
132   }
133
134   void ReloadConfiguration() {
135     manager_.reset(new ProfilePrefStoreManager(profile_dir_.path(),
136                                                configuration_,
137                                                kReportingIdCount,
138                                                seed_,
139                                                "device_id",
140                                                &local_state_));
141   }
142
143   void TearDown() override { DestroyPrefStore(); }
144
145  protected:
146   // Verifies whether a reset was reported via the RecordReset() hook. Also
147   // verifies that GetResetTime() was set (or not) accordingly.
148   void VerifyResetRecorded(bool reset_expected) {
149     EXPECT_EQ(reset_expected, reset_recorded_);
150
151     base::PrefServiceFactory pref_service_factory;
152     pref_service_factory.set_user_prefs(pref_store_);
153
154     scoped_ptr<PrefService> pref_service(
155         pref_service_factory.Create(profile_pref_registry_.get()));
156
157     EXPECT_EQ(
158         reset_expected,
159         !ProfilePrefStoreManager::GetResetTime(pref_service.get()).is_null());
160   }
161
162   void ClearResetRecorded() {
163     reset_recorded_ = false;
164
165     base::PrefServiceFactory pref_service_factory;
166     pref_service_factory.set_user_prefs(pref_store_);
167
168     scoped_ptr<PrefService> pref_service(
169         pref_service_factory.Create(profile_pref_registry_.get()));
170
171     ProfilePrefStoreManager::ClearResetTime(pref_service.get());
172   }
173
174   void InitializePrefs() {
175     // According to the implementation of ProfilePrefStoreManager, this is
176     // actually a SegregatedPrefStore backed by two underlying pref stores.
177     scoped_refptr<PersistentPrefStore> pref_store =
178         manager_->CreateProfilePrefStore(
179             main_message_loop_.message_loop_proxy(),
180             base::Bind(&ProfilePrefStoreManagerTest::RecordReset,
181                        base::Unretained(this)),
182             &mock_validation_delegate_);
183     InitializePrefStore(pref_store.get());
184     pref_store = NULL;
185     base::RunLoop().RunUntilIdle();
186   }
187
188   void DestroyPrefStore() {
189     if (pref_store_.get()) {
190       ClearResetRecorded();
191       // Force everything to be written to disk, triggering the PrefHashFilter
192       // while our RegistryVerifier is watching.
193       pref_store_->CommitPendingWrite();
194       base::RunLoop().RunUntilIdle();
195
196       pref_store_->RemoveObserver(&registry_verifier_);
197       pref_store_ = NULL;
198       // Nothing should have to happen on the background threads, but just in
199       // case...
200       base::RunLoop().RunUntilIdle();
201     }
202   }
203
204   void InitializeDeprecatedCombinedProfilePrefStore() {
205     scoped_refptr<PersistentPrefStore> pref_store =
206         manager_->CreateDeprecatedCombinedProfilePrefStore(
207             main_message_loop_.message_loop_proxy());
208     InitializePrefStore(pref_store.get());
209     pref_store = NULL;
210     base::RunLoop().RunUntilIdle();
211   }
212
213   void InitializePrefStore(PersistentPrefStore* pref_store) {
214     pref_store->AddObserver(&registry_verifier_);
215     PersistentPrefStore::PrefReadError error = pref_store->ReadPrefs();
216     EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, error);
217     pref_store->SetValue(kTrackedAtomic, new base::StringValue(kFoobar));
218     pref_store->SetValue(kProtectedAtomic, new base::StringValue(kHelloWorld));
219     pref_store->SetValue(kUnprotectedPref, new base::StringValue(kFoobar));
220     pref_store->RemoveObserver(&registry_verifier_);
221     pref_store->CommitPendingWrite();
222     base::RunLoop().RunUntilIdle();
223   }
224
225   void LoadExistingPrefs() {
226     DestroyPrefStore();
227     pref_store_ = manager_->CreateProfilePrefStore(
228         main_message_loop_.message_loop_proxy(),
229         base::Bind(&ProfilePrefStoreManagerTest::RecordReset,
230                    base::Unretained(this)),
231         NULL);
232     pref_store_->AddObserver(&registry_verifier_);
233     pref_store_->ReadPrefs();
234   }
235
236   void ReplaceStringInPrefs(const std::string& find,
237                             const std::string& replace) {
238     base::FileEnumerator file_enum(
239         profile_dir_.path(), true, base::FileEnumerator::FILES);
240
241     for (base::FilePath path = file_enum.Next(); !path.empty();
242          path = file_enum.Next()) {
243       // Tamper with the file's contents
244       std::string contents;
245       EXPECT_TRUE(base::ReadFileToString(path, &contents));
246       ReplaceSubstringsAfterOffset(&contents, 0u, find, replace);
247       EXPECT_EQ(static_cast<int>(contents.length()),
248                 base::WriteFile(path, contents.c_str(), contents.length()));
249     }
250   }
251
252   void ExpectStringValueEquals(const std::string& name,
253                                const std::string& expected) {
254     const base::Value* value = NULL;
255     std::string as_string;
256     if (!pref_store_->GetValue(name, &value)) {
257       ADD_FAILURE() << name << " is not a defined value.";
258     } else if (!value->GetAsString(&as_string)) {
259       ADD_FAILURE() << name << " could not be coerced to a string.";
260     } else {
261       EXPECT_EQ(expected, as_string);
262     }
263   }
264
265   void ExpectValidationObserved(const std::string& pref_path) {
266     // No validations are expected for platforms that do not support tracking.
267     if (!ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking)
268       return;
269     if (!mock_validation_delegate_.GetEventForPath(pref_path))
270       ADD_FAILURE() << "No validation observed for preference: " << pref_path;
271   }
272
273   base::MessageLoop main_message_loop_;
274   std::vector<PrefHashFilter::TrackedPreferenceMetadata> configuration_;
275   base::ScopedTempDir profile_dir_;
276   TestingPrefServiceSimple local_state_;
277   scoped_refptr<user_prefs::PrefRegistrySyncable> profile_pref_registry_;
278   RegistryVerifier registry_verifier_;
279   MockValidationDelegate mock_validation_delegate_;
280   scoped_ptr<ProfilePrefStoreManager> manager_;
281   scoped_refptr<PersistentPrefStore> pref_store_;
282
283   std::string seed_;
284
285  private:
286   void RecordReset() {
287     // As-is |reset_recorded_| is only designed to remember a single reset, make
288     // sure none was previously recorded (or that ClearResetRecorded() was
289     // called).
290     EXPECT_FALSE(reset_recorded_);
291     reset_recorded_ = true;
292   }
293
294   bool reset_recorded_;
295 };
296
297 TEST_F(ProfilePrefStoreManagerTest, StoreValues) {
298   InitializePrefs();
299
300   LoadExistingPrefs();
301
302   ExpectStringValueEquals(kTrackedAtomic, kFoobar);
303   ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
304   VerifyResetRecorded(false);
305   ExpectValidationObserved(kTrackedAtomic);
306   ExpectValidationObserved(kProtectedAtomic);
307 }
308
309 TEST_F(ProfilePrefStoreManagerTest, GetPrefFilePathFromProfilePath) {
310   base::FilePath pref_file_path =
311       ProfilePrefStoreManager::GetPrefFilePathFromProfilePath(
312           profile_dir_.path());
313
314   EXPECT_FALSE(base::PathExists(pref_file_path));
315
316   InitializePrefs();
317
318   EXPECT_TRUE(base::PathExists(pref_file_path));
319 }
320
321 TEST_F(ProfilePrefStoreManagerTest, ProtectValues) {
322   InitializePrefs();
323
324   ReplaceStringInPrefs(kFoobar, kBarfoo);
325   ReplaceStringInPrefs(kHelloWorld, kGoodbyeWorld);
326
327   LoadExistingPrefs();
328
329   // kTrackedAtomic is unprotected and thus will be loaded as it appears on
330   // disk.
331   ExpectStringValueEquals(kTrackedAtomic, kBarfoo);
332
333   // If preference tracking is supported, the tampered value of kProtectedAtomic
334   // will be discarded at load time, leaving this preference undefined.
335   EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
336             pref_store_->GetValue(kProtectedAtomic, NULL));
337   VerifyResetRecorded(
338       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
339
340   ExpectValidationObserved(kTrackedAtomic);
341   ExpectValidationObserved(kProtectedAtomic);
342 }
343
344 TEST_F(ProfilePrefStoreManagerTest, MigrateFromOneFile) {
345   InitializeDeprecatedCombinedProfilePrefStore();
346
347   // The deprecated model stores hashes in local state (on supported
348   // platforms)..
349   ASSERT_EQ(
350       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
351       local_state_.GetUserPrefValue(
352           PrefServiceHashStoreContents::kProfilePreferenceHashes) != NULL);
353
354   LoadExistingPrefs();
355
356   // After a first migration, the hashes were copied to the two user preference
357   // files but were not cleaned.
358   ASSERT_EQ(
359       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
360       local_state_.GetUserPrefValue(
361           PrefServiceHashStoreContents::kProfilePreferenceHashes) != NULL);
362
363   ExpectStringValueEquals(kTrackedAtomic, kFoobar);
364   ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
365   VerifyResetRecorded(false);
366
367   LoadExistingPrefs();
368
369   // In a subsequent launch, the local state hash store should be reset.
370   ASSERT_FALSE(local_state_.GetUserPrefValue(
371       PrefServiceHashStoreContents::kProfilePreferenceHashes));
372
373   ExpectStringValueEquals(kTrackedAtomic, kFoobar);
374   ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
375   VerifyResetRecorded(false);
376 }
377
378 TEST_F(ProfilePrefStoreManagerTest, MigrateWithTampering) {
379   InitializeDeprecatedCombinedProfilePrefStore();
380
381   ReplaceStringInPrefs(kFoobar, kBarfoo);
382   ReplaceStringInPrefs(kHelloWorld, kGoodbyeWorld);
383
384   // The deprecated model stores hashes in local state (on supported
385   // platforms)..
386   ASSERT_EQ(
387       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
388       local_state_.GetUserPrefValue(
389           PrefServiceHashStoreContents::kProfilePreferenceHashes) != NULL);
390
391   LoadExistingPrefs();
392
393   // After a first migration, the hashes were copied to the two user preference
394   // files but were not cleaned.
395   ASSERT_EQ(
396       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
397       local_state_.GetUserPrefValue(
398           PrefServiceHashStoreContents::kProfilePreferenceHashes) != NULL);
399
400   // kTrackedAtomic is unprotected and thus will be loaded as it appears on
401   // disk.
402   ExpectStringValueEquals(kTrackedAtomic, kBarfoo);
403
404   // If preference tracking is supported, the tampered value of kProtectedAtomic
405   // will be discarded at load time, leaving this preference undefined.
406   EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
407             pref_store_->GetValue(kProtectedAtomic, NULL));
408   VerifyResetRecorded(
409       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
410
411   LoadExistingPrefs();
412
413   // In a subsequent launch, the local state hash store would be reset.
414   ASSERT_FALSE(local_state_.GetUserPrefValue(
415       PrefServiceHashStoreContents::kProfilePreferenceHashes));
416
417   ExpectStringValueEquals(kTrackedAtomic, kBarfoo);
418   VerifyResetRecorded(false);
419 }
420
421 TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) {
422   base::DictionaryValue master_prefs;
423   master_prefs.Set(kTrackedAtomic, new base::StringValue(kFoobar));
424   master_prefs.Set(kProtectedAtomic, new base::StringValue(kHelloWorld));
425   EXPECT_TRUE(manager_->InitializePrefsFromMasterPrefs(master_prefs));
426
427   LoadExistingPrefs();
428
429   // Verify that InitializePrefsFromMasterPrefs correctly applied the MACs
430   // necessary to authenticate these values.
431   ExpectStringValueEquals(kTrackedAtomic, kFoobar);
432   ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
433   VerifyResetRecorded(false);
434 }
435
436 TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtected) {
437   InitializePrefs();
438
439   ExpectValidationObserved(kTrackedAtomic);
440   ExpectValidationObserved(kProtectedAtomic);
441
442   LoadExistingPrefs();
443   ExpectStringValueEquals(kUnprotectedPref, kFoobar);
444
445   // Ensure everything is written out to disk.
446   DestroyPrefStore();
447
448   ReplaceStringInPrefs(kFoobar, kBarfoo);
449
450   // It's unprotected, so we can load the modified value.
451   LoadExistingPrefs();
452   ExpectStringValueEquals(kUnprotectedPref, kBarfoo);
453
454   // Now update the configuration to protect it.
455   PrefHashFilter::TrackedPreferenceMetadata new_protected = {
456       kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD,
457       PrefHashFilter::TRACKING_STRATEGY_ATOMIC};
458   configuration_.push_back(new_protected);
459   ReloadConfiguration();
460
461   // And try loading with the new configuration.
462   LoadExistingPrefs();
463
464   // Since there was a valid super MAC we were able to extend the existing trust
465   // to the newly protected preference.
466   ExpectStringValueEquals(kUnprotectedPref, kBarfoo);
467   VerifyResetRecorded(false);
468
469   // Ensure everything is written out to disk.
470   DestroyPrefStore();
471
472   // It's protected now, so (if the platform supports it) any tampering should
473   // lead to a reset.
474   ReplaceStringInPrefs(kBarfoo, kFoobar);
475   LoadExistingPrefs();
476   EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
477             pref_store_->GetValue(kUnprotectedPref, NULL));
478   VerifyResetRecorded(
479       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
480 }
481
482 TEST_F(ProfilePrefStoreManagerTest, NewPrefWhenFirstProtecting) {
483   std::vector<PrefHashFilter::TrackedPreferenceMetadata>
484       original_configuration = configuration_;
485   for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it =
486            configuration_.begin();
487        it != configuration_.end();
488        ++it) {
489     it->enforcement_level = PrefHashFilter::NO_ENFORCEMENT;
490   }
491   ReloadConfiguration();
492
493   InitializePrefs();
494
495   ExpectValidationObserved(kTrackedAtomic);
496   ExpectValidationObserved(kProtectedAtomic);
497
498   LoadExistingPrefs();
499   ExpectStringValueEquals(kUnprotectedPref, kFoobar);
500
501   // Ensure everything is written out to disk.
502   DestroyPrefStore();
503
504   // Now introduce protection, including the never-before tracked "new_pref".
505   configuration_ = original_configuration;
506   PrefHashFilter::TrackedPreferenceMetadata new_protected = {
507       kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD,
508       PrefHashFilter::TRACKING_STRATEGY_ATOMIC};
509   configuration_.push_back(new_protected);
510   ReloadConfiguration();
511
512   // And try loading with the new configuration.
513   LoadExistingPrefs();
514
515   // Since there was a valid super MAC we were able to extend the existing trust
516   // to the newly tracked & protected preference.
517   ExpectStringValueEquals(kUnprotectedPref, kFoobar);
518   VerifyResetRecorded(false);
519 }
520
521 TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) {
522   InitializePrefs();
523
524   ExpectValidationObserved(kTrackedAtomic);
525   ExpectValidationObserved(kProtectedAtomic);
526
527   // Now update the configuration to protect it.
528   PrefHashFilter::TrackedPreferenceMetadata new_protected = {
529       kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD,
530       PrefHashFilter::TRACKING_STRATEGY_ATOMIC};
531   configuration_.push_back(new_protected);
532   seed_ = "new-seed-to-break-trust";
533   ReloadConfiguration();
534
535   // And try loading with the new configuration.
536   LoadExistingPrefs();
537
538   // If preference tracking is supported, kUnprotectedPref will have been
539   // discarded because new values are not accepted without a valid super MAC.
540   EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
541             pref_store_->GetValue(kUnprotectedPref, NULL));
542   VerifyResetRecorded(
543       ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
544 }
545
546 // This test verifies that preference values are correctly maintained when a
547 // preference's protection state changes from protected to unprotected.
548 TEST_F(ProfilePrefStoreManagerTest, ProtectedToUnprotected) {
549   InitializePrefs();
550
551   ExpectValidationObserved(kTrackedAtomic);
552   ExpectValidationObserved(kProtectedAtomic);
553
554   DestroyPrefStore();
555
556   // Unconfigure protection for kProtectedAtomic
557   for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it =
558            configuration_.begin();
559        it != configuration_.end();
560        ++it) {
561     if (it->name == kProtectedAtomic) {
562       it->enforcement_level = PrefHashFilter::NO_ENFORCEMENT;
563       break;
564     }
565   }
566
567   seed_ = "new-seed-to-break-trust";
568   ReloadConfiguration();
569   LoadExistingPrefs();
570
571   // Verify that the value was not reset.
572   ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
573   VerifyResetRecorded(false);
574
575   // Accessing the value of the previously protected pref didn't trigger its
576   // move to the unprotected preferences file, though the loading of the pref
577   // store should still have caused the MAC store to be recalculated.
578   LoadExistingPrefs();
579   ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
580
581   // Trigger the logic that migrates it back to the unprotected preferences
582   // file.
583   pref_store_->SetValue(kProtectedAtomic, new base::StringValue(kGoodbyeWorld));
584   LoadExistingPrefs();
585   ExpectStringValueEquals(kProtectedAtomic, kGoodbyeWorld);
586   VerifyResetRecorded(false);
587 }