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

Side by Side Diff: chrome/browser/prefs/tracked/pref_hash_filter_unittest.cc

Issue 1227973003: Componentize //chrome/browser/prefs/tracked. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 4 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
(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_filter.h"
6
7 #include <map>
8 #include <set>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/basictypes.h"
14 #include "base/bind.h"
15 #include "base/callback_forward.h"
16 #include "base/compiler_specific.h"
17 #include "base/logging.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/metrics/histogram_base.h"
21 #include "base/metrics/histogram_samples.h"
22 #include "base/metrics/statistics_recorder.h"
23 #include "base/prefs/testing_pref_store.h"
24 #include "base/values.h"
25 #include "chrome/browser/prefs/tracked/hash_store_contents.h"
26 #include "chrome/browser/prefs/tracked/mock_validation_delegate.h"
27 #include "chrome/browser/prefs/tracked/pref_hash_store.h"
28 #include "chrome/browser/prefs/tracked/pref_hash_store_transaction.h"
29 #include "chrome/common/pref_names.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 namespace {
33
34 const char kAtomicPref[] = "atomic_pref";
35 const char kAtomicPref2[] = "atomic_pref2";
36 const char kAtomicPref3[] = "pref3";
37 const char kAtomicPref4[] = "pref4";
38 const char kReportOnlyPref[] = "report_only";
39 const char kReportOnlySplitPref[] = "report_only_split_pref";
40 const char kSplitPref[] = "split_pref";
41
42 const PrefHashFilter::TrackedPreferenceMetadata kTestTrackedPrefs[] = {
43 {
44 0, kAtomicPref, PrefHashFilter::ENFORCE_ON_LOAD,
45 PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
46 PrefHashFilter::VALUE_PERSONAL
47 },
48 {
49 1, kReportOnlyPref, PrefHashFilter::NO_ENFORCEMENT,
50 PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
51 PrefHashFilter::VALUE_IMPERSONAL
52 },
53 {
54 2, kSplitPref, PrefHashFilter::ENFORCE_ON_LOAD,
55 PrefHashFilter::TRACKING_STRATEGY_SPLIT,
56 PrefHashFilter::VALUE_IMPERSONAL
57 },
58 {
59 3, kReportOnlySplitPref, PrefHashFilter::NO_ENFORCEMENT,
60 PrefHashFilter::TRACKING_STRATEGY_SPLIT,
61 PrefHashFilter::VALUE_IMPERSONAL
62 },
63 {
64 4, kAtomicPref2, PrefHashFilter::ENFORCE_ON_LOAD,
65 PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
66 PrefHashFilter::VALUE_IMPERSONAL
67 },
68 {
69 5, kAtomicPref3, PrefHashFilter::ENFORCE_ON_LOAD,
70 PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
71 PrefHashFilter::VALUE_IMPERSONAL
72 },
73 {
74 6, kAtomicPref4, PrefHashFilter::ENFORCE_ON_LOAD,
75 PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
76 PrefHashFilter::VALUE_IMPERSONAL
77 },
78 };
79
80 } // namespace
81
82 // A PrefHashStore that allows simulation of CheckValue results and captures
83 // checked and stored values.
84 class MockPrefHashStore : public PrefHashStore {
85 public:
86 typedef std::pair<const void*, PrefHashFilter::PrefTrackingStrategy>
87 ValuePtrStrategyPair;
88
89 MockPrefHashStore()
90 : stamp_super_mac_result_(false),
91 is_super_mac_valid_result_(false),
92 transactions_performed_(0),
93 transaction_active_(false) {}
94
95 ~MockPrefHashStore() override { EXPECT_FALSE(transaction_active_); }
96
97 // Set the result that will be returned when |path| is passed to
98 // |CheckValue/CheckSplitValue|.
99 void SetCheckResult(const std::string& path,
100 PrefHashStoreTransaction::ValueState result);
101
102 // Set the invalid_keys that will be returned when |path| is passed to
103 // |CheckSplitValue|. SetCheckResult should already have been called for
104 // |path| with |result == CHANGED| for this to make any sense.
105 void SetInvalidKeysResult(
106 const std::string& path,
107 const std::vector<std::string>& invalid_keys_result);
108
109 // Sets the value that will be returned from
110 // PrefHashStoreTransaction::StampSuperMAC().
111 void set_stamp_super_mac_result(bool result) {
112 stamp_super_mac_result_ = result;
113 }
114
115 // Sets the value that will be returned from
116 // PrefHashStoreTransaction::IsSuperMACValid().
117 void set_is_super_mac_valid_result(bool result) {
118 is_super_mac_valid_result_ = result;
119 }
120
121 // Returns the number of transactions that were performed.
122 size_t transactions_performed() { return transactions_performed_; }
123
124 // Returns the number of paths checked.
125 size_t checked_paths_count() const {
126 return checked_values_.size();
127 }
128
129 // Returns the number of paths stored.
130 size_t stored_paths_count() const {
131 return stored_values_.size();
132 }
133
134 // Returns the pointer value and strategy that was passed to
135 // |CheckHash/CheckSplitHash| for |path|. The returned pointer could since
136 // have been freed and is thus not safe to dereference.
137 ValuePtrStrategyPair checked_value(const std::string& path) const {
138 std::map<std::string, ValuePtrStrategyPair>::const_iterator value =
139 checked_values_.find(path);
140 if (value != checked_values_.end())
141 return value->second;
142 return std::make_pair(
143 reinterpret_cast<void*>(0xBAD),
144 static_cast<PrefHashFilter::PrefTrackingStrategy>(-1));
145 }
146
147 // Returns the pointer value that was passed to |StoreHash/StoreSplitHash| for
148 // |path|. The returned pointer could since have been freed and is thus not
149 // safe to dereference.
150 ValuePtrStrategyPair stored_value(const std::string& path) const {
151 std::map<std::string, ValuePtrStrategyPair>::const_iterator value =
152 stored_values_.find(path);
153 if (value != stored_values_.end())
154 return value->second;
155 return std::make_pair(
156 reinterpret_cast<void*>(0xBAD),
157 static_cast<PrefHashFilter::PrefTrackingStrategy>(-1));
158 }
159
160 // PrefHashStore implementation.
161 scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
162 scoped_ptr<HashStoreContents> storage) override;
163
164 private:
165 // A MockPrefHashStoreTransaction is handed to the caller on
166 // MockPrefHashStore::BeginTransaction(). It then stores state in its
167 // underlying MockPrefHashStore about calls it receives from that same caller
168 // which can later be verified in tests.
169 class MockPrefHashStoreTransaction : public PrefHashStoreTransaction {
170 public:
171 explicit MockPrefHashStoreTransaction(MockPrefHashStore* outer)
172 : outer_(outer) {}
173
174 ~MockPrefHashStoreTransaction() override {
175 outer_->transaction_active_ = false;
176 ++outer_->transactions_performed_;
177 }
178
179 // PrefHashStoreTransaction implementation.
180 PrefHashStoreTransaction::ValueState CheckValue(
181 const std::string& path,
182 const base::Value* value) const override;
183 void StoreHash(const std::string& path,
184 const base::Value* new_value) override;
185 PrefHashStoreTransaction::ValueState CheckSplitValue(
186 const std::string& path,
187 const base::DictionaryValue* initial_split_value,
188 std::vector<std::string>* invalid_keys) const override;
189 void StoreSplitHash(const std::string& path,
190 const base::DictionaryValue* split_value) override;
191 bool HasHash(const std::string& path) const override;
192 void ImportHash(const std::string& path, const base::Value* hash) override;
193 void ClearHash(const std::string& path) override;
194 bool IsSuperMACValid() const override;
195 bool StampSuperMac() override;
196
197 private:
198 MockPrefHashStore* outer_;
199
200 DISALLOW_COPY_AND_ASSIGN(MockPrefHashStoreTransaction);
201 };
202
203 // Records a call to this mock's CheckValue/CheckSplitValue methods.
204 PrefHashStoreTransaction::ValueState RecordCheckValue(
205 const std::string& path,
206 const base::Value* value,
207 PrefHashFilter::PrefTrackingStrategy strategy);
208
209 // Records a call to this mock's StoreHash/StoreSplitHash methods.
210 void RecordStoreHash(const std::string& path,
211 const base::Value* new_value,
212 PrefHashFilter::PrefTrackingStrategy strategy);
213
214 std::map<std::string, PrefHashStoreTransaction::ValueState> check_results_;
215 std::map<std::string, std::vector<std::string> > invalid_keys_results_;
216
217 bool stamp_super_mac_result_;
218 bool is_super_mac_valid_result_;
219
220 std::map<std::string, ValuePtrStrategyPair> checked_values_;
221 std::map<std::string, ValuePtrStrategyPair> stored_values_;
222
223 // Number of transactions that were performed via this MockPrefHashStore.
224 size_t transactions_performed_;
225
226 // Whether a transaction is currently active (only one transaction should be
227 // active at a time).
228 bool transaction_active_;
229
230 DISALLOW_COPY_AND_ASSIGN(MockPrefHashStore);
231 };
232
233 void MockPrefHashStore::SetCheckResult(
234 const std::string& path, PrefHashStoreTransaction::ValueState result) {
235 check_results_.insert(std::make_pair(path, result));
236 }
237
238 void MockPrefHashStore::SetInvalidKeysResult(
239 const std::string& path,
240 const std::vector<std::string>& invalid_keys_result) {
241 // Ensure |check_results_| has a CHANGED entry for |path|.
242 std::map<std::string,
243 PrefHashStoreTransaction::ValueState>::const_iterator result =
244 check_results_.find(path);
245 ASSERT_TRUE(result != check_results_.end());
246 ASSERT_EQ(PrefHashStoreTransaction::CHANGED, result->second);
247
248 invalid_keys_results_.insert(std::make_pair(path, invalid_keys_result));
249 }
250
251 scoped_ptr<PrefHashStoreTransaction> MockPrefHashStore::BeginTransaction(
252 scoped_ptr<HashStoreContents> storage) {
253 EXPECT_FALSE(transaction_active_);
254 return scoped_ptr<PrefHashStoreTransaction>(
255 new MockPrefHashStoreTransaction(this));
256 }
257
258 PrefHashStoreTransaction::ValueState MockPrefHashStore::RecordCheckValue(
259 const std::string& path,
260 const base::Value* value,
261 PrefHashFilter::PrefTrackingStrategy strategy) {
262 // Record that |path| was checked and validate that it wasn't previously
263 // checked.
264 EXPECT_TRUE(checked_values_.insert(
265 std::make_pair(path, std::make_pair(value, strategy))).second);
266 std::map<std::string,
267 PrefHashStoreTransaction::ValueState>::const_iterator result =
268 check_results_.find(path);
269 if (result != check_results_.end())
270 return result->second;
271 return PrefHashStoreTransaction::UNCHANGED;
272 }
273
274 void MockPrefHashStore::RecordStoreHash(
275 const std::string& path,
276 const base::Value* new_value,
277 PrefHashFilter::PrefTrackingStrategy strategy) {
278 EXPECT_TRUE(stored_values_.insert(
279 std::make_pair(path, std::make_pair(new_value, strategy))).second);
280 }
281
282 PrefHashStoreTransaction::ValueState
283 MockPrefHashStore::MockPrefHashStoreTransaction::CheckValue(
284 const std::string& path, const base::Value* value) const {
285 return outer_->RecordCheckValue(path, value,
286 PrefHashFilter::TRACKING_STRATEGY_ATOMIC);
287 }
288
289 void MockPrefHashStore::MockPrefHashStoreTransaction::StoreHash(
290 const std::string& path,
291 const base::Value* new_value) {
292 outer_->RecordStoreHash(path, new_value,
293 PrefHashFilter::TRACKING_STRATEGY_ATOMIC);
294 }
295
296 PrefHashStoreTransaction::ValueState
297 MockPrefHashStore::MockPrefHashStoreTransaction::CheckSplitValue(
298 const std::string& path,
299 const base::DictionaryValue* initial_split_value,
300 std::vector<std::string>* invalid_keys) const {
301 EXPECT_TRUE(invalid_keys && invalid_keys->empty());
302
303 std::map<std::string, std::vector<std::string> >::const_iterator
304 invalid_keys_result = outer_->invalid_keys_results_.find(path);
305 if (invalid_keys_result != outer_->invalid_keys_results_.end()) {
306 invalid_keys->insert(invalid_keys->begin(),
307 invalid_keys_result->second.begin(),
308 invalid_keys_result->second.end());
309 }
310
311 return outer_->RecordCheckValue(path, initial_split_value,
312 PrefHashFilter::TRACKING_STRATEGY_SPLIT);
313 }
314
315 void MockPrefHashStore::MockPrefHashStoreTransaction::StoreSplitHash(
316 const std::string& path,
317 const base::DictionaryValue* new_value) {
318 outer_->RecordStoreHash(path, new_value,
319 PrefHashFilter::TRACKING_STRATEGY_SPLIT);
320 }
321
322 bool MockPrefHashStore::MockPrefHashStoreTransaction::HasHash(
323 const std::string& path) const {
324 ADD_FAILURE() << "Unexpected call.";
325 return false;
326 }
327
328 void MockPrefHashStore::MockPrefHashStoreTransaction::ImportHash(
329 const std::string& path,
330 const base::Value* hash) {
331 ADD_FAILURE() << "Unexpected call.";
332 }
333
334 void MockPrefHashStore::MockPrefHashStoreTransaction::ClearHash(
335 const std::string& path) {
336 // Allow this to be called by PrefHashFilter's deprecated tracked prefs
337 // cleanup tasks.
338 }
339
340 bool MockPrefHashStore::MockPrefHashStoreTransaction::IsSuperMACValid() const {
341 return outer_->is_super_mac_valid_result_;
342 }
343
344 bool MockPrefHashStore::MockPrefHashStoreTransaction::StampSuperMac() {
345 return outer_->stamp_super_mac_result_;
346 }
347
348 std::vector<PrefHashFilter::TrackedPreferenceMetadata> GetConfiguration(
349 PrefHashFilter::EnforcementLevel max_enforcement_level) {
350 std::vector<PrefHashFilter::TrackedPreferenceMetadata> configuration(
351 kTestTrackedPrefs, kTestTrackedPrefs + arraysize(kTestTrackedPrefs));
352 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it =
353 configuration.begin();
354 it != configuration.end();
355 ++it) {
356 if (it->enforcement_level > max_enforcement_level)
357 it->enforcement_level = max_enforcement_level;
358 }
359 return configuration;
360 }
361
362 class PrefHashFilterTest
363 : public testing::TestWithParam<PrefHashFilter::EnforcementLevel> {
364 public:
365 PrefHashFilterTest() : mock_pref_hash_store_(NULL),
366 pref_store_contents_(new base::DictionaryValue),
367 reset_recorded_(false) {}
368
369 void SetUp() override {
370 base::StatisticsRecorder::Initialize();
371 Reset();
372 }
373
374 protected:
375 // Reset the PrefHashFilter instance.
376 void Reset() {
377 // Construct a PrefHashFilter and MockPrefHashStore for the test.
378 InitializePrefHashFilter(GetConfiguration(GetParam()));
379 }
380
381 // Initializes |pref_hash_filter_| with a PrefHashFilter that uses a
382 // MockPrefHashStore. The raw pointer to the MockPrefHashStore (owned by the
383 // PrefHashFilter) is stored in |mock_pref_hash_store_|.
384 void InitializePrefHashFilter(const std::vector<
385 PrefHashFilter::TrackedPreferenceMetadata>& configuration) {
386 scoped_ptr<MockPrefHashStore> temp_mock_pref_hash_store(
387 new MockPrefHashStore);
388 mock_pref_hash_store_ = temp_mock_pref_hash_store.get();
389 pref_hash_filter_.reset(new PrefHashFilter(
390 temp_mock_pref_hash_store.Pass(),
391 configuration,
392 base::Bind(&PrefHashFilterTest::RecordReset, base::Unretained(this)),
393 &mock_validation_delegate_,
394 arraysize(kTestTrackedPrefs),
395 true));
396 }
397
398 // Verifies whether a reset was reported by the PrefHashFiler. Also verifies
399 // that kPreferenceResetTime was set (or not) accordingly.
400 void VerifyRecordedReset(bool reset_expected) {
401 EXPECT_EQ(reset_expected, reset_recorded_);
402 EXPECT_EQ(reset_expected,
403 pref_store_contents_->Get(prefs::kPreferenceResetTime, NULL));
404 }
405
406 // Calls FilterOnLoad() on |pref_hash_Filter_|. |pref_store_contents_| is
407 // handed off, but should be given back to us synchronously through
408 // GetPrefsBack() as there is no FilterOnLoadInterceptor installed on
409 // |pref_hash_filter_|.
410 void DoFilterOnLoad(bool expect_prefs_modifications) {
411 pref_hash_filter_->FilterOnLoad(
412 base::Bind(&PrefHashFilterTest::GetPrefsBack, base::Unretained(this),
413 expect_prefs_modifications),
414 pref_store_contents_.Pass());
415 }
416
417 MockPrefHashStore* mock_pref_hash_store_;
418 scoped_ptr<base::DictionaryValue> pref_store_contents_;
419 MockValidationDelegate mock_validation_delegate_;
420 scoped_ptr<PrefHashFilter> pref_hash_filter_;
421
422 private:
423 // Stores |prefs| back in |pref_store_contents| and ensure
424 // |expected_schedule_write| matches the reported |schedule_write|.
425 void GetPrefsBack(bool expected_schedule_write,
426 scoped_ptr<base::DictionaryValue> prefs,
427 bool schedule_write) {
428 pref_store_contents_ = prefs.Pass();
429 EXPECT_TRUE(pref_store_contents_);
430 EXPECT_EQ(expected_schedule_write, schedule_write);
431 }
432
433 void RecordReset() {
434 // As-is |reset_recorded_| is only designed to remember a single reset, make
435 // sure none was previously recorded.
436 EXPECT_FALSE(reset_recorded_);
437 reset_recorded_ = true;
438 }
439
440 bool reset_recorded_;
441
442 DISALLOW_COPY_AND_ASSIGN(PrefHashFilterTest);
443 };
444
445 TEST_P(PrefHashFilterTest, EmptyAndUnchanged) {
446 DoFilterOnLoad(false);
447 // All paths checked.
448 ASSERT_EQ(arraysize(kTestTrackedPrefs),
449 mock_pref_hash_store_->checked_paths_count());
450 // No paths stored, since they all return |UNCHANGED|.
451 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
452 // Since there was nothing in |pref_store_contents_| the checked value should
453 // have been NULL for all tracked preferences.
454 for (size_t i = 0; i < arraysize(kTestTrackedPrefs); ++i) {
455 ASSERT_EQ(NULL, mock_pref_hash_store_->checked_value(
456 kTestTrackedPrefs[i].name).first);
457 }
458 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
459 VerifyRecordedReset(false);
460
461 // Delegate saw all paths, and all unchanged.
462 ASSERT_EQ(arraysize(kTestTrackedPrefs),
463 mock_validation_delegate_.recorded_validations_count());
464 ASSERT_EQ(arraysize(kTestTrackedPrefs),
465 mock_validation_delegate_.CountValidationsOfState(
466 PrefHashStoreTransaction::UNCHANGED));
467 }
468
469 TEST_P(PrefHashFilterTest, StampSuperMACAltersStore) {
470 mock_pref_hash_store_->set_stamp_super_mac_result(true);
471 DoFilterOnLoad(true);
472 // No paths stored, since they all return |UNCHANGED|. The StampSuperMAC
473 // result is the only reason the prefs were considered altered.
474 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
475 }
476
477 TEST_P(PrefHashFilterTest, FilterTrackedPrefUpdate) {
478 base::DictionaryValue root_dict;
479 // Ownership of |string_value| is transfered to |root_dict|.
480 base::Value* string_value = new base::StringValue("string value");
481 root_dict.Set(kAtomicPref, string_value);
482
483 // No path should be stored on FilterUpdate.
484 pref_hash_filter_->FilterUpdate(kAtomicPref);
485 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
486
487 // One path should be stored on FilterSerializeData.
488 pref_hash_filter_->FilterSerializeData(&root_dict);
489 ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count());
490 MockPrefHashStore::ValuePtrStrategyPair stored_value =
491 mock_pref_hash_store_->stored_value(kAtomicPref);
492 ASSERT_EQ(string_value, stored_value.first);
493 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, stored_value.second);
494
495 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
496 VerifyRecordedReset(false);
497 }
498
499 TEST_P(PrefHashFilterTest, ReportSuperMacValidity) {
500 // Do this once just to force the histogram to be defined.
501 DoFilterOnLoad(false);
502
503 base::HistogramBase* histogram = base::StatisticsRecorder::FindHistogram(
504 "Settings.HashesDictionaryTrusted");
505 ASSERT_TRUE(histogram);
506
507 base::HistogramBase::Count initial_untrusted =
508 histogram->SnapshotSamples()->GetCount(0);
509 base::HistogramBase::Count initial_trusted =
510 histogram->SnapshotSamples()->GetCount(1);
511
512 Reset();
513
514 // Run with an invalid super MAC.
515 mock_pref_hash_store_->set_is_super_mac_valid_result(false);
516
517 DoFilterOnLoad(false);
518
519 // Verify that the invalidity was reported.
520 ASSERT_EQ(initial_untrusted + 1, histogram->SnapshotSamples()->GetCount(0));
521 ASSERT_EQ(initial_trusted, histogram->SnapshotSamples()->GetCount(1));
522
523 Reset();
524
525 // Run with a valid super MAC.
526 mock_pref_hash_store_->set_is_super_mac_valid_result(true);
527
528 DoFilterOnLoad(false);
529
530 // Verify that the validity was reported.
531 ASSERT_EQ(initial_untrusted + 1, histogram->SnapshotSamples()->GetCount(0));
532 ASSERT_EQ(initial_trusted + 1, histogram->SnapshotSamples()->GetCount(1));
533 }
534
535 TEST_P(PrefHashFilterTest, FilterSplitPrefUpdate) {
536 base::DictionaryValue root_dict;
537 // Ownership of |dict_value| is transfered to |root_dict|.
538 base::DictionaryValue* dict_value = new base::DictionaryValue;
539 dict_value->SetString("a", "foo");
540 dict_value->SetInteger("b", 1234);
541 root_dict.Set(kSplitPref, dict_value);
542
543 // No path should be stored on FilterUpdate.
544 pref_hash_filter_->FilterUpdate(kSplitPref);
545 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
546
547 // One path should be stored on FilterSerializeData.
548 pref_hash_filter_->FilterSerializeData(&root_dict);
549 ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count());
550 MockPrefHashStore::ValuePtrStrategyPair stored_value =
551 mock_pref_hash_store_->stored_value(kSplitPref);
552 ASSERT_EQ(dict_value, stored_value.first);
553 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value.second);
554
555 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
556 VerifyRecordedReset(false);
557 }
558
559 TEST_P(PrefHashFilterTest, FilterUntrackedPrefUpdate) {
560 base::DictionaryValue root_dict;
561 root_dict.Set("untracked", new base::StringValue("some value"));
562 pref_hash_filter_->FilterUpdate("untracked");
563
564 // No paths should be stored on FilterUpdate.
565 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
566
567 // Nor on FilterSerializeData.
568 pref_hash_filter_->FilterSerializeData(&root_dict);
569 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
570
571 // No transaction should even be started on FilterSerializeData() if there are
572 // no updates to perform.
573 ASSERT_EQ(0u, mock_pref_hash_store_->transactions_performed());
574 }
575
576 TEST_P(PrefHashFilterTest, MultiplePrefsFilterSerializeData) {
577 base::DictionaryValue root_dict;
578 // Ownership of the following values is transfered to |root_dict|.
579 base::Value* int_value1 = new base::FundamentalValue(1);
580 base::Value* int_value2 = new base::FundamentalValue(2);
581 base::Value* int_value3 = new base::FundamentalValue(3);
582 base::Value* int_value4 = new base::FundamentalValue(4);
583 base::DictionaryValue* dict_value = new base::DictionaryValue;
584 dict_value->Set("a", new base::FundamentalValue(true));
585 root_dict.Set(kAtomicPref, int_value1);
586 root_dict.Set(kAtomicPref2, int_value2);
587 root_dict.Set(kAtomicPref3, int_value3);
588 root_dict.Set("untracked", int_value4);
589 root_dict.Set(kSplitPref, dict_value);
590
591 // Only update kAtomicPref, kAtomicPref3, and kSplitPref.
592 pref_hash_filter_->FilterUpdate(kAtomicPref);
593 pref_hash_filter_->FilterUpdate(kAtomicPref3);
594 pref_hash_filter_->FilterUpdate(kSplitPref);
595 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
596
597 // Update kAtomicPref3 again, nothing should be stored still.
598 base::Value* int_value5 = new base::FundamentalValue(5);
599 root_dict.Set(kAtomicPref3, int_value5);
600 ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
601
602 // On FilterSerializeData, only kAtomicPref, kAtomicPref3, and kSplitPref
603 // should get a new hash.
604 pref_hash_filter_->FilterSerializeData(&root_dict);
605 ASSERT_EQ(3u, mock_pref_hash_store_->stored_paths_count());
606 MockPrefHashStore::ValuePtrStrategyPair stored_value_atomic1 =
607 mock_pref_hash_store_->stored_value(kAtomicPref);
608 ASSERT_EQ(int_value1, stored_value_atomic1.first);
609 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
610 stored_value_atomic1.second);
611 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
612
613 MockPrefHashStore::ValuePtrStrategyPair stored_value_atomic3 =
614 mock_pref_hash_store_->stored_value(kAtomicPref3);
615 ASSERT_EQ(int_value5, stored_value_atomic3.first);
616 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
617 stored_value_atomic3.second);
618
619 MockPrefHashStore::ValuePtrStrategyPair stored_value_split =
620 mock_pref_hash_store_->stored_value(kSplitPref);
621 ASSERT_EQ(dict_value, stored_value_split.first);
622 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value_split.second);
623 }
624
625 TEST_P(PrefHashFilterTest, UnknownNullValue) {
626 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
627 ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
628 // NULL values are always trusted by the PrefHashStore.
629 mock_pref_hash_store_->SetCheckResult(
630 kAtomicPref, PrefHashStoreTransaction::TRUSTED_NULL_VALUE);
631 mock_pref_hash_store_->SetCheckResult(
632 kSplitPref, PrefHashStoreTransaction::TRUSTED_NULL_VALUE);
633 DoFilterOnLoad(false);
634 ASSERT_EQ(arraysize(kTestTrackedPrefs),
635 mock_pref_hash_store_->checked_paths_count());
636 ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
637 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
638
639 MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
640 mock_pref_hash_store_->stored_value(kAtomicPref);
641 ASSERT_EQ(NULL, stored_atomic_value.first);
642 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
643 stored_atomic_value.second);
644
645 MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
646 mock_pref_hash_store_->stored_value(kSplitPref);
647 ASSERT_EQ(NULL, stored_split_value.first);
648 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
649 stored_split_value.second);
650
651 // Delegate saw all prefs, two of which had the expected value_state.
652 ASSERT_EQ(arraysize(kTestTrackedPrefs),
653 mock_validation_delegate_.recorded_validations_count());
654 ASSERT_EQ(2u,
655 mock_validation_delegate_.CountValidationsOfState(
656 PrefHashStoreTransaction::TRUSTED_NULL_VALUE));
657 ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
658 mock_validation_delegate_.CountValidationsOfState(
659 PrefHashStoreTransaction::UNCHANGED));
660
661 const MockValidationDelegate::ValidationEvent* validated_split_pref =
662 mock_validation_delegate_.GetEventForPath(kSplitPref);
663 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
664 validated_split_pref->strategy);
665 ASSERT_FALSE(validated_split_pref->is_personal);
666 const MockValidationDelegate::ValidationEvent* validated_atomic_pref =
667 mock_validation_delegate_.GetEventForPath(kAtomicPref);
668 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
669 validated_atomic_pref->strategy);
670 ASSERT_TRUE(validated_atomic_pref->is_personal);
671 }
672
673 TEST_P(PrefHashFilterTest, InitialValueUnknown) {
674 // Ownership of these values is transfered to |pref_store_contents_|.
675 base::StringValue* string_value = new base::StringValue("string value");
676 pref_store_contents_->Set(kAtomicPref, string_value);
677
678 base::DictionaryValue* dict_value = new base::DictionaryValue;
679 dict_value->SetString("a", "foo");
680 dict_value->SetInteger("b", 1234);
681 pref_store_contents_->Set(kSplitPref, dict_value);
682
683 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
684 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
685
686 mock_pref_hash_store_->SetCheckResult(
687 kAtomicPref, PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE);
688 mock_pref_hash_store_->SetCheckResult(
689 kSplitPref, PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE);
690 // If we are enforcing, expect this to report changes.
691 DoFilterOnLoad(GetParam() >= PrefHashFilter::ENFORCE_ON_LOAD);
692 ASSERT_EQ(arraysize(kTestTrackedPrefs),
693 mock_pref_hash_store_->checked_paths_count());
694 ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
695 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
696
697 // Delegate saw all prefs, two of which had the expected value_state.
698 ASSERT_EQ(arraysize(kTestTrackedPrefs),
699 mock_validation_delegate_.recorded_validations_count());
700 ASSERT_EQ(2u,
701 mock_validation_delegate_.CountValidationsOfState(
702 PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE));
703 ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
704 mock_validation_delegate_.CountValidationsOfState(
705 PrefHashStoreTransaction::UNCHANGED));
706
707 MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
708 mock_pref_hash_store_->stored_value(kAtomicPref);
709 MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
710 mock_pref_hash_store_->stored_value(kSplitPref);
711 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
712 stored_atomic_value.second);
713 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
714 stored_split_value.second);
715 if (GetParam() == PrefHashFilter::ENFORCE_ON_LOAD) {
716 // Ensure the prefs were cleared and the hashes for NULL were restored if
717 // the current enforcement level denies seeding.
718 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
719 ASSERT_EQ(NULL, stored_atomic_value.first);
720
721 ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
722 ASSERT_EQ(NULL, stored_split_value.first);
723
724 VerifyRecordedReset(true);
725 } else {
726 // Otherwise the values should have remained intact and the hashes should
727 // have been updated to match them.
728 const base::Value* atomic_value_in_store;
729 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
730 ASSERT_EQ(string_value, atomic_value_in_store);
731 ASSERT_EQ(string_value, stored_atomic_value.first);
732
733 const base::Value* split_value_in_store;
734 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
735 ASSERT_EQ(dict_value, split_value_in_store);
736 ASSERT_EQ(dict_value, stored_split_value.first);
737
738 VerifyRecordedReset(false);
739 }
740 }
741
742 TEST_P(PrefHashFilterTest, InitialValueTrustedUnknown) {
743 // Ownership of this value is transfered to |pref_store_contents_|.
744 base::Value* string_value = new base::StringValue("test");
745 pref_store_contents_->Set(kAtomicPref, string_value);
746
747 base::DictionaryValue* dict_value = new base::DictionaryValue;
748 dict_value->SetString("a", "foo");
749 dict_value->SetInteger("b", 1234);
750 pref_store_contents_->Set(kSplitPref, dict_value);
751
752 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
753 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
754
755 mock_pref_hash_store_->SetCheckResult(
756 kAtomicPref, PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE);
757 mock_pref_hash_store_->SetCheckResult(
758 kSplitPref, PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE);
759 DoFilterOnLoad(false);
760 ASSERT_EQ(arraysize(kTestTrackedPrefs),
761 mock_pref_hash_store_->checked_paths_count());
762 ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
763 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
764
765 // Delegate saw all prefs, two of which had the expected value_state.
766 ASSERT_EQ(arraysize(kTestTrackedPrefs),
767 mock_validation_delegate_.recorded_validations_count());
768 ASSERT_EQ(2u,
769 mock_validation_delegate_.CountValidationsOfState(
770 PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE));
771 ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
772 mock_validation_delegate_.CountValidationsOfState(
773 PrefHashStoreTransaction::UNCHANGED));
774
775 // Seeding is always allowed for trusted unknown values.
776 const base::Value* atomic_value_in_store;
777 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
778 ASSERT_EQ(string_value, atomic_value_in_store);
779 MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
780 mock_pref_hash_store_->stored_value(kAtomicPref);
781 ASSERT_EQ(string_value, stored_atomic_value.first);
782 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
783 stored_atomic_value.second);
784
785 const base::Value* split_value_in_store;
786 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
787 ASSERT_EQ(dict_value, split_value_in_store);
788 MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
789 mock_pref_hash_store_->stored_value(kSplitPref);
790 ASSERT_EQ(dict_value, stored_split_value.first);
791 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
792 stored_split_value.second);
793 }
794
795 TEST_P(PrefHashFilterTest, InitialValueChanged) {
796 // Ownership of this value is transfered to |pref_store_contents_|.
797 base::Value* int_value = new base::FundamentalValue(1234);
798 pref_store_contents_->Set(kAtomicPref, int_value);
799
800 base::DictionaryValue* dict_value = new base::DictionaryValue;
801 dict_value->SetString("a", "foo");
802 dict_value->SetInteger("b", 1234);
803 dict_value->SetInteger("c", 56);
804 dict_value->SetBoolean("d", false);
805 pref_store_contents_->Set(kSplitPref, dict_value);
806
807 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
808 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
809
810 mock_pref_hash_store_->SetCheckResult(kAtomicPref,
811 PrefHashStoreTransaction::CHANGED);
812 mock_pref_hash_store_->SetCheckResult(kSplitPref,
813 PrefHashStoreTransaction::CHANGED);
814
815 std::vector<std::string> mock_invalid_keys;
816 mock_invalid_keys.push_back("a");
817 mock_invalid_keys.push_back("c");
818 mock_pref_hash_store_->SetInvalidKeysResult(kSplitPref, mock_invalid_keys);
819
820 DoFilterOnLoad(GetParam() >= PrefHashFilter::ENFORCE_ON_LOAD);
821 ASSERT_EQ(arraysize(kTestTrackedPrefs),
822 mock_pref_hash_store_->checked_paths_count());
823 ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
824 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
825
826 MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
827 mock_pref_hash_store_->stored_value(kAtomicPref);
828 MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
829 mock_pref_hash_store_->stored_value(kSplitPref);
830 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
831 stored_atomic_value.second);
832 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
833 stored_split_value.second);
834 if (GetParam() == PrefHashFilter::ENFORCE_ON_LOAD) {
835 // Ensure the atomic pref was cleared and the hash for NULL was restored if
836 // the current enforcement level prevents changes.
837 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
838 ASSERT_EQ(NULL, stored_atomic_value.first);
839
840 // The split pref on the other hand should only have been stripped of its
841 // invalid keys.
842 const base::Value* split_value_in_store;
843 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
844 ASSERT_EQ(2U, dict_value->size());
845 ASSERT_FALSE(dict_value->HasKey("a"));
846 ASSERT_TRUE(dict_value->HasKey("b"));
847 ASSERT_FALSE(dict_value->HasKey("c"));
848 ASSERT_TRUE(dict_value->HasKey("d"));
849 ASSERT_EQ(dict_value, stored_split_value.first);
850
851 VerifyRecordedReset(true);
852 } else {
853 // Otherwise the value should have remained intact and the hash should have
854 // been updated to match it.
855 const base::Value* atomic_value_in_store;
856 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
857 ASSERT_EQ(int_value, atomic_value_in_store);
858 ASSERT_EQ(int_value, stored_atomic_value.first);
859
860 const base::Value* split_value_in_store;
861 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
862 ASSERT_EQ(dict_value, split_value_in_store);
863 ASSERT_EQ(4U, dict_value->size());
864 ASSERT_TRUE(dict_value->HasKey("a"));
865 ASSERT_TRUE(dict_value->HasKey("b"));
866 ASSERT_TRUE(dict_value->HasKey("c"));
867 ASSERT_TRUE(dict_value->HasKey("d"));
868 ASSERT_EQ(dict_value, stored_split_value.first);
869
870 VerifyRecordedReset(false);
871 }
872 }
873
874 TEST_P(PrefHashFilterTest, EmptyCleared) {
875 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
876 ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
877 mock_pref_hash_store_->SetCheckResult(kAtomicPref,
878 PrefHashStoreTransaction::CLEARED);
879 mock_pref_hash_store_->SetCheckResult(kSplitPref,
880 PrefHashStoreTransaction::CLEARED);
881 DoFilterOnLoad(false);
882 ASSERT_EQ(arraysize(kTestTrackedPrefs),
883 mock_pref_hash_store_->checked_paths_count());
884 ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
885 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
886
887 // Delegate saw all prefs, two of which had the expected value_state.
888 ASSERT_EQ(arraysize(kTestTrackedPrefs),
889 mock_validation_delegate_.recorded_validations_count());
890 ASSERT_EQ(2u,
891 mock_validation_delegate_.CountValidationsOfState(
892 PrefHashStoreTransaction::CLEARED));
893 ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
894 mock_validation_delegate_.CountValidationsOfState(
895 PrefHashStoreTransaction::UNCHANGED));
896
897 // Regardless of the enforcement level, the only thing that should be done is
898 // to restore the hash for NULL. The value itself should still be NULL.
899 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
900 MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
901 mock_pref_hash_store_->stored_value(kAtomicPref);
902 ASSERT_EQ(NULL, stored_atomic_value.first);
903 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
904 stored_atomic_value.second);
905
906 ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
907 MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
908 mock_pref_hash_store_->stored_value(kSplitPref);
909 ASSERT_EQ(NULL, stored_split_value.first);
910 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
911 stored_split_value.second);
912 }
913
914 TEST_P(PrefHashFilterTest, InitialValueUnchangedLegacyId) {
915 // Ownership of these values is transfered to |pref_store_contents_|.
916 base::StringValue* string_value = new base::StringValue("string value");
917 pref_store_contents_->Set(kAtomicPref, string_value);
918
919 base::DictionaryValue* dict_value = new base::DictionaryValue;
920 dict_value->SetString("a", "foo");
921 dict_value->SetInteger("b", 1234);
922 pref_store_contents_->Set(kSplitPref, dict_value);
923
924 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
925 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
926
927 mock_pref_hash_store_->SetCheckResult(
928 kAtomicPref, PrefHashStoreTransaction::SECURE_LEGACY);
929 mock_pref_hash_store_->SetCheckResult(
930 kSplitPref, PrefHashStoreTransaction::SECURE_LEGACY);
931 DoFilterOnLoad(false);
932 ASSERT_EQ(arraysize(kTestTrackedPrefs),
933 mock_pref_hash_store_->checked_paths_count());
934 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
935
936 // Delegate saw all prefs, two of which had the expected value_state.
937 ASSERT_EQ(arraysize(kTestTrackedPrefs),
938 mock_validation_delegate_.recorded_validations_count());
939 ASSERT_EQ(2u,
940 mock_validation_delegate_.CountValidationsOfState(
941 PrefHashStoreTransaction::SECURE_LEGACY));
942 ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
943 mock_validation_delegate_.CountValidationsOfState(
944 PrefHashStoreTransaction::UNCHANGED));
945
946 // Ensure that both the atomic and split hashes were restored.
947 ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
948
949 // In all cases, the values should have remained intact and the hashes should
950 // have been updated to match them.
951
952 MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
953 mock_pref_hash_store_->stored_value(kAtomicPref);
954 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
955 stored_atomic_value.second);
956 const base::Value* atomic_value_in_store;
957 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
958 ASSERT_EQ(string_value, atomic_value_in_store);
959 ASSERT_EQ(string_value, stored_atomic_value.first);
960
961 MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
962 mock_pref_hash_store_->stored_value(kSplitPref);
963 ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
964 stored_split_value.second);
965 const base::Value* split_value_in_store;
966 ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
967 ASSERT_EQ(dict_value, split_value_in_store);
968 ASSERT_EQ(dict_value, stored_split_value.first);
969
970 VerifyRecordedReset(false);
971 }
972
973 TEST_P(PrefHashFilterTest, DontResetReportOnly) {
974 // Ownership of these values is transfered to |pref_store_contents_|.
975 base::Value* int_value1 = new base::FundamentalValue(1);
976 base::Value* int_value2 = new base::FundamentalValue(2);
977 base::Value* report_only_val = new base::FundamentalValue(3);
978 base::DictionaryValue* report_only_split_val = new base::DictionaryValue;
979 report_only_split_val->SetInteger("a", 1234);
980 pref_store_contents_->Set(kAtomicPref, int_value1);
981 pref_store_contents_->Set(kAtomicPref2, int_value2);
982 pref_store_contents_->Set(kReportOnlyPref, report_only_val);
983 pref_store_contents_->Set(kReportOnlySplitPref, report_only_split_val);
984
985 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
986 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref2, NULL));
987 ASSERT_TRUE(pref_store_contents_->Get(kReportOnlyPref, NULL));
988 ASSERT_TRUE(pref_store_contents_->Get(kReportOnlySplitPref, NULL));
989
990 mock_pref_hash_store_->SetCheckResult(kAtomicPref,
991 PrefHashStoreTransaction::CHANGED);
992 mock_pref_hash_store_->SetCheckResult(kAtomicPref2,
993 PrefHashStoreTransaction::CHANGED);
994 mock_pref_hash_store_->SetCheckResult(kReportOnlyPref,
995 PrefHashStoreTransaction::CHANGED);
996 mock_pref_hash_store_->SetCheckResult(kReportOnlySplitPref,
997 PrefHashStoreTransaction::CHANGED);
998
999 DoFilterOnLoad(GetParam() >= PrefHashFilter::ENFORCE_ON_LOAD);
1000 // All prefs should be checked and a new hash should be stored for each tested
1001 // pref.
1002 ASSERT_EQ(arraysize(kTestTrackedPrefs),
1003 mock_pref_hash_store_->checked_paths_count());
1004 ASSERT_EQ(4u, mock_pref_hash_store_->stored_paths_count());
1005 ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
1006
1007 // Delegate saw all prefs, four of which had the expected value_state.
1008 ASSERT_EQ(arraysize(kTestTrackedPrefs),
1009 mock_validation_delegate_.recorded_validations_count());
1010 ASSERT_EQ(4u,
1011 mock_validation_delegate_.CountValidationsOfState(
1012 PrefHashStoreTransaction::CHANGED));
1013 ASSERT_EQ(arraysize(kTestTrackedPrefs) - 4u,
1014 mock_validation_delegate_.CountValidationsOfState(
1015 PrefHashStoreTransaction::UNCHANGED));
1016
1017 // No matter what the enforcement level is, the report only pref should never
1018 // be reset.
1019 ASSERT_TRUE(pref_store_contents_->Get(kReportOnlyPref, NULL));
1020 ASSERT_TRUE(pref_store_contents_->Get(kReportOnlySplitPref, NULL));
1021 ASSERT_EQ(report_only_val,
1022 mock_pref_hash_store_->stored_value(kReportOnlyPref).first);
1023 ASSERT_EQ(report_only_split_val,
1024 mock_pref_hash_store_->stored_value(kReportOnlySplitPref).first);
1025
1026 // All other prefs should have been reset if the enforcement level allows it.
1027 if (GetParam() == PrefHashFilter::ENFORCE_ON_LOAD) {
1028 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
1029 ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref2, NULL));
1030 ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kAtomicPref).first);
1031 ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kAtomicPref2).first);
1032
1033 VerifyRecordedReset(true);
1034 } else {
1035 const base::Value* value_in_store;
1036 const base::Value* value_in_store2;
1037 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &value_in_store));
1038 ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref2, &value_in_store2));
1039 ASSERT_EQ(int_value1, value_in_store);
1040 ASSERT_EQ(int_value1,
1041 mock_pref_hash_store_->stored_value(kAtomicPref).first);
1042 ASSERT_EQ(int_value2, value_in_store2);
1043 ASSERT_EQ(int_value2,
1044 mock_pref_hash_store_->stored_value(kAtomicPref2).first);
1045
1046 VerifyRecordedReset(false);
1047 }
1048 }
1049
1050 INSTANTIATE_TEST_CASE_P(
1051 PrefHashFilterTestInstance, PrefHashFilterTest,
1052 testing::Values(PrefHashFilter::NO_ENFORCEMENT,
1053 PrefHashFilter::ENFORCE_ON_LOAD));
OLDNEW
« no previous file with comments | « chrome/browser/prefs/tracked/pref_hash_filter.cc ('k') | chrome/browser/prefs/tracked/pref_hash_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698