Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(474)

Side by Side Diff: chrome/browser/prefs/profile_pref_store_manager_unittest.cc

Issue 205813002: Separate storage for protected preferences into Protected Preferences file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pp4_profile_pref_store
Patch Set: Pull out some changes into other CLs. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prefs/profile_pref_store_manager.h" 5 #include "chrome/browser/prefs/profile_pref_store_manager.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/files/file_enumerator.h"
11 #include "base/files/scoped_temp_dir.h" 12 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
15 #include "base/prefs/json_pref_store.h" 16 #include "base/prefs/json_pref_store.h"
16 #include "base/prefs/persistent_pref_store.h" 17 #include "base/prefs/persistent_pref_store.h"
17 #include "base/prefs/pref_service.h" 18 #include "base/prefs/pref_service.h"
18 #include "base/prefs/pref_store.h" 19 #include "base/prefs/pref_store.h"
19 #include "base/prefs/testing_pref_service.h" 20 #include "base/prefs/testing_pref_service.h"
20 #include "base/run_loop.h" 21 #include "base/run_loop.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 FirstEqualsPredicate(key))) 54 FirstEqualsPredicate(key)))
54 << "Unregistered key " << key << " was changed."; 55 << "Unregistered key " << key << " was changed.";
55 } 56 }
56 57
57 virtual void OnInitializationCompleted(bool succeeded) OVERRIDE {} 58 virtual void OnInitializationCompleted(bool succeeded) OVERRIDE {}
58 59
59 private: 60 private:
60 scoped_refptr<PrefRegistry> pref_registry_; 61 scoped_refptr<PrefRegistry> pref_registry_;
61 }; 62 };
62 63
64 const char kUnprotectedAtomic[] = "unprotected_atomic";
63 const char kTrackedAtomic[] = "tracked_atomic"; 65 const char kTrackedAtomic[] = "tracked_atomic";
64 const char kProtectedAtomic[] = "protected_atomic"; 66 const char kProtectedAtomic[] = "protected_atomic";
65 const char kProtectedSplit[] = "protected_split"; 67 const char kProtectedSplit[] = "protected_split";
66 68
67 const char kFoobar[] = "FOOBAR"; 69 const char kFoobar[] = "FOOBAR";
68 const char kBarfoo[] = "BARFOO"; 70 const char kBarfoo[] = "BARFOO";
69 const char kHelloWorld[] = "HELLOWORLD"; 71 const char kHelloWorld[] = "HELLOWORLD";
70 const char kGoodbyeWorld[] = "GOODBYEWORLD"; 72 const char kGoodbyeWorld[] = "GOODBYEWORLD";
71 73
72 const PrefHashFilter::TrackedPreferenceMetadata kConfiguration[] = { 74 const PrefHashFilter::TrackedPreferenceMetadata kConfiguration[] = {
(...skipping 21 matching lines...) Expand all
94 it != kConfiguration + arraysize(kConfiguration); 96 it != kConfiguration + arraysize(kConfiguration);
95 ++it) { 97 ++it) {
96 if (it->strategy == PrefHashFilter::TRACKING_STRATEGY_ATOMIC) { 98 if (it->strategy == PrefHashFilter::TRACKING_STRATEGY_ATOMIC) {
97 profile_pref_registry_->RegisterStringPref( 99 profile_pref_registry_->RegisterStringPref(
98 it->name, "", user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 100 it->name, "", user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
99 } else { 101 } else {
100 profile_pref_registry_->RegisterDictionaryPref( 102 profile_pref_registry_->RegisterDictionaryPref(
101 it->name, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 103 it->name, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
102 } 104 }
103 } 105 }
106 profile_pref_registry_->RegisterStringPref(
107 kUnprotectedAtomic,
108 "",
Bernhard Bauer 2014/03/26 15:05:50 Use std::string() instead of "".
erikwright (departed) 2014/03/26 21:08:12 Done.
109 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
110
104 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); 111 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
112 ReloadConfiguration();
113 }
105 114
115 void ReloadConfiguration() {
106 manager_.reset(new ProfilePrefStoreManager(profile_dir_.path(), 116 manager_.reset(new ProfilePrefStoreManager(profile_dir_.path(),
107 configuration_, 117 configuration_,
108 configuration_.size(), 118 configuration_.size(),
109 "seed", 119 "seed",
110 "device_id", 120 "device_id",
111 &local_state_)); 121 &local_state_));
112 } 122 }
113 123
114 virtual void TearDown() OVERRIDE { 124 virtual void TearDown() OVERRIDE { DestroyPrefStore(); }
125
126 protected:
127 void InitializePrefs() {
128 scoped_refptr<PersistentPrefStore> pref_store =
129 manager_->CreateProfilePrefStore(
130 main_message_loop_.message_loop_proxy());
131 InitializePrefStore(pref_store);
132 pref_store = NULL;
133 base::RunLoop().RunUntilIdle();
134 }
Bernhard Bauer 2014/03/26 15:05:50 Nit: empty line afterwards.
erikwright (departed) 2014/03/26 21:08:12 Done.
135 void DestroyPrefStore() {
115 if (pref_store_) { 136 if (pref_store_) {
116 // Force everything to be written to disk, triggering the PrefHashFilter 137 // Force everything to be written to disk, triggering the PrefHashFilter
117 // while our RegistryVerifier is watching. 138 // while our RegistryVerifier is watching.
118 pref_store_->CommitPendingWrite(); 139 pref_store_->CommitPendingWrite();
119 base::RunLoop().RunUntilIdle(); 140 base::RunLoop().RunUntilIdle();
120 141
121 pref_store_->RemoveObserver(&registry_verifier_); 142 pref_store_->RemoveObserver(&registry_verifier_);
122 pref_store_ = NULL; 143 pref_store_ = NULL;
123 // Nothing should have to happen on the background threads, but just in 144 // Nothing should have to happen on the background threads, but just in
124 // case... 145 // case...
125 base::RunLoop().RunUntilIdle(); 146 base::RunLoop().RunUntilIdle();
126 } 147 }
127 } 148 }
128 149
129 protected: 150 void InitializeDeprecatedCombinedProfilePrefStore() {
130 void InitializePrefs() {
131 scoped_refptr<PersistentPrefStore> pref_store = 151 scoped_refptr<PersistentPrefStore> pref_store =
132 manager_->CreateProfilePrefStore( 152 manager_->CreateDeprecatedCombinedProfilePrefStore(
133 main_message_loop_.message_loop_proxy()); 153 main_message_loop_.message_loop_proxy());
154 InitializePrefStore(pref_store);
155 pref_store = NULL;
156 base::RunLoop().RunUntilIdle();
157 }
158
159 void InitializePrefStore(PersistentPrefStore* pref_store) {
134 pref_store->AddObserver(&registry_verifier_); 160 pref_store->AddObserver(&registry_verifier_);
135 PersistentPrefStore::PrefReadError error = pref_store->ReadPrefs(); 161 PersistentPrefStore::PrefReadError error = pref_store->ReadPrefs();
136 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, error); 162 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, error);
137 pref_store->SetValue(kTrackedAtomic, new base::StringValue(kFoobar)); 163 pref_store->SetValue(kTrackedAtomic, new base::StringValue(kFoobar));
138 pref_store->SetValue(kProtectedAtomic, new base::StringValue(kHelloWorld)); 164 pref_store->SetValue(kProtectedAtomic, new base::StringValue(kHelloWorld));
165 pref_store->SetValue(kUnprotectedAtomic, new base::StringValue(kFoobar));
139 pref_store->RemoveObserver(&registry_verifier_); 166 pref_store->RemoveObserver(&registry_verifier_);
140 pref_store = NULL; 167 pref_store->CommitPendingWrite();
141 base::RunLoop().RunUntilIdle(); 168 base::RunLoop().RunUntilIdle();
142 } 169 }
143 170
144 void LoadExistingPrefs() { 171 void LoadExistingPrefs() {
172 DestroyPrefStore();
145 pref_store_ = manager_->CreateProfilePrefStore( 173 pref_store_ = manager_->CreateProfilePrefStore(
146 main_message_loop_.message_loop_proxy()); 174 main_message_loop_.message_loop_proxy());
147 pref_store_->AddObserver(&registry_verifier_); 175 pref_store_->AddObserver(&registry_verifier_);
148 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 176 pref_store_->ReadPrefs();
149 pref_store_->ReadPrefs());
150 } 177 }
151 178
152 void ReplaceStringInPrefs(const std::string& find, 179 void ReplaceStringInPrefs(const std::string& find,
153 const std::string& replace) { 180 const std::string& replace) {
154 // Tamper with the file's contents 181 base::FileEnumerator file_enumerator(
155 base::FilePath pref_file_path = 182 profile_dir_.path(), true, base::FileEnumerator::FILES);
156 ProfilePrefStoreManager::GetPrefFilePathFromProfilePath( 183
157 profile_dir_.path()); 184 base::FilePath pref_file_path;
158 std::string pref_file_contents; 185 while (!(pref_file_path = file_enumerator.Next()).empty()) {
159 EXPECT_TRUE(base::ReadFileToString(pref_file_path, &pref_file_contents)); 186 // Tamper with the file's contents
160 ReplaceSubstringsAfterOffset(&pref_file_contents, 0u, find, replace); 187 std::string pref_file_contents;
161 EXPECT_EQ(static_cast<int>(pref_file_contents.length()), 188 EXPECT_TRUE(base::ReadFileToString(pref_file_path, &pref_file_contents));
162 base::WriteFile(pref_file_path, 189 ReplaceSubstringsAfterOffset(&pref_file_contents, 0u, find, replace);
163 pref_file_contents.c_str(), 190 EXPECT_EQ((int)pref_file_contents.length(),
164 pref_file_contents.length())); 191 base::WriteFile(pref_file_path,
192 pref_file_contents.c_str(),
193 pref_file_contents.length()));
194 }
165 } 195 }
166 196
167 void ExpectStringValueEquals(const std::string& name, 197 void ExpectStringValueEquals(const std::string& name,
168 const std::string& expected) { 198 const std::string& expected) {
169 const base::Value* value = NULL; 199 const base::Value* value = NULL;
170 std::string as_string; 200 std::string as_string;
171 if (!pref_store_->GetValue(name, &value)) { 201 if (!pref_store_->GetValue(name, &value)) {
172 ADD_FAILURE() << name << " is not a defined value."; 202 ADD_FAILURE() << name << " is not a defined value.";
173 } else if (!value->GetAsString(&as_string)) { 203 } else if (!value->GetAsString(&as_string)) {
174 ADD_FAILURE() << name << " could not be coerced to a string."; 204 ADD_FAILURE() << name << " could not be coerced to a string.";
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 LoadExistingPrefs(); 279 LoadExistingPrefs();
250 280
251 // kTrackedAtomic is loaded as it appears on disk. 281 // kTrackedAtomic is loaded as it appears on disk.
252 ExpectStringValueEquals(kTrackedAtomic, kFoobar); 282 ExpectStringValueEquals(kTrackedAtomic, kFoobar);
253 // If preference tracking is supported, kProtectedAtomic will be undefined 283 // If preference tracking is supported, kProtectedAtomic will be undefined
254 // because the value was discarded due to loss of the hash store contents. 284 // because the value was discarded due to loss of the hash store contents.
255 EXPECT_EQ(!ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, 285 EXPECT_EQ(!ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
256 pref_store_->GetValue(kProtectedAtomic, NULL)); 286 pref_store_->GetValue(kProtectedAtomic, NULL));
257 } 287 }
258 288
289 TEST_F(ProfilePrefStoreManagerTest, MigrateFromOneFile) {
290 InitializeDeprecatedCombinedProfilePrefStore();
291
292 LoadExistingPrefs();
293
294 ExpectStringValueEquals(kTrackedAtomic, kFoobar);
295 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
296 }
297
259 TEST_F(ProfilePrefStoreManagerTest, UpdateProfileHashStoreIfRequired) { 298 TEST_F(ProfilePrefStoreManagerTest, UpdateProfileHashStoreIfRequired) {
260 InitializePrefs(); 299 scoped_refptr<JsonPrefStore> legacy_prefs(
261 300 new JsonPrefStore(ProfilePrefStoreManager::GetPrefFilePathFromProfilePath(
262 manager_->ResetPrefHashStore(); 301 profile_dir_.path()),
302 main_message_loop_.message_loop_proxy(),
303 scoped_ptr<PrefFilter>()));
304 legacy_prefs->SetValue(kTrackedAtomic, new base::StringValue(kFoobar));
305 legacy_prefs->SetValue(kProtectedAtomic, new base::StringValue(kHelloWorld));
306 legacy_prefs = NULL;
307 base::RunLoop().RunUntilIdle();
263 308
264 // This is a no-op if !kPlatformSupportsPreferenceTracking. 309 // This is a no-op if !kPlatformSupportsPreferenceTracking.
265 manager_->UpdateProfileHashStoreIfRequired( 310 manager_->UpdateProfileHashStoreIfRequired(
266 main_message_loop_.message_loop_proxy()); 311 main_message_loop_.message_loop_proxy());
267 base::RunLoop().RunUntilIdle(); 312 base::RunLoop().RunUntilIdle();
268 313
269 // At the moment, UpdateProfileHashStoreIfRequired will accept existing 314 // At the moment, UpdateProfileHashStoreIfRequired will accept existing
270 // values. 315 // values.
271 LoadExistingPrefs(); 316 LoadExistingPrefs();
272 317
(...skipping 10 matching lines...) Expand all
283 ASSERT_TRUE( 328 ASSERT_TRUE(
284 manager_->InitializePrefsFromMasterPrefs(*master_prefs)); 329 manager_->InitializePrefsFromMasterPrefs(*master_prefs));
285 330
286 LoadExistingPrefs(); 331 LoadExistingPrefs();
287 332
288 // Verify that InitializePrefsFromMasterPrefs correctly applied the MACs 333 // Verify that InitializePrefsFromMasterPrefs correctly applied the MACs
289 // necessary to authenticate these values. 334 // necessary to authenticate these values.
290 ExpectStringValueEquals(kTrackedAtomic, kFoobar); 335 ExpectStringValueEquals(kTrackedAtomic, kFoobar);
291 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); 336 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
292 } 337 }
338
339 TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtected) {
340 InitializePrefs();
341 LoadExistingPrefs();
342 ExpectStringValueEquals(kUnprotectedAtomic, kFoobar);
343
344 PrefHashFilter::TrackedPreferenceMetadata new_protected = {
345 99u, kUnprotectedAtomic, PrefHashFilter::ENFORCE_ON_LOAD,
346 PrefHashFilter::TRACKING_STRATEGY_ATOMIC};
347 configuration_.push_back(new_protected);
348 ReloadConfiguration();
349 LoadExistingPrefs();
350 ExpectStringValueEquals(kUnprotectedAtomic, kFoobar);
351 }
352
353 TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) {
354 InitializePrefs();
355 PrefHashFilter::TrackedPreferenceMetadata new_protected = {
356 99u, kUnprotectedAtomic, PrefHashFilter::ENFORCE_ON_LOAD,
357 PrefHashFilter::TRACKING_STRATEGY_ATOMIC};
358 configuration_.push_back(new_protected);
359 ReloadConfiguration();
360 ProfilePrefStoreManager::ResetAllPrefHashStores(&local_state_);
361
362 LoadExistingPrefs();
363 ASSERT_FALSE(pref_store_->GetValue(kUnprotectedAtomic, NULL));
364 }
365
366
367 TEST_F(ProfilePrefStoreManagerTest, ProtectedToUnprotected) {
368 InitializePrefs();
369 ProfilePrefStoreManager::ResetAllPrefHashStores(&local_state_);
370
371 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it =
372 configuration_.begin();
373 it != configuration_.end();
374 ++it) {
375 if (it->name == std::string(kProtectedAtomic)) {
376 configuration_.erase(it);
377 break;
378 }
379 }
380
381 ReloadConfiguration();
382
383 LoadExistingPrefs();
384 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
385
386 // Accessing the value of the previously proteted pref didn't trigger its move
387 // to the unprotected preferences file, though the loading of the pref store
388 // should still have caused the MAC store to be recalculated.
389 LoadExistingPrefs();
390 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld);
391
392 // Trigger the logic that migrates it back to the unprotected preferences
393 // file.
394 pref_store_->SetValue(kProtectedAtomic, new base::StringValue(kGoodbyeWorld));
395 LoadExistingPrefs();
396 ExpectStringValueEquals(kProtectedAtomic, kGoodbyeWorld);
397 }
398
399 // Add test coverage for when Reset events should and should not be recorded.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698