| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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/pref_hash_store_impl.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/macros.h" | |
| 10 #include "base/values.h" | |
| 11 #include "chrome/browser/prefs/tracked/dictionary_hash_store_contents.h" | |
| 12 #include "chrome/browser/prefs/tracked/hash_store_contents.h" | |
| 13 #include "chrome/browser/prefs/tracked/pref_hash_store_impl.h" | |
| 14 #include "chrome/browser/prefs/tracked/pref_hash_store_transaction.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 | |
| 17 class PrefHashStoreImplTest : public testing::Test { | |
| 18 protected: | |
| 19 scoped_ptr<HashStoreContents> CreateHashStoreContents() { | |
| 20 return scoped_ptr<HashStoreContents>( | |
| 21 new DictionaryHashStoreContents(&pref_store_contents_)); | |
| 22 } | |
| 23 | |
| 24 private: | |
| 25 base::DictionaryValue pref_store_contents_; | |
| 26 }; | |
| 27 | |
| 28 TEST_F(PrefHashStoreImplTest, AtomicHashStoreAndCheck) { | |
| 29 base::StringValue string_1("string1"); | |
| 30 base::StringValue string_2("string2"); | |
| 31 | |
| 32 { | |
| 33 // 32 NULL bytes is the seed that was used to generate the legacy hash. | |
| 34 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 35 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 36 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 37 | |
| 38 // Only NULL should be trusted in the absence of a hash. | |
| 39 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 40 transaction->CheckValue("path1", &string_1)); | |
| 41 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE, | |
| 42 transaction->CheckValue("path1", NULL)); | |
| 43 | |
| 44 transaction->StoreHash("path1", &string_1); | |
| 45 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 46 transaction->CheckValue("path1", &string_1)); | |
| 47 EXPECT_EQ(PrefHashStoreTransaction::CLEARED, | |
| 48 transaction->CheckValue("path1", NULL)); | |
| 49 transaction->StoreHash("path1", NULL); | |
| 50 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 51 transaction->CheckValue("path1", NULL)); | |
| 52 EXPECT_EQ(PrefHashStoreTransaction::CHANGED, | |
| 53 transaction->CheckValue("path1", &string_2)); | |
| 54 | |
| 55 base::DictionaryValue dict; | |
| 56 dict.Set("a", new base::StringValue("foo")); | |
| 57 dict.Set("d", new base::StringValue("bad")); | |
| 58 dict.Set("b", new base::StringValue("bar")); | |
| 59 dict.Set("c", new base::StringValue("baz")); | |
| 60 | |
| 61 transaction->StoreHash("path1", &dict); | |
| 62 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 63 transaction->CheckValue("path1", &dict)); | |
| 64 } | |
| 65 | |
| 66 ASSERT_FALSE(CreateHashStoreContents()->GetSuperMac().empty()); | |
| 67 | |
| 68 { | |
| 69 // |pref_hash_store2| should trust its initial hashes dictionary and thus | |
| 70 // trust new unknown values. | |
| 71 PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true); | |
| 72 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 73 pref_hash_store2.BeginTransaction(CreateHashStoreContents())); | |
| 74 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE, | |
| 75 transaction->CheckValue("new_path", &string_1)); | |
| 76 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE, | |
| 77 transaction->CheckValue("new_path", &string_2)); | |
| 78 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE, | |
| 79 transaction->CheckValue("new_path", NULL)); | |
| 80 } | |
| 81 | |
| 82 // Manually corrupt the super MAC. | |
| 83 CreateHashStoreContents()->SetSuperMac(std::string(64, 'A')); | |
| 84 | |
| 85 { | |
| 86 // |pref_hash_store3| should no longer trust its initial hashes dictionary | |
| 87 // and thus shouldn't trust non-NULL unknown values. | |
| 88 PrefHashStoreImpl pref_hash_store3(std::string(32, 0), "device_id", true); | |
| 89 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 90 pref_hash_store3.BeginTransaction(CreateHashStoreContents())); | |
| 91 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 92 transaction->CheckValue("new_path", &string_1)); | |
| 93 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 94 transaction->CheckValue("new_path", &string_2)); | |
| 95 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE, | |
| 96 transaction->CheckValue("new_path", NULL)); | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 TEST_F(PrefHashStoreImplTest, ImportExportOperations) { | |
| 101 base::StringValue string_1("string1"); | |
| 102 base::StringValue string_2("string2"); | |
| 103 | |
| 104 // Initial state: no super MAC. | |
| 105 { | |
| 106 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 107 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 108 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 109 ASSERT_FALSE(transaction->IsSuperMACValid()); | |
| 110 | |
| 111 ASSERT_FALSE(transaction->HasHash("path1")); | |
| 112 | |
| 113 // Storing a hash will stamp the super MAC. | |
| 114 transaction->StoreHash("path1", &string_1); | |
| 115 | |
| 116 ASSERT_TRUE(transaction->HasHash("path1")); | |
| 117 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 118 transaction->CheckValue("path1", &string_1)); | |
| 119 EXPECT_EQ(PrefHashStoreTransaction::CHANGED, | |
| 120 transaction->CheckValue("path1", &string_2)); | |
| 121 } | |
| 122 | |
| 123 // Make a copy of the stored hash for future use. | |
| 124 const base::Value* hash = NULL; | |
| 125 ASSERT_TRUE(CreateHashStoreContents()->GetContents()->Get("path1", &hash)); | |
| 126 scoped_ptr<base::Value> path_1_string_1_hash_copy(hash->DeepCopy()); | |
| 127 hash = NULL; | |
| 128 | |
| 129 // Verify that the super MAC was stamped. | |
| 130 { | |
| 131 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 132 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 133 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 134 ASSERT_TRUE(transaction->IsSuperMACValid()); | |
| 135 ASSERT_TRUE(transaction->HasHash("path1")); | |
| 136 | |
| 137 // Clearing the hash should preserve validity. | |
| 138 transaction->ClearHash("path1"); | |
| 139 | |
| 140 // The effects of the clear should be immediately visible. | |
| 141 ASSERT_FALSE(transaction->HasHash("path1")); | |
| 142 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE, | |
| 143 transaction->CheckValue("path1", NULL)); | |
| 144 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE, | |
| 145 transaction->CheckValue("path1", &string_1)); | |
| 146 } | |
| 147 | |
| 148 // Verify that validity was preserved and that the clear took effect. | |
| 149 { | |
| 150 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 151 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 152 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 153 ASSERT_TRUE(transaction->IsSuperMACValid()); | |
| 154 ASSERT_FALSE(transaction->HasHash("path1")); | |
| 155 } | |
| 156 | |
| 157 // Invalidate the super MAC. | |
| 158 CreateHashStoreContents()->SetSuperMac(std::string()); | |
| 159 | |
| 160 { | |
| 161 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 162 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 163 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 164 ASSERT_FALSE(transaction->IsSuperMACValid()); | |
| 165 ASSERT_FALSE(transaction->HasHash("path1")); | |
| 166 | |
| 167 // An import should preserve invalidity. | |
| 168 transaction->ImportHash("path1", path_1_string_1_hash_copy.get()); | |
| 169 | |
| 170 ASSERT_TRUE(transaction->HasHash("path1")); | |
| 171 | |
| 172 // The imported hash should be usable for validating the original value. | |
| 173 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 174 transaction->CheckValue("path1", &string_1)); | |
| 175 } | |
| 176 | |
| 177 // Verify that invalidity was preserved and that the import took effect. | |
| 178 { | |
| 179 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 180 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 181 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 182 ASSERT_FALSE(transaction->IsSuperMACValid()); | |
| 183 ASSERT_TRUE(transaction->HasHash("path1")); | |
| 184 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 185 transaction->CheckValue("path1", &string_1)); | |
| 186 | |
| 187 // After clearing the hash, non-null values are UNTRUSTED_UNKNOWN. | |
| 188 transaction->ClearHash("path1"); | |
| 189 | |
| 190 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE, | |
| 191 transaction->CheckValue("path1", NULL)); | |
| 192 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 193 transaction->CheckValue("path1", &string_1)); | |
| 194 } | |
| 195 | |
| 196 { | |
| 197 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 198 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 199 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 200 ASSERT_FALSE(transaction->IsSuperMACValid()); | |
| 201 | |
| 202 // Test StampSuperMac. | |
| 203 transaction->StampSuperMac(); | |
| 204 } | |
| 205 | |
| 206 // Verify that the store is now valid. | |
| 207 { | |
| 208 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 209 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 210 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 211 ASSERT_TRUE(transaction->IsSuperMACValid()); | |
| 212 | |
| 213 // Store the hash of a different value to test an "over-import". | |
| 214 transaction->StoreHash("path1", &string_2); | |
| 215 EXPECT_EQ(PrefHashStoreTransaction::CHANGED, | |
| 216 transaction->CheckValue("path1", &string_1)); | |
| 217 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 218 transaction->CheckValue("path1", &string_2)); | |
| 219 } | |
| 220 | |
| 221 { | |
| 222 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 223 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 224 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 225 ASSERT_TRUE(transaction->IsSuperMACValid()); | |
| 226 | |
| 227 // "Over-import". An import should preserve validity. | |
| 228 transaction->ImportHash("path1", path_1_string_1_hash_copy.get()); | |
| 229 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 230 transaction->CheckValue("path1", &string_1)); | |
| 231 EXPECT_EQ(PrefHashStoreTransaction::CHANGED, | |
| 232 transaction->CheckValue("path1", &string_2)); | |
| 233 } | |
| 234 | |
| 235 // Verify that validity was preserved and the "over-import" took effect. | |
| 236 { | |
| 237 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 238 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 239 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 240 ASSERT_TRUE(transaction->IsSuperMACValid()); | |
| 241 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 242 transaction->CheckValue("path1", &string_1)); | |
| 243 EXPECT_EQ(PrefHashStoreTransaction::CHANGED, | |
| 244 transaction->CheckValue("path1", &string_2)); | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 TEST_F(PrefHashStoreImplTest, SuperMACDisabled) { | |
| 249 base::StringValue string_1("string1"); | |
| 250 base::StringValue string_2("string2"); | |
| 251 | |
| 252 { | |
| 253 // Pass |use_super_mac| => false. | |
| 254 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", false); | |
| 255 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 256 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 257 | |
| 258 transaction->StoreHash("path1", &string_2); | |
| 259 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 260 transaction->CheckValue("path1", &string_2)); | |
| 261 } | |
| 262 | |
| 263 ASSERT_TRUE(CreateHashStoreContents()->GetSuperMac().empty()); | |
| 264 | |
| 265 { | |
| 266 PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", false); | |
| 267 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 268 pref_hash_store2.BeginTransaction(CreateHashStoreContents())); | |
| 269 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 270 transaction->CheckValue("new_path", &string_1)); | |
| 271 } | |
| 272 } | |
| 273 | |
| 274 TEST_F(PrefHashStoreImplTest, SplitHashStoreAndCheck) { | |
| 275 base::DictionaryValue dict; | |
| 276 dict.Set("a", new base::StringValue("to be replaced")); | |
| 277 dict.Set("b", new base::StringValue("same")); | |
| 278 dict.Set("o", new base::StringValue("old")); | |
| 279 | |
| 280 base::DictionaryValue modified_dict; | |
| 281 modified_dict.Set("a", new base::StringValue("replaced")); | |
| 282 modified_dict.Set("b", new base::StringValue("same")); | |
| 283 modified_dict.Set("c", new base::StringValue("new")); | |
| 284 | |
| 285 base::DictionaryValue empty_dict; | |
| 286 | |
| 287 std::vector<std::string> invalid_keys; | |
| 288 | |
| 289 { | |
| 290 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 291 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 292 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 293 | |
| 294 // No hashes stored yet and hashes dictionary is empty (and thus not | |
| 295 // trusted). | |
| 296 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 297 transaction->CheckSplitValue("path1", &dict, &invalid_keys)); | |
| 298 EXPECT_TRUE(invalid_keys.empty()); | |
| 299 | |
| 300 transaction->StoreSplitHash("path1", &dict); | |
| 301 | |
| 302 // Verify match post storage. | |
| 303 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 304 transaction->CheckSplitValue("path1", &dict, &invalid_keys)); | |
| 305 EXPECT_TRUE(invalid_keys.empty()); | |
| 306 | |
| 307 // Verify new path is still unknown. | |
| 308 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 309 transaction->CheckSplitValue("path2", &dict, &invalid_keys)); | |
| 310 EXPECT_TRUE(invalid_keys.empty()); | |
| 311 | |
| 312 // Verify NULL or empty dicts are declared as having been cleared. | |
| 313 EXPECT_EQ(PrefHashStoreTransaction::CLEARED, | |
| 314 transaction->CheckSplitValue("path1", NULL, &invalid_keys)); | |
| 315 EXPECT_TRUE(invalid_keys.empty()); | |
| 316 EXPECT_EQ( | |
| 317 PrefHashStoreTransaction::CLEARED, | |
| 318 transaction->CheckSplitValue("path1", &empty_dict, &invalid_keys)); | |
| 319 EXPECT_TRUE(invalid_keys.empty()); | |
| 320 | |
| 321 // Verify changes are properly detected. | |
| 322 EXPECT_EQ( | |
| 323 PrefHashStoreTransaction::CHANGED, | |
| 324 transaction->CheckSplitValue("path1", &modified_dict, &invalid_keys)); | |
| 325 std::vector<std::string> expected_invalid_keys1; | |
| 326 expected_invalid_keys1.push_back("a"); | |
| 327 expected_invalid_keys1.push_back("c"); | |
| 328 expected_invalid_keys1.push_back("o"); | |
| 329 EXPECT_EQ(expected_invalid_keys1, invalid_keys); | |
| 330 invalid_keys.clear(); | |
| 331 | |
| 332 // Verify |dict| still matches post check. | |
| 333 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 334 transaction->CheckSplitValue("path1", &dict, &invalid_keys)); | |
| 335 EXPECT_TRUE(invalid_keys.empty()); | |
| 336 | |
| 337 // Store hash for |modified_dict|. | |
| 338 transaction->StoreSplitHash("path1", &modified_dict); | |
| 339 | |
| 340 // Verify |modified_dict| is now the one that verifies correctly. | |
| 341 EXPECT_EQ( | |
| 342 PrefHashStoreTransaction::UNCHANGED, | |
| 343 transaction->CheckSplitValue("path1", &modified_dict, &invalid_keys)); | |
| 344 EXPECT_TRUE(invalid_keys.empty()); | |
| 345 | |
| 346 // Verify old dict no longer matches. | |
| 347 EXPECT_EQ(PrefHashStoreTransaction::CHANGED, | |
| 348 transaction->CheckSplitValue("path1", &dict, &invalid_keys)); | |
| 349 std::vector<std::string> expected_invalid_keys2; | |
| 350 expected_invalid_keys2.push_back("a"); | |
| 351 expected_invalid_keys2.push_back("o"); | |
| 352 expected_invalid_keys2.push_back("c"); | |
| 353 EXPECT_EQ(expected_invalid_keys2, invalid_keys); | |
| 354 invalid_keys.clear(); | |
| 355 | |
| 356 } | |
| 357 | |
| 358 { | |
| 359 // |pref_hash_store2| should trust its initial hashes dictionary and thus | |
| 360 // trust new unknown values. | |
| 361 PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true); | |
| 362 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 363 pref_hash_store2.BeginTransaction(CreateHashStoreContents())); | |
| 364 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE, | |
| 365 transaction->CheckSplitValue("new_path", &dict, &invalid_keys)); | |
| 366 EXPECT_TRUE(invalid_keys.empty()); | |
| 367 } | |
| 368 | |
| 369 // Manually corrupt the super MAC. | |
| 370 CreateHashStoreContents()->SetSuperMac(std::string(64, 'A')); | |
| 371 | |
| 372 { | |
| 373 // |pref_hash_store3| should no longer trust its initial hashes dictionary | |
| 374 // and thus shouldn't trust unknown values. | |
| 375 PrefHashStoreImpl pref_hash_store3(std::string(32, 0), "device_id", true); | |
| 376 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 377 pref_hash_store3.BeginTransaction(CreateHashStoreContents())); | |
| 378 EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE, | |
| 379 transaction->CheckSplitValue("new_path", &dict, &invalid_keys)); | |
| 380 EXPECT_TRUE(invalid_keys.empty()); | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 TEST_F(PrefHashStoreImplTest, EmptyAndNULLSplitDict) { | |
| 385 base::DictionaryValue empty_dict; | |
| 386 | |
| 387 std::vector<std::string> invalid_keys; | |
| 388 | |
| 389 { | |
| 390 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 391 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 392 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 393 | |
| 394 // Store hashes for a random dict to be overwritten below. | |
| 395 base::DictionaryValue initial_dict; | |
| 396 initial_dict.Set("a", new base::StringValue("foo")); | |
| 397 transaction->StoreSplitHash("path1", &initial_dict); | |
| 398 | |
| 399 // Verify stored empty dictionary matches NULL and empty dictionary back. | |
| 400 transaction->StoreSplitHash("path1", &empty_dict); | |
| 401 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 402 transaction->CheckSplitValue("path1", NULL, &invalid_keys)); | |
| 403 EXPECT_TRUE(invalid_keys.empty()); | |
| 404 EXPECT_EQ( | |
| 405 PrefHashStoreTransaction::UNCHANGED, | |
| 406 transaction->CheckSplitValue("path1", &empty_dict, &invalid_keys)); | |
| 407 EXPECT_TRUE(invalid_keys.empty()); | |
| 408 | |
| 409 // Same when storing NULL directly. | |
| 410 transaction->StoreSplitHash("path1", NULL); | |
| 411 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 412 transaction->CheckSplitValue("path1", NULL, &invalid_keys)); | |
| 413 EXPECT_TRUE(invalid_keys.empty()); | |
| 414 EXPECT_EQ( | |
| 415 PrefHashStoreTransaction::UNCHANGED, | |
| 416 transaction->CheckSplitValue("path1", &empty_dict, &invalid_keys)); | |
| 417 EXPECT_TRUE(invalid_keys.empty()); | |
| 418 } | |
| 419 | |
| 420 { | |
| 421 // |pref_hash_store2| should trust its initial hashes dictionary (and thus | |
| 422 // trust new unknown values) even though the last action done was to clear | |
| 423 // the hashes for path1 by setting its value to NULL (this is a regression | |
| 424 // test ensuring that the internal action of clearing some hashes does | |
| 425 // update the stored hash of hashes). | |
| 426 PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true); | |
| 427 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 428 pref_hash_store2.BeginTransaction(CreateHashStoreContents())); | |
| 429 | |
| 430 base::DictionaryValue tested_dict; | |
| 431 tested_dict.Set("a", new base::StringValue("foo")); | |
| 432 tested_dict.Set("b", new base::StringValue("bar")); | |
| 433 EXPECT_EQ( | |
| 434 PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE, | |
| 435 transaction->CheckSplitValue("new_path", &tested_dict, &invalid_keys)); | |
| 436 EXPECT_TRUE(invalid_keys.empty()); | |
| 437 } | |
| 438 } | |
| 439 | |
| 440 // Test that the PrefHashStore returns TRUSTED_UNKNOWN_VALUE when checking for | |
| 441 // a split preference even if there is an existing atomic preference's hash | |
| 442 // stored. There is no point providing a migration path for preferences | |
| 443 // switching strategies after their initial release as split preferences are | |
| 444 // turned into split preferences specifically because the atomic hash isn't | |
| 445 // considered useful. | |
| 446 TEST_F(PrefHashStoreImplTest, TrustedUnknownSplitValueFromExistingAtomic) { | |
| 447 base::StringValue string("string1"); | |
| 448 | |
| 449 base::DictionaryValue dict; | |
| 450 dict.Set("a", new base::StringValue("foo")); | |
| 451 dict.Set("d", new base::StringValue("bad")); | |
| 452 dict.Set("b", new base::StringValue("bar")); | |
| 453 dict.Set("c", new base::StringValue("baz")); | |
| 454 | |
| 455 { | |
| 456 PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true); | |
| 457 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 458 pref_hash_store.BeginTransaction(CreateHashStoreContents())); | |
| 459 | |
| 460 transaction->StoreHash("path1", &string); | |
| 461 EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED, | |
| 462 transaction->CheckValue("path1", &string)); | |
| 463 } | |
| 464 | |
| 465 { | |
| 466 // Load a new |pref_hash_store2| in which the hashes dictionary is trusted. | |
| 467 PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true); | |
| 468 scoped_ptr<PrefHashStoreTransaction> transaction( | |
| 469 pref_hash_store2.BeginTransaction(CreateHashStoreContents())); | |
| 470 std::vector<std::string> invalid_keys; | |
| 471 EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE, | |
| 472 transaction->CheckSplitValue("path1", &dict, &invalid_keys)); | |
| 473 EXPECT_TRUE(invalid_keys.empty()); | |
| 474 } | |
| 475 } | |
| OLD | NEW |