Chromium Code Reviews| Index: chrome/browser/prefs/pref_hash_filter_unittest.cc |
| diff --git a/chrome/browser/prefs/pref_hash_filter_unittest.cc b/chrome/browser/prefs/pref_hash_filter_unittest.cc |
| index 9248322a98a2f8d41d854fb7a7cf267313858d24..94fe7bf1c2fff1bf6cf32ec689cc69b2435d00f9 100644 |
| --- a/chrome/browser/prefs/pref_hash_filter_unittest.cc |
| +++ b/chrome/browser/prefs/pref_hash_filter_unittest.cc |
| @@ -15,18 +15,23 @@ |
| #include "base/memory/scoped_ptr.h" |
| #include "base/values.h" |
| #include "chrome/browser/prefs/pref_hash_store.h" |
| +#include "chrome/browser/prefs/tracked_preference.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| namespace { |
| -const char kTestPref[] = "pref"; |
| -const char kTestPref2[] = "pref2"; |
| +const char kAtomicPref[] = "atomic_pref"; |
| +const char kAtomicPref2[] = "atomic_pref2"; |
| const char kReportOnlyPref[] = "report_only"; |
| - |
| -const PrefHashFilter::TrackedPreference kTestTrackedPrefs[] = { |
| - { 0, kTestPref, true }, |
| - { 1, kReportOnlyPref, false }, |
| - { 2, kTestPref2, true }, |
| +const char kReportOnlySplitPref[] = "report_only_split_pref"; |
| +const char kSplitPref[] = "split_pref"; |
| + |
| +const PrefHashFilter::TrackedPreferenceMetadata kTestTrackedPrefs[] = { |
| + { 0, kAtomicPref, true, PrefHashFilter::TRACKING_STRATEGY_ATOMIC }, |
| + { 1, kReportOnlyPref, false, PrefHashFilter::TRACKING_STRATEGY_ATOMIC }, |
| + { 2, kSplitPref, true, PrefHashFilter::TRACKING_STRATEGY_SPLIT }, |
| + { 3, kReportOnlySplitPref, false, PrefHashFilter::TRACKING_STRATEGY_SPLIT }, |
| + { 4, kAtomicPref2, true, PrefHashFilter::TRACKING_STRATEGY_ATOMIC }, |
| }; |
| } // namespace |
| @@ -35,13 +40,23 @@ const PrefHashFilter::TrackedPreference kTestTrackedPrefs[] = { |
| // checked and stored values. |
| class MockPrefHashStore : public PrefHashStore { |
| public: |
| + typedef std::pair<const void*, PrefHashFilter::PrefTrackingStrategy> |
| + ValuePtrStrategyPair; |
| MockPrefHashStore() {} |
| - // Set the result that will be returned when |path| is passed to |CheckValue|. |
| + // Set the result that will be returned when |path| is passed to |
| + // |Check(Split)?Value|. |
| void SetCheckResult(const std::string& path, |
| PrefHashStore::ValueState result); |
| + // Set the invalid_keys that will be returned when |path| is passed to |
| + // |CheckSplitValue|. SetCheckResult should already have been called for |
| + // |path| with |result == CHANGED| for this to make any sense. |
| + void SetInvalidKeysResult( |
| + const std::string& path, |
| + const std::vector<std::string>& invalid_keys_result); |
| + |
| // Returns the number of paths checked. |
| size_t checked_paths_count() const { |
| return checked_values_.size(); |
| @@ -52,26 +67,30 @@ class MockPrefHashStore : public PrefHashStore { |
| return stored_values_.size(); |
| } |
| - // Returns the pointer value that was passed to |CheckValue| for |path|. The |
| - // returned pointer could since have been freed and is thus not safe to |
| - // dereference. |
| - const void* checked_value(const std::string& path) const { |
| - std::map<std::string, const base::Value*>::iterator value = |
| + // Returns the pointer value and strategy that was passed to |
| + // |Check(Split)?Hash| for |path|. The returned pointer could since have been |
|
Bernhard Bauer
2014/01/17 17:00:05
Nit: CheckHash/CheckSplitHash reads a bit easier t
gab
2014/01/17 19:56:49
Done.
|
| + // freed and is thus not safe to dereference. |
| + ValuePtrStrategyPair checked_value(const std::string& path) const { |
| + std::map<std::string, ValuePtrStrategyPair>::iterator value = |
| checked_values_.find(path); |
| if (value != checked_values_.end()) |
| return value->second; |
| - return reinterpret_cast<void*>(0xBAD); |
| + return std::make_pair( |
| + reinterpret_cast<void*>(0xBAD), |
| + static_cast<PrefHashFilter::PrefTrackingStrategy>(-1)); |
| } |
| - // Returns the pointer value that was passed to |StoreHash| for |path|. The |
| - // returned pointer could since have been freed and is thus not safe to |
| - // dereference. |
| - const void* stored_value(const std::string& path) const { |
| - std::map<std::string, const base::Value*>::const_iterator value = |
| + // Returns the pointer value that was passed to |Store(Split)?Hash| for |
| + // |path|. The returned pointer could since have been freed and is thus not |
| + // safe to dereference. |
| + ValuePtrStrategyPair stored_value(const std::string& path) const { |
| + std::map<std::string, ValuePtrStrategyPair>::const_iterator value = |
| stored_values_.find(path); |
| if (value != stored_values_.end()) |
| return value->second; |
| - return reinterpret_cast<void*>(0xBAD); |
| + return std::make_pair( |
| + reinterpret_cast<void*>(0xBAD), |
| + static_cast<PrefHashFilter::PrefTrackingStrategy>(-1)); |
| } |
| // PrefHashStore implementation. |
| @@ -79,11 +98,30 @@ class MockPrefHashStore : public PrefHashStore { |
| const std::string& path, const base::Value* value) const OVERRIDE; |
| virtual void StoreHash(const std::string& path, |
| const base::Value* new_value) OVERRIDE; |
| + virtual PrefHashStore::ValueState CheckSplitValue( |
| + const std::string& path, |
| + const base::DictionaryValue* initial_split_value, |
| + std::vector<std::string>* invalid_keys) const OVERRIDE; |
| + virtual void StoreSplitHash( |
| + const std::string& path, |
| + const base::DictionaryValue* split_value) OVERRIDE; |
| private: |
| + // Records a call to this mock's CheckValue/CheckSplitValue methods. |
| + PrefHashStore::ValueState RecordCheckValue( |
| + const std::string& path, |
| + const base::Value* value, |
| + PrefHashFilter::PrefTrackingStrategy strategy) const; |
| + |
| + // Records a call to this mock's StoreHash/StoreSplitHash methods. |
| + void RecordStoreHash(const std::string& path, |
| + const base::Value* new_value, |
| + PrefHashFilter::PrefTrackingStrategy strategy); |
| + |
| std::map<std::string, PrefHashStore::ValueState> check_results_; |
| - mutable std::map<std::string, const base::Value*> checked_values_; |
| - std::map<std::string, const base::Value*> stored_values_; |
| + std::map<std::string, std::vector<std::string> > invalid_keys_results_; |
| + mutable std::map<std::string, ValuePtrStrategyPair> checked_values_; |
| + std::map<std::string, ValuePtrStrategyPair> stored_values_; |
| DISALLOW_COPY_AND_ASSIGN(MockPrefHashStore); |
| }; |
| @@ -93,10 +131,60 @@ void MockPrefHashStore::SetCheckResult( |
| check_results_.insert(std::make_pair(path, result)); |
| } |
| +void MockPrefHashStore::SetInvalidKeysResult( |
| + const std::string& path, |
| + const std::vector<std::string>& invalid_keys_result) { |
| + // Ensure |check_results_| has a CHANGED entry for |path|. |
| + std::map<std::string, PrefHashStore::ValueState>::const_iterator result = |
| + check_results_.find(path); |
| + ASSERT_TRUE(result != check_results_.end()); |
| + ASSERT_EQ(PrefHashStore::CHANGED, result->second); |
| + |
| + invalid_keys_results_.insert(std::make_pair(path, invalid_keys_result)); |
| +} |
| + |
| PrefHashStore::ValueState MockPrefHashStore::CheckValue( |
| const std::string& path, const base::Value* value) const { |
| - checked_values_.insert(std::make_pair(path, value)); |
| + return RecordCheckValue(path, value, |
| + PrefHashFilter::TRACKING_STRATEGY_ATOMIC); |
| +} |
| + |
| +void MockPrefHashStore::StoreHash(const std::string& path, |
| + const base::Value* new_value) { |
| + RecordStoreHash(path, new_value, PrefHashFilter::TRACKING_STRATEGY_ATOMIC); |
| +} |
| +PrefHashStore::ValueState MockPrefHashStore::CheckSplitValue( |
| + const std::string& path, |
| + const base::DictionaryValue* initial_split_value, |
| + std::vector<std::string>* invalid_keys) const { |
| + EXPECT_TRUE(invalid_keys && invalid_keys->empty()); |
| + |
| + std::map<std::string, std::vector<std::string> >::const_iterator |
| + invalid_keys_result = invalid_keys_results_.find(path); |
| + if (invalid_keys_result != invalid_keys_results_.end()) { |
| + invalid_keys->insert(invalid_keys->begin(), |
| + invalid_keys_result->second.begin(), |
| + invalid_keys_result->second.end()); |
| + } |
| + |
| + return RecordCheckValue(path, initial_split_value, |
| + PrefHashFilter::TRACKING_STRATEGY_SPLIT); |
| +} |
| + |
| +void MockPrefHashStore::StoreSplitHash(const std::string& path, |
| + const base::DictionaryValue* new_value) { |
| + RecordStoreHash(path, new_value, PrefHashFilter::TRACKING_STRATEGY_SPLIT); |
| +} |
| + |
| +PrefHashStore::ValueState MockPrefHashStore::RecordCheckValue( |
| + const std::string& path, |
| + const base::Value* value, |
| + PrefHashFilter::PrefTrackingStrategy strategy) const { |
| + // Record that |path| was checked and validate that it wasn't previously |
| + // checked. |
| + EXPECT_TRUE(checked_values_.insert( |
| + std::make_pair(path, std::make_pair(value, strategy))).second); |
| std::map<std::string, PrefHashStore::ValueState>::const_iterator result = |
| check_results_.find(path); |
| if (result != check_results_.end()) |
| @@ -104,16 +192,19 @@ PrefHashStore::ValueState MockPrefHashStore::CheckValue( |
| return PrefHashStore::UNCHANGED; |
| } |
| -void MockPrefHashStore::StoreHash(const std::string& path, |
| - const base::Value* new_value) { |
| - stored_values_.insert(std::make_pair(path, new_value)); |
| +void MockPrefHashStore::RecordStoreHash( |
| + const std::string& path, |
| + const base::Value* new_value, |
| + PrefHashFilter::PrefTrackingStrategy strategy) { |
| + EXPECT_TRUE(stored_values_.insert( |
| + std::make_pair(path, std::make_pair(new_value, strategy))).second); |
| } |
| // Creates a PrefHashFilter that uses a MockPrefHashStore. The |
| // MockPrefHashStore (owned by the PrefHashFilter) is returned in |
| // |mock_pref_hash_store|. |
| scoped_ptr<PrefHashFilter> CreatePrefHashFilter( |
| - PrefHashFilter::EnforcementLevel enforcement_level, |
| + TrackedPreferenceHelper::EnforcementLevel enforcement_level, |
| MockPrefHashStore** mock_pref_hash_store) { |
| scoped_ptr<MockPrefHashStore> temp_mock_pref_hash_store( |
| new MockPrefHashStore); |
| @@ -127,7 +218,7 @@ scoped_ptr<PrefHashFilter> CreatePrefHashFilter( |
| } |
| class PrefHashFilterTest |
| - : public testing::TestWithParam<PrefHashFilter::EnforcementLevel> { |
| + : public testing::TestWithParam<TrackedPreferenceHelper::EnforcementLevel> { |
| public: |
| PrefHashFilterTest() : mock_pref_hash_store_(NULL) {} |
| @@ -155,17 +246,33 @@ TEST_P(PrefHashFilterTest, EmptyAndUnchanged) { |
| // Since there was nothing in |pref_store_contents_| the checked value should |
| // have been NULL for all tracked preferences. |
| for (size_t i = 0; i < arraysize(kTestTrackedPrefs); ++i) { |
| - ASSERT_EQ(NULL, |
| - mock_pref_hash_store_->checked_value(kTestTrackedPrefs[i].name)); |
| + ASSERT_EQ(NULL, mock_pref_hash_store_->checked_value( |
| + kTestTrackedPrefs[i].name).first); |
| } |
| } |
| -TEST_P(PrefHashFilterTest, FilterTrackedPrefUpdate) { |
| +TEST_P(PrefHashFilterTest, FilterAtomicPrefUpdate) { |
| base::StringValue string_value("string value"); |
| - pref_hash_filter_->FilterUpdate(kTestPref, &string_value); |
| + pref_hash_filter_->FilterUpdate(kAtomicPref, &string_value); |
| // One path should be stored. |
| ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| - ASSERT_EQ(&string_value, mock_pref_hash_store_->stored_value(kTestPref)); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + ASSERT_EQ(&string_value, stored_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, stored_value.second); |
| +} |
| + |
| +TEST_P(PrefHashFilterTest, FilterSplitPrefUpdate) { |
| + base::DictionaryValue dict_value; |
| + dict_value.SetString("a", "foo"); |
| + dict_value.SetInteger("b", 1234); |
| + pref_hash_filter_->FilterUpdate(kSplitPref, &dict_value); |
| + // One path should be stored. |
| + ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_value = |
| + mock_pref_hash_store_->stored_value(kSplitPref); |
| + ASSERT_EQ(&dict_value, stored_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value.second); |
| } |
| TEST_P(PrefHashFilterTest, FilterUntrackedPrefUpdate) { |
| @@ -176,137 +283,257 @@ TEST_P(PrefHashFilterTest, FilterUntrackedPrefUpdate) { |
| } |
| TEST_P(PrefHashFilterTest, EmptyAndUnknown) { |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_FALSE(pref_store_contents_.Get(kSplitPref, NULL)); |
| // NULL values are always trusted by the PrefHashStore. |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, |
| + PrefHashStore::TRUSTED_UNKNOWN_VALUE); |
| + mock_pref_hash_store_->SetCheckResult(kSplitPref, |
| PrefHashStore::TRUSTED_UNKNOWN_VALUE); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| - ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| - |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref)); |
| + ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count()); |
| + |
| + MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + ASSERT_EQ(NULL, stored_atomic_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
| + stored_atomic_value.second); |
| + |
| + MockPrefHashStore::ValuePtrStrategyPair stored_split_value = |
| + mock_pref_hash_store_->stored_value(kSplitPref); |
| + ASSERT_EQ(NULL, stored_split_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, |
| + stored_split_value.second); |
| } |
| TEST_P(PrefHashFilterTest, InitialValueUnknown) { |
| - // Ownership of this value is transfered to |pref_store_contents_|. |
| - base::Value* string_value = base::Value::CreateStringValue("test"); |
| - pref_store_contents_.Set(kTestPref, string_value); |
| + // Ownership of these values is transfered to |pref_store_contents_|. |
| + base::StringValue* string_value = new base::StringValue("string value"); |
| + pref_store_contents_.Set(kAtomicPref, string_value); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, NULL)); |
| + base::DictionaryValue* dict_value = new base::DictionaryValue; |
| + dict_value->SetString("a", "foo"); |
| + dict_value->SetInteger("b", 1234); |
| + pref_store_contents_.Set(kSplitPref, dict_value); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, NULL)); |
| + |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, |
| + PrefHashStore::UNTRUSTED_UNKNOWN_VALUE); |
| + mock_pref_hash_store_->SetCheckResult(kSplitPref, |
| PrefHashStore::UNTRUSTED_UNKNOWN_VALUE); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| - ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| - |
| - if (GetParam() >= PrefHashFilter::ENFORCE_NO_SEEDING) { |
| - // Ensure the pref was cleared and the hash for NULL was restored if the |
| - // current enforcement level denies seeding. |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref)); |
| + ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count()); |
| + |
| + MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_split_value = |
| + mock_pref_hash_store_->stored_value(kSplitPref); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
| + stored_atomic_value.second); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, |
| + stored_split_value.second); |
| + if (GetParam() >= TrackedPreferenceHelper::ENFORCE_NO_SEEDING) { |
| + // Ensure the prefs were cleared and the hashes for NULL were restored if |
| + // the current enforcement level denies seeding. |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_EQ(NULL, stored_atomic_value.first); |
| + |
| + ASSERT_FALSE(pref_store_contents_.Get(kSplitPref, NULL)); |
| + ASSERT_EQ(NULL, stored_split_value.first); |
| } else { |
| - // Otherwise the value should have remained intact and the hash should have |
| - // been updated to match it. |
| - const base::Value* value_in_store; |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, &value_in_store)); |
| - ASSERT_EQ(string_value, value_in_store); |
| - ASSERT_EQ(string_value, mock_pref_hash_store_->stored_value(kTestPref)); |
| + // Otherwise the values should have remained intact and the hashes should |
| + // have been updated to match them. |
| + const base::Value* atomic_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, &atomic_value_in_store)); |
| + ASSERT_EQ(string_value, atomic_value_in_store); |
| + ASSERT_EQ(string_value, stored_atomic_value.first); |
| + |
| + const base::Value* split_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, &split_value_in_store)); |
| + ASSERT_EQ(dict_value, split_value_in_store); |
| + ASSERT_EQ(dict_value, stored_split_value.first); |
| } |
| } |
| TEST_P(PrefHashFilterTest, InitialValueTrustedUnknown) { |
| // Ownership of this value is transfered to |pref_store_contents_|. |
| base::Value* string_value = base::Value::CreateStringValue("test"); |
| - pref_store_contents_.Set(kTestPref, string_value); |
| + pref_store_contents_.Set(kAtomicPref, string_value); |
| + |
| + base::DictionaryValue* dict_value = new base::DictionaryValue; |
| + dict_value->SetString("a", "foo"); |
| + dict_value->SetInteger("b", 1234); |
| + pref_store_contents_.Set(kSplitPref, dict_value); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, NULL)); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, |
| + PrefHashStore::TRUSTED_UNKNOWN_VALUE); |
| + mock_pref_hash_store_->SetCheckResult(kSplitPref, |
| PrefHashStore::TRUSTED_UNKNOWN_VALUE); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| - ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| + ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count()); |
| // Seeding is always allowed for trusted unknown values. |
| - const base::Value* value_in_store; |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, &value_in_store)); |
| - ASSERT_EQ(string_value, value_in_store); |
| - ASSERT_EQ(string_value, mock_pref_hash_store_->stored_value(kTestPref)); |
| + const base::Value* atomic_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, &atomic_value_in_store)); |
| + ASSERT_EQ(string_value, atomic_value_in_store); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + ASSERT_EQ(string_value, stored_atomic_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
| + stored_atomic_value.second); |
| + |
| + const base::Value* split_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, &split_value_in_store)); |
| + ASSERT_EQ(dict_value, split_value_in_store); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_split_value = |
| + mock_pref_hash_store_->stored_value(kSplitPref); |
| + ASSERT_EQ(dict_value, stored_split_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, |
| + stored_split_value.second); |
| } |
| TEST_P(PrefHashFilterTest, InitialValueChanged) { |
| // Ownership of this value is transfered to |pref_store_contents_|. |
| base::Value* int_value = base::Value::CreateIntegerValue(1234); |
| - pref_store_contents_.Set(kTestPref, int_value); |
| + pref_store_contents_.Set(kAtomicPref, int_value); |
| + |
| + base::DictionaryValue* dict_value = new base::DictionaryValue; |
| + dict_value->SetString("a", "foo"); |
| + dict_value->SetInteger("b", 1234); |
| + dict_value->SetInteger("c", 56); |
| + dict_value->SetBoolean("d", false); |
| + pref_store_contents_.Set(kSplitPref, dict_value); |
| + |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, NULL)); |
| + |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, PrefHashStore::CHANGED); |
| + mock_pref_hash_store_->SetCheckResult(kSplitPref, PrefHashStore::CHANGED); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, NULL)); |
| + std::vector<std::string> mock_invalid_keys; |
| + mock_invalid_keys.push_back("a"); |
| + mock_invalid_keys.push_back("c"); |
| + mock_pref_hash_store_->SetInvalidKeysResult(kSplitPref, mock_invalid_keys); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, PrefHashStore::CHANGED); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| - ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| - |
| - if (GetParam() >= PrefHashFilter::ENFORCE) { |
| - // Ensure the pref was cleared and the hash for NULL was restored if the |
| - // current enforcement level prevents changes. |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref)); |
| + ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count()); |
| + |
| + MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_split_value = |
| + mock_pref_hash_store_->stored_value(kSplitPref); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
| + stored_atomic_value.second); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, |
| + stored_split_value.second); |
| + if (GetParam() >= TrackedPreferenceHelper::ENFORCE) { |
| + // Ensure the atomic pref was cleared and the hash for NULL was restored if |
| + // the current enforcement level prevents changes. |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_EQ(NULL, stored_atomic_value.first); |
| + |
| + // The split pref on the other hand should only have been stripped of its |
| + // invalid keys. |
| + const base::Value* split_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, &split_value_in_store)); |
| + ASSERT_EQ(2U, dict_value->size()); |
| + ASSERT_FALSE(dict_value->HasKey("a")); |
| + ASSERT_TRUE(dict_value->HasKey("b")); |
| + ASSERT_FALSE(dict_value->HasKey("c")); |
| + ASSERT_TRUE(dict_value->HasKey("d")); |
| + ASSERT_EQ(dict_value, stored_split_value.first); |
| } else { |
| // Otherwise the value should have remained intact and the hash should have |
| // been updated to match it. |
| - const base::Value* value_in_store; |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, &value_in_store)); |
| - ASSERT_EQ(int_value, value_in_store); |
| - ASSERT_EQ(int_value, mock_pref_hash_store_->stored_value(kTestPref)); |
| + const base::Value* atomic_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, &atomic_value_in_store)); |
| + ASSERT_EQ(int_value, atomic_value_in_store); |
| + ASSERT_EQ(int_value, stored_atomic_value.first); |
| + |
| + const base::Value* split_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kSplitPref, &split_value_in_store)); |
| + ASSERT_EQ(dict_value, split_value_in_store); |
| + ASSERT_EQ(4U, dict_value->size()); |
| + ASSERT_TRUE(dict_value->HasKey("a")); |
| + ASSERT_TRUE(dict_value->HasKey("b")); |
| + ASSERT_TRUE(dict_value->HasKey("c")); |
| + ASSERT_TRUE(dict_value->HasKey("d")); |
| + ASSERT_EQ(dict_value, stored_split_value.first); |
| } |
| } |
| TEST_P(PrefHashFilterTest, EmptyCleared) { |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, PrefHashStore::CLEARED); |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_FALSE(pref_store_contents_.Get(kSplitPref, NULL)); |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, PrefHashStore::CLEARED); |
| + mock_pref_hash_store_->SetCheckResult(kSplitPref, PrefHashStore::CLEARED); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| - ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| + ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count()); |
| // Regardless of the enforcement level, the only thing that should be done is |
| // to restore the hash for NULL. The value itself should still be NULL. |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref)); |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + ASSERT_EQ(NULL, stored_atomic_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
| + stored_atomic_value.second); |
| + |
| + ASSERT_FALSE(pref_store_contents_.Get(kSplitPref, NULL)); |
| + MockPrefHashStore::ValuePtrStrategyPair stored_split_value = |
| + mock_pref_hash_store_->stored_value(kSplitPref); |
| + ASSERT_EQ(NULL, stored_split_value.first); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, |
| + stored_split_value.second); |
| } |
| -TEST_P(PrefHashFilterTest, EmptyMigrated) { |
| +TEST_P(PrefHashFilterTest, InitialValueMigrated) { |
| + // Only test atomic prefs, split prefs were introduce after the migration. |
| + |
| // Ownership of this value is transfered to |pref_store_contents_|. |
| base::ListValue* list_value = new base::ListValue; |
| list_value->Append(base::Value::CreateStringValue("test")); |
| - pref_store_contents_.Set(kTestPref, list_value); |
| + pref_store_contents_.Set(kAtomicPref, list_value); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, PrefHashStore::MIGRATED); |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, PrefHashStore::MIGRATED); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
| - if (GetParam() >= PrefHashFilter::ENFORCE_NO_SEEDING_NO_MIGRATION) { |
| + MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
| + mock_pref_hash_store_->stored_value(kAtomicPref); |
| + ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
| + stored_atomic_value.second); |
| + if (GetParam() >= TrackedPreferenceHelper::ENFORCE_NO_SEEDING_NO_MIGRATION) { |
| // Ensure the pref was cleared and the hash for NULL was restored if the |
| // current enforcement level prevents migration. |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref)); |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_EQ(NULL, stored_atomic_value.first); |
| } else { |
| // Otherwise the value should have remained intact and the hash should have |
| // been updated to match it. |
| - const base::Value* value_in_store; |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, &value_in_store)); |
| - ASSERT_EQ(list_value, value_in_store); |
| - ASSERT_EQ(list_value, mock_pref_hash_store_->stored_value(kTestPref)); |
| + const base::Value* atomic_value_in_store; |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, &atomic_value_in_store)); |
| + ASSERT_EQ(list_value, atomic_value_in_store); |
| + ASSERT_EQ(list_value, stored_atomic_value.first); |
| } |
| } |
| @@ -315,51 +542,61 @@ TEST_P(PrefHashFilterTest, DontResetReportOnly) { |
| base::Value* int_value1 = base::Value::CreateIntegerValue(1); |
| base::Value* int_value2 = base::Value::CreateIntegerValue(2); |
| base::Value* report_only_val = base::Value::CreateIntegerValue(3); |
| - pref_store_contents_.Set(kTestPref, int_value1); |
| - pref_store_contents_.Set(kTestPref2, int_value2); |
| + base::DictionaryValue* report_only_split_val = new base::DictionaryValue; |
| + report_only_split_val->SetInteger("a", 1234); |
| + pref_store_contents_.Set(kAtomicPref, int_value1); |
| + pref_store_contents_.Set(kAtomicPref2, int_value2); |
| pref_store_contents_.Set(kReportOnlyPref, report_only_val); |
| + pref_store_contents_.Set(kReportOnlySplitPref, report_only_split_val); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref2, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref2, NULL)); |
| ASSERT_TRUE(pref_store_contents_.Get(kReportOnlyPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kReportOnlySplitPref, NULL)); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref, PrefHashStore::CHANGED); |
| - mock_pref_hash_store_->SetCheckResult(kTestPref2, PrefHashStore::CHANGED); |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref, PrefHashStore::CHANGED); |
| + mock_pref_hash_store_->SetCheckResult(kAtomicPref2, PrefHashStore::CHANGED); |
| mock_pref_hash_store_->SetCheckResult(kReportOnlyPref, |
| PrefHashStore::CHANGED); |
| + mock_pref_hash_store_->SetCheckResult(kReportOnlySplitPref, |
| + PrefHashStore::CHANGED); |
| pref_hash_filter_->FilterOnLoad(&pref_store_contents_); |
| // All prefs should be checked and a new hash should be stored for each. |
| ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| mock_pref_hash_store_->checked_paths_count()); |
| - ASSERT_EQ(arraysize(kTestTrackedPrefs), |
| - mock_pref_hash_store_->stored_paths_count()); |
| + ASSERT_EQ(4u, mock_pref_hash_store_->stored_paths_count()); |
| // No matter what the enforcement level is, the report only pref should never |
| // be reset. |
| ASSERT_TRUE(pref_store_contents_.Get(kReportOnlyPref, NULL)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kReportOnlySplitPref, NULL)); |
| ASSERT_EQ(report_only_val, |
| - mock_pref_hash_store_->stored_value(kReportOnlyPref)); |
| + mock_pref_hash_store_->stored_value(kReportOnlyPref).first); |
| + ASSERT_EQ(report_only_split_val, |
| + mock_pref_hash_store_->stored_value(kReportOnlySplitPref).first); |
| // All other prefs should have been reset if the enforcement level allows it. |
| - if (GetParam() >= PrefHashFilter::ENFORCE) { |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref, NULL)); |
| - ASSERT_FALSE(pref_store_contents_.Get(kTestPref2, NULL)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref)); |
| - ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kTestPref2)); |
| + if (GetParam() >= TrackedPreferenceHelper::ENFORCE) { |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref, NULL)); |
| + ASSERT_FALSE(pref_store_contents_.Get(kAtomicPref2, NULL)); |
| + ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kAtomicPref).first); |
| + ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kAtomicPref2).first); |
| } else { |
| const base::Value* value_in_store; |
| const base::Value* value_in_store2; |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref, &value_in_store)); |
| - ASSERT_TRUE(pref_store_contents_.Get(kTestPref2, &value_in_store2)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref, &value_in_store)); |
| + ASSERT_TRUE(pref_store_contents_.Get(kAtomicPref2, &value_in_store2)); |
| ASSERT_EQ(int_value1, value_in_store); |
| - ASSERT_EQ(int_value1, mock_pref_hash_store_->stored_value(kTestPref)); |
| + ASSERT_EQ(int_value1, |
| + mock_pref_hash_store_->stored_value(kAtomicPref).first); |
| ASSERT_EQ(int_value2, value_in_store2); |
| - ASSERT_EQ(int_value2, mock_pref_hash_store_->stored_value(kTestPref2)); |
| + ASSERT_EQ(int_value2, |
| + mock_pref_hash_store_->stored_value(kAtomicPref2).first); |
| } |
| } |
| // This is a hack to allow testing::Range to iterate over enum values in |
| -// PrefHashFilter::EnforcementLevel. This is required as |
| +// TrackedPreferenceHelper::EnforcementLevel. This is required as |
| // testing::internals::RangeGenerator used by testing::Range needs to be able |
| // to do |i = i + step| where i is an EnforcementLevel and |step| is 1 by |
| // default; |enum + 1| results in an |int| type, not an |enum|, and there is no |
| @@ -368,15 +605,16 @@ TEST_P(PrefHashFilterTest, DontResetReportOnly) { |
| // explicit cast in the overloaded operator+ below and makes |i = i + step| a |
| // valid statement. |
| class EnforcementLevelIncrement {}; |
| -PrefHashFilter::EnforcementLevel operator+( |
| - PrefHashFilter::EnforcementLevel current_level, |
| +TrackedPreferenceHelper::EnforcementLevel operator+( |
| + TrackedPreferenceHelper::EnforcementLevel current_level, |
| const EnforcementLevelIncrement& /* increment */) { |
| - return static_cast<PrefHashFilter::EnforcementLevel>(current_level + 1); |
| + return static_cast<TrackedPreferenceHelper::EnforcementLevel>( |
| + current_level + 1); |
| } |
| INSTANTIATE_TEST_CASE_P( |
| PrefEnforcementLevels, PrefHashFilterTest, |
| - testing::Range(PrefHashFilter::NO_ENFORCEMENT, |
| - static_cast<PrefHashFilter::EnforcementLevel>( |
| - PrefHashFilter::ENFORCE_ALL + 1), |
| + testing::Range(TrackedPreferenceHelper::NO_ENFORCEMENT, |
| + static_cast<TrackedPreferenceHelper::EnforcementLevel>( |
| + TrackedPreferenceHelper::ENFORCE_ALL + 1), |
| EnforcementLevelIncrement())); |