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/prefs/testing_pref_service.h" 15 #include "base/strings/string_split.h" 16 #include "base/values.h" 17 #include "chrome/browser/prefs/interceptable_pref_filter.h" 18 #include "chrome/browser/prefs/pref_hash_store.h" 19 #include "chrome/browser/prefs/pref_hash_store_impl.h" 20 #include "chrome/browser/prefs/pref_hash_store_transaction.h" 21 #include "chrome/browser/prefs/profile_pref_store_manager.h" 22 #include "chrome/browser/prefs/tracked/dictionary_hash_store_contents.h" 23 #include "chrome/browser/prefs/tracked/hash_store_contents.h" 24 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h" 25 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h" 26 #include "testing/gtest/include/gtest/gtest.h" 27 28 namespace { 29 30 // An unprotected pref. 31 const char kUnprotectedPref[] = "unprotected"; 32 // A protected pref. 33 const char kProtectedPref[] = "protected"; 34 // A protected pref which is initially stored in the unprotected store. 35 const char kPreviouslyUnprotectedPref[] = "previously.unprotected"; 36 // An unprotected pref which is initially stored in the protected store. 37 const char kPreviouslyProtectedPref[] = "previously.protected"; 38 39 const char kUnprotectedPrefValue[] = "unprotected_value"; 40 const char kProtectedPrefValue[] = "protected_value"; 41 const char kPreviouslyUnprotectedPrefValue[] = "previously_unprotected_value"; 42 const char kPreviouslyProtectedPrefValue[] = "previously_protected_value"; 43 44 // A simple InterceptablePrefFilter which doesn't do anything but hand the prefs 45 // back downstream in FinalizeFilterOnLoad. 46 class SimpleInterceptablePrefFilter : public InterceptablePrefFilter { 47 public: 48 // PrefFilter remaining implementation. 49 virtual void FilterUpdate(const std::string& path) OVERRIDE { 50 ADD_FAILURE(); 51 } 52 virtual void FilterSerializeData( 53 base::DictionaryValue* pref_store_contents) OVERRIDE { 54 ADD_FAILURE(); 55 } 56 57 private: 58 // InterceptablePrefFilter implementation. 59 virtual void FinalizeFilterOnLoad( 60 const PostFilterOnLoadCallback& post_filter_on_load_callback, 61 scoped_ptr<base::DictionaryValue> pref_store_contents, 62 bool prefs_altered) OVERRIDE { 63 post_filter_on_load_callback.Run(pref_store_contents.Pass(), prefs_altered); 64 } 65 }; 66 67 // A test fixture designed to be used like this: 68 // 1) Set up initial store prefs with PresetStoreValue(). 69 // 2) Hand both sets of prefs to the migrator via HandPrefsToMigrator(). 70 // 3) Migration completes synchronously when the second store hands its prefs 71 // over. 72 // 4) Verifications can be made via various methods of this fixture. 73 // Call Reset() to perform a second migration. 74 class TrackedPreferencesMigrationTest : public testing::Test { 75 public: 76 enum MockPrefStoreID { 77 MOCK_UNPROTECTED_PREF_STORE, 78 MOCK_PROTECTED_PREF_STORE, 79 }; 80 81 TrackedPreferencesMigrationTest() 82 : unprotected_prefs_(new base::DictionaryValue), 83 protected_prefs_(new base::DictionaryValue), 84 migration_modified_unprotected_store_(false), 85 migration_modified_protected_store_(false), 86 unprotected_store_migration_complete_(false), 87 protected_store_migration_complete_(false) {} 88 89 virtual void SetUp() OVERRIDE { 90 ProfilePrefStoreManager::RegisterPrefs(local_state_.registry()); 91 Reset(); 92 } 93 94 void Reset() { 95 std::set<std::string> unprotected_pref_names; 96 std::set<std::string> protected_pref_names; 97 unprotected_pref_names.insert(kUnprotectedPref); 98 unprotected_pref_names.insert(kPreviouslyProtectedPref); 99 protected_pref_names.insert(kProtectedPref); 100 protected_pref_names.insert(kPreviouslyUnprotectedPref); 101 102 migration_modified_unprotected_store_ = false; 103 migration_modified_protected_store_ = false; 104 unprotected_store_migration_complete_ = false; 105 protected_store_migration_complete_ = false; 106 107 unprotected_store_successful_write_callback_.Reset(); 108 protected_store_successful_write_callback_.Reset(); 109 110 SetupTrackedPreferencesMigration( 111 unprotected_pref_names, 112 protected_pref_names, 113 base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore, 114 base::Unretained(this), 115 MOCK_UNPROTECTED_PREF_STORE), 116 base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore, 117 base::Unretained(this), 118 MOCK_PROTECTED_PREF_STORE), 119 base::Bind( 120 &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure, 121 base::Unretained(this), 122 MOCK_UNPROTECTED_PREF_STORE), 123 base::Bind( 124 &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure, 125 base::Unretained(this), 126 MOCK_PROTECTED_PREF_STORE), 127 scoped_ptr<PrefHashStore>( 128 new PrefHashStoreImpl(kSeed, kDeviceId, false)), 129 scoped_ptr<PrefHashStore>( 130 new PrefHashStoreImpl(kSeed, kDeviceId, true)), 131 scoped_ptr<HashStoreContents>( 132 new PrefServiceHashStoreContents(kHashStoreId, &local_state_)), 133 134 &mock_unprotected_pref_filter_, 135 &mock_protected_pref_filter_); 136 137 // Verify initial expectations are met. 138 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 139 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 140 EXPECT_FALSE( 141 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 142 EXPECT_FALSE( 143 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 144 } 145 146 protected: 147 // Sets |key| to |value| in the test store identified by |store_id| before 148 // migration begins. Also sets the corresponding hash in the same store. 149 void PresetStoreValue(MockPrefStoreID store_id, 150 const std::string& key, 151 const std::string value) { 152 PresetStoreValueOnly(store_id, key, value); 153 PresetStoreValueHash(store_id, key, value); 154 } 155 156 // Sets |key| to |value| in the test store identified by |store_id| before 157 // migration begins. Stores the value hash in Local State as in M36 and 158 // earlier. 159 void PresetLegacyStoreValue(MockPrefStoreID store_id, 160 const std::string& key, 161 const std::string value) { 162 PresetStoreValueOnly(store_id, key, value); 163 PresetLegacyValueHash(key, value); 164 } 165 166 // Stores a hash for |key| and |value| in the hash store identified by 167 // |store_id| before migration begins. 168 void PresetStoreValueHash(MockPrefStoreID store_id, 169 const std::string& key, 170 const std::string value) { 171 base::DictionaryValue* store = NULL; 172 scoped_ptr<PrefHashStore> pref_hash_store; 173 switch (store_id) { 174 case MOCK_UNPROTECTED_PREF_STORE: 175 store = unprotected_prefs_.get(); 176 pref_hash_store.reset(new PrefHashStoreImpl(kSeed, kDeviceId, false)); 177 break; 178 case MOCK_PROTECTED_PREF_STORE: 179 store = protected_prefs_.get(); 180 pref_hash_store.reset(new PrefHashStoreImpl(kSeed, kDeviceId, true)); 181 break; 182 } 183 DCHECK(store); 184 185 base::StringValue string_value(value); 186 pref_hash_store->BeginTransaction( 187 scoped_ptr<HashStoreContents>( 188 new DictionaryHashStoreContents(store)))->StoreHash( 189 key, &string_value); 190 } 191 192 // Stores a hash for |key| and |value| in the legacy hash store in 193 // local_state. 194 void PresetLegacyValueHash(const std::string& key, 195 const std::string value) { 196 scoped_ptr<PrefHashStore> pref_hash_store( 197 new PrefHashStoreImpl(kSeed, kDeviceId, true)); 198 199 base::StringValue string_value(value); 200 PrefHashStoreImpl(kSeed, kDeviceId, true) 201 .BeginTransaction(scoped_ptr<HashStoreContents>( 202 new PrefServiceHashStoreContents(kHashStoreId, &local_state_))) 203 ->StoreHash(key, &string_value); 204 } 205 206 // Returns true if the store opposite to |store_id| is observed for its next 207 // successful write. 208 bool WasOnSuccessfulWriteCallbackRegistered(MockPrefStoreID store_id) { 209 switch (store_id) { 210 case MOCK_UNPROTECTED_PREF_STORE: 211 return !protected_store_successful_write_callback_.is_null(); 212 case MOCK_PROTECTED_PREF_STORE: 213 return !unprotected_store_successful_write_callback_.is_null(); 214 } 215 NOTREACHED(); 216 return false; 217 } 218 219 // Verifies that the (key, value) pairs in |expected_prefs_in_store| are found 220 // in the store identified by |store_id|. 221 void VerifyValuesStored( 222 MockPrefStoreID store_id, 223 const base::StringPairs& expected_prefs_in_store) { 224 base::DictionaryValue* store = NULL; 225 switch (store_id) { 226 case MOCK_UNPROTECTED_PREF_STORE: 227 store = unprotected_prefs_.get(); 228 break; 229 case MOCK_PROTECTED_PREF_STORE: 230 store = protected_prefs_.get(); 231 break; 232 } 233 DCHECK(store); 234 235 for (base::StringPairs::const_iterator it = expected_prefs_in_store.begin(); 236 it != expected_prefs_in_store.end(); ++it) { 237 std::string val; 238 EXPECT_TRUE(store->GetString(it->first, &val)); 239 EXPECT_EQ(it->second, val); 240 } 241 } 242 243 // Determines whether |expected_pref_in_hash_store| has a hash in the hash 244 // store identified by |store_id|. 245 bool ContainsHash(MockPrefStoreID store_id, 246 std::string expected_pref_in_hash_store) { 247 base::DictionaryValue* store = NULL; 248 switch (store_id) { 249 case MOCK_UNPROTECTED_PREF_STORE: 250 store = unprotected_prefs_.get(); 251 break; 252 case MOCK_PROTECTED_PREF_STORE: 253 store = protected_prefs_.get(); 254 break; 255 } 256 DCHECK(store); 257 const base::DictionaryValue* hash_store_contents = 258 DictionaryHashStoreContents(store).GetContents(); 259 return hash_store_contents && 260 hash_store_contents->GetString(expected_pref_in_hash_store, 261 static_cast<std::string*>(NULL)); 262 } 263 264 // Determines whether |expected_pref_in_hash_store| has a hash in the Local 265 // State hash store. 266 bool ContainsLegacyHash(std::string expected_pref_in_hash_store) { 267 const base::DictionaryValue* hash_store_contents = 268 PrefServiceHashStoreContents(kHashStoreId, &local_state_).GetContents(); 269 return hash_store_contents && 270 hash_store_contents->GetString(expected_pref_in_hash_store, 271 static_cast<std::string*>(NULL)); 272 } 273 274 // Both stores need to hand their prefs over in order for migration to kick 275 // in. 276 void HandPrefsToMigrator(MockPrefStoreID store_id) { 277 switch (store_id) { 278 case MOCK_UNPROTECTED_PREF_STORE: 279 mock_unprotected_pref_filter_.FilterOnLoad( 280 base::Bind(&TrackedPreferencesMigrationTest::GetPrefsBack, 281 base::Unretained(this), 282 MOCK_UNPROTECTED_PREF_STORE), 283 unprotected_prefs_.Pass()); 284 break; 285 case MOCK_PROTECTED_PREF_STORE: 286 mock_protected_pref_filter_.FilterOnLoad( 287 base::Bind(&TrackedPreferencesMigrationTest::GetPrefsBack, 288 base::Unretained(this), 289 MOCK_PROTECTED_PREF_STORE), 290 protected_prefs_.Pass()); 291 break; 292 } 293 } 294 295 bool HasPrefs(MockPrefStoreID store_id) { 296 switch (store_id) { 297 case MOCK_UNPROTECTED_PREF_STORE: 298 return unprotected_prefs_; 299 case MOCK_PROTECTED_PREF_STORE: 300 return protected_prefs_; 301 } 302 NOTREACHED(); 303 return false; 304 } 305 306 bool StoreModifiedByMigration(MockPrefStoreID store_id) { 307 switch (store_id) { 308 case MOCK_UNPROTECTED_PREF_STORE: 309 return migration_modified_unprotected_store_; 310 case MOCK_PROTECTED_PREF_STORE: 311 return migration_modified_protected_store_; 312 } 313 NOTREACHED(); 314 return false; 315 } 316 317 bool MigrationCompleted() { 318 return unprotected_store_migration_complete_ && 319 protected_store_migration_complete_; 320 } 321 322 void SimulateSuccessfulWrite(MockPrefStoreID store_id) { 323 switch (store_id) { 324 case MOCK_UNPROTECTED_PREF_STORE: 325 EXPECT_FALSE(unprotected_store_successful_write_callback_.is_null()); 326 unprotected_store_successful_write_callback_.Run(); 327 unprotected_store_successful_write_callback_.Reset(); 328 break; 329 case MOCK_PROTECTED_PREF_STORE: 330 EXPECT_FALSE(protected_store_successful_write_callback_.is_null()); 331 protected_store_successful_write_callback_.Run(); 332 protected_store_successful_write_callback_.Reset(); 333 break; 334 } 335 } 336 337 private: 338 void RegisterSuccessfulWriteClosure( 339 MockPrefStoreID store_id, 340 const base::Closure& successful_write_closure) { 341 switch (store_id) { 342 case MOCK_UNPROTECTED_PREF_STORE: 343 EXPECT_TRUE(unprotected_store_successful_write_callback_.is_null()); 344 unprotected_store_successful_write_callback_ = successful_write_closure; 345 break; 346 case MOCK_PROTECTED_PREF_STORE: 347 EXPECT_TRUE(protected_store_successful_write_callback_.is_null()); 348 protected_store_successful_write_callback_ = successful_write_closure; 349 break; 350 } 351 } 352 353 // Helper given as an InterceptablePrefFilter::FinalizeFilterOnLoadCallback 354 // to the migrator to be invoked when it's done. 355 void GetPrefsBack(MockPrefStoreID store_id, 356 scoped_ptr<base::DictionaryValue> prefs, 357 bool prefs_altered) { 358 switch (store_id) { 359 case MOCK_UNPROTECTED_PREF_STORE: 360 EXPECT_FALSE(unprotected_prefs_); 361 unprotected_prefs_ = prefs.Pass(); 362 migration_modified_unprotected_store_ = prefs_altered; 363 unprotected_store_migration_complete_ = true; 364 break; 365 case MOCK_PROTECTED_PREF_STORE: 366 EXPECT_FALSE(protected_prefs_); 367 protected_prefs_ = prefs.Pass(); 368 migration_modified_protected_store_ = prefs_altered; 369 protected_store_migration_complete_ = true; 370 break; 371 } 372 } 373 374 // Helper given as a cleaning callback to the migrator. 375 void RemovePathFromStore(MockPrefStoreID store_id, const std::string& key) { 376 switch (store_id) { 377 case MOCK_UNPROTECTED_PREF_STORE: 378 ASSERT_TRUE(unprotected_prefs_); 379 unprotected_prefs_->RemovePath(key, NULL); 380 break; 381 case MOCK_PROTECTED_PREF_STORE: 382 ASSERT_TRUE(protected_prefs_); 383 protected_prefs_->RemovePath(key, NULL); 384 break; 385 } 386 } 387 388 // Sets |key| to |value| in the test store identified by |store_id| before 389 // migration begins. Does not store a preference hash. 390 void PresetStoreValueOnly(MockPrefStoreID store_id, 391 const std::string& key, 392 const std::string value) { 393 base::DictionaryValue* store = NULL; 394 switch (store_id) { 395 case MOCK_UNPROTECTED_PREF_STORE: 396 store = unprotected_prefs_.get(); 397 break; 398 case MOCK_PROTECTED_PREF_STORE: 399 store = protected_prefs_.get(); 400 break; 401 } 402 DCHECK(store); 403 404 store->SetString(key, value); 405 } 406 407 static const char kHashStoreId[]; 408 static const char kSeed[]; 409 static const char kDeviceId[]; 410 411 scoped_ptr<base::DictionaryValue> unprotected_prefs_; 412 scoped_ptr<base::DictionaryValue> protected_prefs_; 413 414 SimpleInterceptablePrefFilter mock_unprotected_pref_filter_; 415 SimpleInterceptablePrefFilter mock_protected_pref_filter_; 416 417 base::Closure unprotected_store_successful_write_callback_; 418 base::Closure protected_store_successful_write_callback_; 419 420 bool migration_modified_unprotected_store_; 421 bool migration_modified_protected_store_; 422 423 bool unprotected_store_migration_complete_; 424 bool protected_store_migration_complete_; 425 426 TestingPrefServiceSimple local_state_; 427 428 DISALLOW_COPY_AND_ASSIGN(TrackedPreferencesMigrationTest); 429 }; 430 431 // static 432 const char TrackedPreferencesMigrationTest::kHashStoreId[] = "hash-store-id"; 433 434 // static 435 const char TrackedPreferencesMigrationTest::kSeed[] = "seed"; 436 437 // static 438 const char TrackedPreferencesMigrationTest::kDeviceId[] = "device-id"; 439 440 } // namespace 441 442 TEST_F(TrackedPreferencesMigrationTest, NoMigrationRequired) { 443 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, 444 kUnprotectedPrefValue); 445 PresetStoreValue(MOCK_PROTECTED_PREF_STORE, kProtectedPref, 446 kProtectedPrefValue); 447 448 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 449 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 450 451 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 452 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 453 454 // Hand unprotected prefs to the migrator which should wait for the protected 455 // prefs. 456 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 457 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 458 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 459 EXPECT_FALSE(MigrationCompleted()); 460 461 // Hand protected prefs to the migrator which should proceed with the 462 // migration synchronously. 463 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 464 EXPECT_TRUE(MigrationCompleted()); 465 466 // Prefs should have been handed back over. 467 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 468 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 469 EXPECT_FALSE( 470 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 471 EXPECT_FALSE( 472 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 473 EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE)); 474 EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE)); 475 476 base::StringPairs expected_unprotected_values; 477 expected_unprotected_values.push_back( 478 std::make_pair(kUnprotectedPref, kUnprotectedPrefValue)); 479 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values); 480 481 base::StringPairs expected_protected_values; 482 expected_protected_values.push_back( 483 std::make_pair(kProtectedPref, kProtectedPrefValue)); 484 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 485 486 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 487 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 488 489 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 490 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 491 } 492 493 TEST_F(TrackedPreferencesMigrationTest, LegacyHashMigrationOnly) { 494 PresetLegacyStoreValue( 495 MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue); 496 PresetLegacyStoreValue( 497 MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue); 498 499 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 500 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 501 502 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 503 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 504 505 EXPECT_TRUE(ContainsLegacyHash(kProtectedPref)); 506 EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref)); 507 508 // Hand unprotected prefs to the migrator which should wait for the protected 509 // prefs. 510 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 511 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 512 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 513 EXPECT_FALSE(MigrationCompleted()); 514 515 // Hand protected prefs to the migrator which should proceed with the 516 // migration synchronously. 517 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 518 EXPECT_TRUE(MigrationCompleted()); 519 520 // Prefs should have been handed back over. 521 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 522 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 523 524 // There is no pending cleanup task for the modern hash stores. 525 EXPECT_FALSE( 526 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 527 EXPECT_FALSE( 528 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 529 530 // Both stores were modified as hashes were moved from Local State. 531 EXPECT_TRUE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE)); 532 EXPECT_TRUE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE)); 533 534 base::StringPairs expected_unprotected_values; 535 expected_unprotected_values.push_back( 536 std::make_pair(kUnprotectedPref, kUnprotectedPrefValue)); 537 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values); 538 539 base::StringPairs expected_protected_values; 540 expected_protected_values.push_back( 541 std::make_pair(kProtectedPref, kProtectedPrefValue)); 542 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 543 544 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 545 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 546 547 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 548 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 549 550 // The Local State hash store will not be reset until the next run. 551 EXPECT_TRUE(ContainsLegacyHash(kProtectedPref)); 552 EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref)); 553 554 Reset(); 555 556 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 557 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 558 EXPECT_TRUE(MigrationCompleted()); 559 560 // Neither store was modified. 561 EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE)); 562 EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE)); 563 564 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 565 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 566 567 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 568 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 569 570 EXPECT_FALSE(ContainsLegacyHash(kProtectedPref)); 571 EXPECT_FALSE(ContainsLegacyHash(kUnprotectedPref)); 572 } 573 574 TEST_F(TrackedPreferencesMigrationTest, FullMigrationWithLegacyHashStore) { 575 // Store some values with matching MACs in Local State. 576 PresetLegacyStoreValue( 577 MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue); 578 PresetLegacyStoreValue(MOCK_UNPROTECTED_PREF_STORE, 579 kPreviouslyUnprotectedPref, 580 kPreviouslyUnprotectedPrefValue); 581 PresetLegacyStoreValue( 582 MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue); 583 PresetLegacyStoreValue(MOCK_PROTECTED_PREF_STORE, 584 kPreviouslyProtectedPref, 585 kPreviouslyProtectedPrefValue); 586 587 // Verify that there are no MACs in Preferences or Secure Preferences. 588 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 589 EXPECT_FALSE( 590 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 591 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 592 EXPECT_FALSE( 593 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 594 595 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 596 EXPECT_FALSE( 597 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 598 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 599 EXPECT_FALSE( 600 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 601 602 // Verify that there are MACs in Local State. 603 EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref)); 604 EXPECT_TRUE(ContainsLegacyHash(kPreviouslyUnprotectedPref)); 605 EXPECT_TRUE(ContainsLegacyHash(kProtectedPref)); 606 EXPECT_TRUE(ContainsLegacyHash(kPreviouslyProtectedPref)); 607 608 // Perform a first-pass migration. 609 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 610 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 611 EXPECT_TRUE(MigrationCompleted()); 612 613 // All values should have been moved to their preferred locations, including 614 // MACs. 615 base::StringPairs expected_unprotected_values; 616 expected_unprotected_values.push_back( 617 std::make_pair(kUnprotectedPref, kUnprotectedPrefValue)); 618 expected_unprotected_values.push_back( 619 std::make_pair(kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 620 base::StringPairs expected_protected_values; 621 expected_protected_values.push_back( 622 std::make_pair(kProtectedPref, kProtectedPrefValue)); 623 expected_protected_values.push_back(std::make_pair( 624 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue)); 625 626 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values); 627 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 628 629 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 630 EXPECT_TRUE( 631 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 632 EXPECT_TRUE( 633 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 634 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 635 636 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 637 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 638 639 EXPECT_FALSE( 640 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 641 EXPECT_FALSE( 642 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 643 644 // Removing the values from their previous locations is deferred until the new 645 // locations are persisted. 646 EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref)); 647 EXPECT_TRUE(ContainsLegacyHash(kPreviouslyUnprotectedPref)); 648 EXPECT_TRUE(ContainsLegacyHash(kProtectedPref)); 649 EXPECT_TRUE(ContainsLegacyHash(kPreviouslyProtectedPref)); 650 651 EXPECT_TRUE( 652 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 653 EXPECT_TRUE( 654 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 655 656 SimulateSuccessfulWrite(MOCK_UNPROTECTED_PREF_STORE); 657 SimulateSuccessfulWrite(MOCK_PROTECTED_PREF_STORE); 658 659 Reset(); 660 661 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 662 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 663 EXPECT_TRUE(MigrationCompleted()); 664 665 // In this run the MACs should have been removed from their previous 666 // locations. There is no more pending action. 667 EXPECT_FALSE( 668 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 669 EXPECT_FALSE( 670 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 671 672 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 673 EXPECT_FALSE( 674 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 675 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 676 EXPECT_TRUE( 677 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 678 679 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 680 EXPECT_TRUE( 681 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 682 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 683 EXPECT_FALSE( 684 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 685 686 EXPECT_FALSE(ContainsLegacyHash(kUnprotectedPref)); 687 EXPECT_FALSE(ContainsLegacyHash(kPreviouslyUnprotectedPref)); 688 EXPECT_FALSE(ContainsLegacyHash(kProtectedPref)); 689 EXPECT_FALSE(ContainsLegacyHash(kPreviouslyProtectedPref)); 690 691 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values); 692 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 693 } 694 695 TEST_F(TrackedPreferencesMigrationTest, FullMigration) { 696 PresetStoreValue( 697 MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue); 698 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, 699 kPreviouslyUnprotectedPref, 700 kPreviouslyUnprotectedPrefValue); 701 PresetStoreValue( 702 MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue); 703 PresetStoreValue(MOCK_PROTECTED_PREF_STORE, 704 kPreviouslyProtectedPref, 705 kPreviouslyProtectedPrefValue); 706 707 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 708 EXPECT_TRUE( 709 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 710 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 711 EXPECT_FALSE( 712 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 713 714 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 715 EXPECT_FALSE( 716 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 717 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 718 EXPECT_TRUE( 719 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 720 721 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 722 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 723 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 724 EXPECT_FALSE(MigrationCompleted()); 725 726 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 727 EXPECT_TRUE(MigrationCompleted()); 728 729 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 730 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 731 EXPECT_TRUE( 732 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 733 EXPECT_TRUE( 734 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 735 EXPECT_TRUE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE)); 736 EXPECT_TRUE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE)); 737 738 // Values should have been migrated to their store, but migrated values should 739 // still remain in the source store until cleanup tasks are later invoked. 740 { 741 base::StringPairs expected_unprotected_values; 742 expected_unprotected_values.push_back(std::make_pair( 743 kUnprotectedPref, kUnprotectedPrefValue)); 744 expected_unprotected_values.push_back(std::make_pair( 745 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 746 expected_unprotected_values.push_back(std::make_pair( 747 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue)); 748 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, 749 expected_unprotected_values); 750 751 base::StringPairs expected_protected_values; 752 expected_protected_values.push_back(std::make_pair( 753 kProtectedPref, kProtectedPrefValue)); 754 expected_protected_values.push_back(std::make_pair( 755 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue)); 756 expected_unprotected_values.push_back(std::make_pair( 757 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 758 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 759 760 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 761 EXPECT_TRUE( 762 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 763 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 764 EXPECT_TRUE( 765 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 766 767 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 768 EXPECT_TRUE( 769 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 770 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 771 EXPECT_TRUE( 772 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 773 } 774 775 // A successful write of the protected pref store should result in a clean up 776 // of the unprotected store. 777 SimulateSuccessfulWrite(MOCK_PROTECTED_PREF_STORE); 778 779 { 780 base::StringPairs expected_unprotected_values; 781 expected_unprotected_values.push_back(std::make_pair( 782 kUnprotectedPref, kUnprotectedPrefValue)); 783 expected_unprotected_values.push_back(std::make_pair( 784 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 785 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, 786 expected_unprotected_values); 787 788 base::StringPairs expected_protected_values; 789 expected_protected_values.push_back(std::make_pair( 790 kProtectedPref, kProtectedPrefValue)); 791 expected_protected_values.push_back(std::make_pair( 792 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue)); 793 expected_unprotected_values.push_back(std::make_pair( 794 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 795 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 796 } 797 798 SimulateSuccessfulWrite(MOCK_UNPROTECTED_PREF_STORE); 799 800 { 801 base::StringPairs expected_unprotected_values; 802 expected_unprotected_values.push_back(std::make_pair( 803 kUnprotectedPref, kUnprotectedPrefValue)); 804 expected_unprotected_values.push_back(std::make_pair( 805 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 806 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, 807 expected_unprotected_values); 808 809 base::StringPairs expected_protected_values; 810 expected_protected_values.push_back(std::make_pair( 811 kProtectedPref, kProtectedPrefValue)); 812 expected_protected_values.push_back(std::make_pair( 813 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue)); 814 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 815 } 816 817 // Hashes are not cleaned up yet. 818 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 819 EXPECT_TRUE( 820 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 821 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 822 EXPECT_TRUE( 823 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 824 825 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 826 EXPECT_TRUE( 827 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 828 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 829 EXPECT_TRUE( 830 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 831 832 Reset(); 833 834 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 835 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 836 EXPECT_TRUE(MigrationCompleted()); 837 838 // Hashes are cleaned up. 839 EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref)); 840 EXPECT_FALSE( 841 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 842 EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref)); 843 EXPECT_TRUE( 844 ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 845 846 EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref)); 847 EXPECT_TRUE( 848 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref)); 849 EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref)); 850 EXPECT_FALSE( 851 ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref)); 852 } 853 854 TEST_F(TrackedPreferencesMigrationTest, CleanupOnly) { 855 // Already migrated; only cleanup needed. 856 PresetStoreValue( 857 MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue); 858 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, 859 kPreviouslyProtectedPref, 860 kPreviouslyProtectedPrefValue); 861 PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, 862 kPreviouslyUnprotectedPref, 863 kPreviouslyUnprotectedPrefValue); 864 PresetStoreValue( 865 MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue); 866 PresetStoreValue(MOCK_PROTECTED_PREF_STORE, 867 kPreviouslyProtectedPref, 868 kPreviouslyProtectedPrefValue); 869 PresetStoreValue(MOCK_PROTECTED_PREF_STORE, 870 kPreviouslyUnprotectedPref, 871 kPreviouslyUnprotectedPrefValue); 872 873 HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE); 874 EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 875 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 876 EXPECT_FALSE(MigrationCompleted()); 877 878 HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE); 879 EXPECT_TRUE(MigrationCompleted()); 880 881 EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE)); 882 EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE)); 883 EXPECT_FALSE( 884 WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE)); 885 EXPECT_FALSE( 886 WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE)); 887 EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE)); 888 EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE)); 889 890 // Cleanup should happen synchronously if the values were already present in 891 // their destination stores. 892 { 893 base::StringPairs expected_unprotected_values; 894 expected_unprotected_values.push_back(std::make_pair( 895 kUnprotectedPref, kUnprotectedPrefValue)); 896 expected_unprotected_values.push_back(std::make_pair( 897 kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue)); 898 VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, 899 expected_unprotected_values); 900 901 base::StringPairs expected_protected_values; 902 expected_protected_values.push_back(std::make_pair( 903 kProtectedPref, kProtectedPrefValue)); 904 expected_protected_values.push_back(std::make_pair( 905 kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue)); 906 VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values); 907 } 908 } 909