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 63bd4477d6f273847daba463c7c04aa4ae321ff9..66f5cc46cf3e3dd9460867c63f0f894fec28eea0 100644 |
--- a/chrome/browser/prefs/pref_hash_filter_unittest.cc |
+++ b/chrome/browser/prefs/pref_hash_filter_unittest.cc |
@@ -16,20 +16,25 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/values.h" |
#include "chrome/browser/prefs/pref_hash_store.h" |
+#include "chrome/browser/prefs/tracked/tracked_preference.h" |
#include "testing/gtest/include/gtest/gtest.h" |
namespace { |
-const char kTestPref[] = "pref"; |
-const char kTestPref2[] = "pref2"; |
-const char kTestPref3[] = "pref3"; |
+const char kAtomicPref[] = "atomic_pref"; |
+const char kAtomicPref2[] = "atomic_pref2"; |
+const char kAtomicPref3[] = "pref3"; |
const char kReportOnlyPref[] = "report_only"; |
- |
-const PrefHashFilter::TrackedPreference kTestTrackedPrefs[] = { |
- { 0, kTestPref, true }, |
- { 1, kReportOnlyPref, false }, |
- { 2, kTestPref2, true }, |
- { 3, kTestPref3, 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 }, |
+ { 5, kAtomicPref3, true, PrefHashFilter::TRACKING_STRATEGY_ATOMIC }, |
}; |
} // namespace |
@@ -38,13 +43,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 |
+ // |CheckValue/CheckSplitValue|. |
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(); |
@@ -55,26 +70,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 |
+ // |CheckHash/CheckSplitHash| for |path|. The returned pointer could since |
+ // have been 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 |StoreHash/StoreSplitHash| 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. |
@@ -83,11 +102,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); |
}; |
@@ -97,6 +135,18 @@ 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)); |
+} |
+ |
bool MockPrefHashStore::IsInitialized() const { |
NOTREACHED(); |
return true; |
@@ -104,8 +154,46 @@ bool MockPrefHashStore::IsInitialized() const { |
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()) |
@@ -113,9 +201,12 @@ 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 |
@@ -164,8 +255,8 @@ 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); |
} |
} |
@@ -173,16 +264,40 @@ TEST_P(PrefHashFilterTest, FilterTrackedPrefUpdate) { |
base::DictionaryValue root_dict; |
// Ownership of |string_value| is transfered to |root_dict|. |
base::Value* string_value = base::Value::CreateStringValue("string value"); |
- root_dict.Set(kTestPref, string_value); |
+ root_dict.Set(kAtomicPref, string_value); |
+ |
+ // No path should be stored on FilterUpdate. |
+ pref_hash_filter_->FilterUpdate(kAtomicPref); |
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count()); |
+ |
+ // One path should be stored on FilterSerializeData. |
+ pref_hash_filter_->FilterSerializeData(&root_dict); |
+ ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count()); |
+ 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 root_dict; |
+ // Ownership of |dict_value| is transfered to |root_dict|. |
+ base::DictionaryValue* dict_value = new base::DictionaryValue; |
+ dict_value->SetString("a", "foo"); |
+ dict_value->SetInteger("b", 1234); |
+ root_dict.Set(kSplitPref, dict_value); |
// No path should be stored on FilterUpdate. |
- pref_hash_filter_->FilterUpdate(kTestPref); |
+ pref_hash_filter_->FilterUpdate(kSplitPref); |
ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count()); |
// One path should be stored on FilterSerializeData. |
pref_hash_filter_->FilterSerializeData(&root_dict); |
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(kSplitPref); |
+ ASSERT_EQ(dict_value, stored_value.first); |
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value.second); |
} |
TEST_P(PrefHashFilterTest, FilterUntrackedPrefUpdate) { |
@@ -205,161 +320,299 @@ TEST_P(PrefHashFilterTest, MultiplePrefsFilterSerializeData) { |
base::Value* int_value2 = base::Value::CreateIntegerValue(2); |
base::Value* int_value3 = base::Value::CreateIntegerValue(3); |
base::Value* int_value4 = base::Value::CreateIntegerValue(4); |
- root_dict.Set(kTestPref, int_value1); |
- root_dict.Set(kTestPref2, int_value2); |
- root_dict.Set(kTestPref3, int_value3); |
+ base::DictionaryValue* dict_value = new base::DictionaryValue; |
+ dict_value->Set("a", base::Value::CreateBooleanValue(true)); |
+ root_dict.Set(kAtomicPref, int_value1); |
+ root_dict.Set(kAtomicPref2, int_value2); |
+ root_dict.Set(kAtomicPref3, int_value3); |
root_dict.Set("untracked", int_value4); |
+ root_dict.Set(kSplitPref, dict_value); |
- // Only update kTestPref and kTestPref3 |
- pref_hash_filter_->FilterUpdate(kTestPref); |
- pref_hash_filter_->FilterUpdate(kTestPref3); |
+ // Only update kAtomicPref, kAtomicPref3, and kSplitPref. |
+ pref_hash_filter_->FilterUpdate(kAtomicPref); |
+ pref_hash_filter_->FilterUpdate(kAtomicPref3); |
+ pref_hash_filter_->FilterUpdate(kSplitPref); |
ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count()); |
- // Update kTestPref3 again, nothing should be stored still. |
+ // Update kAtomicPref3 again, nothing should be stored still. |
base::Value* int_value5 = base::Value::CreateIntegerValue(5); |
- root_dict.Set(kTestPref3, int_value5); |
+ root_dict.Set(kAtomicPref3, int_value5); |
ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count()); |
- // On FilterSerializeData, only kTestPref and kTestPref3 should get a new |
- // hash. |
+ // On FilterSerializeData, only kAtomicPref, kAtomicPref3, and kSplitPref |
+ // should get a new hash. |
pref_hash_filter_->FilterSerializeData(&root_dict); |
- ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count()); |
- ASSERT_EQ(int_value1, mock_pref_hash_store_->stored_value(kTestPref)); |
- ASSERT_EQ(int_value5, mock_pref_hash_store_->stored_value(kTestPref3)); |
+ ASSERT_EQ(3u, mock_pref_hash_store_->stored_paths_count()); |
+ MockPrefHashStore::ValuePtrStrategyPair stored_value_atomic1 = |
+ mock_pref_hash_store_->stored_value(kAtomicPref); |
+ ASSERT_EQ(int_value1, stored_value_atomic1.first); |
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
+ stored_value_atomic1.second); |
+ |
+ MockPrefHashStore::ValuePtrStrategyPair stored_value_atomic3 = |
+ mock_pref_hash_store_->stored_value(kAtomicPref3); |
+ ASSERT_EQ(int_value5, stored_value_atomic3.first); |
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
+ stored_value_atomic3.second); |
+ |
+ MockPrefHashStore::ValuePtrStrategyPair stored_value_split = |
+ mock_pref_hash_store_->stored_value(kSplitPref); |
+ ASSERT_EQ(dict_value, stored_value_split.first); |
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value_split.second); |
} |
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_EQ(2u, 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)); |
+ 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()); |
+ 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() >= 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)); |
+ // 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(kTestPref, NULL)); |
+ 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); |
+ |
+ 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()); |
+ 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() >= 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)); |
+ // 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()); |
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value = |
+ mock_pref_hash_store_->stored_value(kAtomicPref); |
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, |
+ stored_atomic_value.second); |
if (GetParam() >= PrefHashFilter::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); |
} |
} |
@@ -368,46 +621,57 @@ 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 tested |
// pref. |
ASSERT_EQ(arraysize(kTestTrackedPrefs), |
mock_pref_hash_store_->checked_paths_count()); |
- ASSERT_EQ(3u, 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)); |
+ 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); |
} |
} |
@@ -424,7 +688,8 @@ class EnforcementLevelIncrement {}; |
PrefHashFilter::EnforcementLevel operator+( |
PrefHashFilter::EnforcementLevel current_level, |
const EnforcementLevelIncrement& /* increment */) { |
- return static_cast<PrefHashFilter::EnforcementLevel>(current_level + 1); |
+ return static_cast<PrefHashFilter::EnforcementLevel>( |
+ current_level + 1); |
} |
INSTANTIATE_TEST_CASE_P( |