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