| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/prefs/tracked/pref_hash_calculator.h" | 5 #include "components/user_prefs/tracked/pref_hash_calculator.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/values.h" | 11 #include "base/values.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 13 |
| 14 TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) { | 14 TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) { |
| 15 base::StringValue string_value_1("string value 1"); | 15 base::StringValue string_value_1("string value 1"); |
| 16 base::StringValue string_value_2("string value 2"); | 16 base::StringValue string_value_2("string value 2"); |
| 17 base::DictionaryValue dictionary_value_1; | 17 base::DictionaryValue dictionary_value_1; |
| 18 dictionary_value_1.SetInteger("int value", 1); | 18 dictionary_value_1.SetInteger("int value", 1); |
| 19 dictionary_value_1.Set("nested empty map", new base::DictionaryValue); | 19 dictionary_value_1.Set("nested empty map", new base::DictionaryValue); |
| 20 base::DictionaryValue dictionary_value_1_equivalent; | 20 base::DictionaryValue dictionary_value_1_equivalent; |
| 21 dictionary_value_1_equivalent.SetInteger("int value", 1); | 21 dictionary_value_1_equivalent.SetInteger("int value", 1); |
| 22 base::DictionaryValue dictionary_value_2; | 22 base::DictionaryValue dictionary_value_2; |
| 23 dictionary_value_2.SetInteger("int value", 2); | 23 dictionary_value_2.SetInteger("int value", 2); |
| 24 | 24 |
| 25 PrefHashCalculator calc1("seed1", "deviceid"); | 25 PrefHashCalculator calc1("seed1", "deviceid"); |
| 26 PrefHashCalculator calc1_dup("seed1", "deviceid"); | 26 PrefHashCalculator calc1_dup("seed1", "deviceid"); |
| 27 PrefHashCalculator calc2("seed2", "deviceid"); | 27 PrefHashCalculator calc2("seed2", "deviceid"); |
| 28 PrefHashCalculator calc3("seed1", "deviceid2"); | 28 PrefHashCalculator calc3("seed1", "deviceid2"); |
| 29 | 29 |
| 30 // Two calculators with same seed produce same hash. | 30 // Two calculators with same seed produce same hash. |
| 31 ASSERT_EQ(calc1.Calculate("pref_path", &string_value_1), | 31 ASSERT_EQ(calc1.Calculate("pref_path", &string_value_1), |
| 32 calc1_dup.Calculate("pref_path", &string_value_1)); | 32 calc1_dup.Calculate("pref_path", &string_value_1)); |
| 33 ASSERT_EQ(PrefHashCalculator::VALID, | 33 ASSERT_EQ(PrefHashCalculator::VALID, |
| 34 calc1_dup.Validate( | 34 calc1_dup.Validate("pref_path", &string_value_1, |
| 35 "pref_path", | 35 calc1.Calculate("pref_path", &string_value_1))); |
| 36 &string_value_1, | |
| 37 calc1.Calculate("pref_path", &string_value_1))); | |
| 38 | 36 |
| 39 // Different seeds, different hashes. | 37 // Different seeds, different hashes. |
| 40 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1), | 38 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1), |
| 41 calc2.Calculate("pref_path", &string_value_1)); | 39 calc2.Calculate("pref_path", &string_value_1)); |
| 42 ASSERT_EQ(PrefHashCalculator::INVALID, | 40 ASSERT_EQ(PrefHashCalculator::INVALID, |
| 43 calc2.Validate( | 41 calc2.Validate("pref_path", &string_value_1, |
| 44 "pref_path", | 42 calc1.Calculate("pref_path", &string_value_1))); |
| 45 &string_value_1, | |
| 46 calc1.Calculate("pref_path", &string_value_1))); | |
| 47 | 43 |
| 48 // Different device IDs, different hashes. | 44 // Different device IDs, different hashes. |
| 49 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1), | 45 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1), |
| 50 calc3.Calculate("pref_path", &string_value_1)); | 46 calc3.Calculate("pref_path", &string_value_1)); |
| 51 | 47 |
| 52 // Different values, different hashes. | 48 // Different values, different hashes. |
| 53 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1), | 49 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1), |
| 54 calc1.Calculate("pref_path", &string_value_2)); | 50 calc1.Calculate("pref_path", &string_value_2)); |
| 55 | 51 |
| 56 // Different paths, different hashes. | 52 // Different paths, different hashes. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 85 new base::FundamentalValue(123.0987654321)); | 81 new base::FundamentalValue(123.0987654321)); |
| 86 scoped_ptr<base::Value> string_value( | 82 scoped_ptr<base::Value> string_value( |
| 87 new base::StringValue("testing with special chars:\n<>{}:^^@#$\\/")); | 83 new base::StringValue("testing with special chars:\n<>{}:^^@#$\\/")); |
| 88 | 84 |
| 89 // For legacy reasons, we have to support pruning of empty lists/dictionaries | 85 // For legacy reasons, we have to support pruning of empty lists/dictionaries |
| 90 // and nested empty ists/dicts in the hash generation algorithm. | 86 // and nested empty ists/dicts in the hash generation algorithm. |
| 91 scoped_ptr<base::DictionaryValue> nested_empty_dict( | 87 scoped_ptr<base::DictionaryValue> nested_empty_dict( |
| 92 new base::DictionaryValue); | 88 new base::DictionaryValue); |
| 93 nested_empty_dict->Set("a", new base::DictionaryValue); | 89 nested_empty_dict->Set("a", new base::DictionaryValue); |
| 94 nested_empty_dict->Set("b", new base::ListValue); | 90 nested_empty_dict->Set("b", new base::ListValue); |
| 95 scoped_ptr<base::ListValue> nested_empty_list( | 91 scoped_ptr<base::ListValue> nested_empty_list(new base::ListValue); |
| 96 new base::ListValue); | |
| 97 nested_empty_list->Append(new base::DictionaryValue); | 92 nested_empty_list->Append(new base::DictionaryValue); |
| 98 nested_empty_list->Append(new base::ListValue); | 93 nested_empty_list->Append(new base::ListValue); |
| 99 nested_empty_list->Append(nested_empty_dict->DeepCopy()); | 94 nested_empty_list->Append(nested_empty_dict->DeepCopy()); |
| 100 | 95 |
| 101 // A dictionary with an empty dictionary, an empty list, and nested empty | 96 // A dictionary with an empty dictionary, an empty list, and nested empty |
| 102 // dictionaries/lists in it. | 97 // dictionaries/lists in it. |
| 103 scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue); | 98 scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue); |
| 104 dict_value->Set("a", new base::StringValue("foo")); | 99 dict_value->Set("a", new base::StringValue("foo")); |
| 105 dict_value->Set("d", new base::ListValue); | 100 dict_value->Set("d", new base::ListValue); |
| 106 dict_value->Set("b", new base::DictionaryValue); | 101 dict_value->Set("b", new base::DictionaryValue); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 119 ASSERT_EQ(base::Value::TYPE_DOUBLE, double_value->GetType()); | 114 ASSERT_EQ(base::Value::TYPE_DOUBLE, double_value->GetType()); |
| 120 ASSERT_EQ(base::Value::TYPE_STRING, string_value->GetType()); | 115 ASSERT_EQ(base::Value::TYPE_STRING, string_value->GetType()); |
| 121 ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict_value->GetType()); | 116 ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict_value->GetType()); |
| 122 ASSERT_EQ(base::Value::TYPE_LIST, list_value->GetType()); | 117 ASSERT_EQ(base::Value::TYPE_LIST, list_value->GetType()); |
| 123 | 118 |
| 124 // Test every value type independently. Intentionally omits TYPE_BINARY which | 119 // Test every value type independently. Intentionally omits TYPE_BINARY which |
| 125 // isn't even allowed in JSONWriter's input. | 120 // isn't even allowed in JSONWriter's input. |
| 126 static const char kExpectedNullValue[] = | 121 static const char kExpectedNullValue[] = |
| 127 "82A9F3BBC7F9FF84C76B033C854E79EEB162783FA7B3E99FF9372FA8E12C44F7"; | 122 "82A9F3BBC7F9FF84C76B033C854E79EEB162783FA7B3E99FF9372FA8E12C44F7"; |
| 128 EXPECT_EQ(PrefHashCalculator::VALID, | 123 EXPECT_EQ(PrefHashCalculator::VALID, |
| 129 PrefHashCalculator(kSeed, kDeviceId).Validate( | 124 PrefHashCalculator(kSeed, kDeviceId) |
| 130 "pref.path", null_value.get(), kExpectedNullValue)); | 125 .Validate("pref.path", null_value.get(), kExpectedNullValue)); |
| 131 | 126 |
| 132 static const char kExpectedBooleanValue[] = | 127 static const char kExpectedBooleanValue[] = |
| 133 "A520D8F43EA307B0063736DC9358C330539D0A29417580514C8B9862632C4CCC"; | 128 "A520D8F43EA307B0063736DC9358C330539D0A29417580514C8B9862632C4CCC"; |
| 134 EXPECT_EQ(PrefHashCalculator::VALID, | 129 EXPECT_EQ( |
| 135 PrefHashCalculator(kSeed, kDeviceId).Validate( | 130 PrefHashCalculator::VALID, |
| 136 "pref.path", bool_value.get(), kExpectedBooleanValue)); | 131 PrefHashCalculator(kSeed, kDeviceId) |
| 132 .Validate("pref.path", bool_value.get(), kExpectedBooleanValue)); |
| 137 | 133 |
| 138 static const char kExpectedIntegerValue[] = | 134 static const char kExpectedIntegerValue[] = |
| 139 "8D60DA1F10BF5AA29819D2D66D7CCEF9AABC5DA93C11A0D2BD21078D63D83682"; | 135 "8D60DA1F10BF5AA29819D2D66D7CCEF9AABC5DA93C11A0D2BD21078D63D83682"; |
| 140 EXPECT_EQ(PrefHashCalculator::VALID, | 136 EXPECT_EQ(PrefHashCalculator::VALID, |
| 141 PrefHashCalculator(kSeed, kDeviceId).Validate( | 137 PrefHashCalculator(kSeed, kDeviceId) |
| 142 "pref.path", int_value.get(), kExpectedIntegerValue)); | 138 .Validate("pref.path", int_value.get(), kExpectedIntegerValue)); |
| 143 | 139 |
| 144 static const char kExpectedDoubleValue[] = | 140 static const char kExpectedDoubleValue[] = |
| 145 "C9D94772516125BEEDAE68C109D44BC529E719EE020614E894CC7FB4098C545D"; | 141 "C9D94772516125BEEDAE68C109D44BC529E719EE020614E894CC7FB4098C545D"; |
| 146 EXPECT_EQ(PrefHashCalculator::VALID, | 142 EXPECT_EQ( |
| 147 PrefHashCalculator(kSeed, kDeviceId).Validate( | 143 PrefHashCalculator::VALID, |
| 148 "pref.path", double_value.get(), kExpectedDoubleValue)); | 144 PrefHashCalculator(kSeed, kDeviceId) |
| 145 .Validate("pref.path", double_value.get(), kExpectedDoubleValue)); |
| 149 | 146 |
| 150 static const char kExpectedStringValue[] = | 147 static const char kExpectedStringValue[] = |
| 151 "05ACCBD3B05C45C36CD06190F63EC577112311929D8380E26E5F13182EB68318"; | 148 "05ACCBD3B05C45C36CD06190F63EC577112311929D8380E26E5F13182EB68318"; |
| 152 EXPECT_EQ(PrefHashCalculator::VALID, | 149 EXPECT_EQ( |
| 153 PrefHashCalculator(kSeed, kDeviceId).Validate( | 150 PrefHashCalculator::VALID, |
| 154 "pref.path", string_value.get(), kExpectedStringValue)); | 151 PrefHashCalculator(kSeed, kDeviceId) |
| 152 .Validate("pref.path", string_value.get(), kExpectedStringValue)); |
| 155 | 153 |
| 156 static const char kExpectedDictValue[] = | 154 static const char kExpectedDictValue[] = |
| 157 "7A84DCC710D796C771F789A4DA82C952095AA956B6F1667EE42D0A19ECAA3C4A"; | 155 "7A84DCC710D796C771F789A4DA82C952095AA956B6F1667EE42D0A19ECAA3C4A"; |
| 158 EXPECT_EQ(PrefHashCalculator::VALID, | 156 EXPECT_EQ(PrefHashCalculator::VALID, |
| 159 PrefHashCalculator(kSeed, kDeviceId).Validate( | 157 PrefHashCalculator(kSeed, kDeviceId) |
| 160 "pref.path", dict_value.get(), kExpectedDictValue)); | 158 .Validate("pref.path", dict_value.get(), kExpectedDictValue)); |
| 161 | 159 |
| 162 static const char kExpectedListValue[] = | 160 static const char kExpectedListValue[] = |
| 163 "8D5A25972DF5AE20D041C780E7CA54E40F614AD53513A0724EE8D62D4F992740"; | 161 "8D5A25972DF5AE20D041C780E7CA54E40F614AD53513A0724EE8D62D4F992740"; |
| 164 EXPECT_EQ(PrefHashCalculator::VALID, | 162 EXPECT_EQ(PrefHashCalculator::VALID, |
| 165 PrefHashCalculator(kSeed, kDeviceId).Validate( | 163 PrefHashCalculator(kSeed, kDeviceId) |
| 166 "pref.path", list_value.get(), kExpectedListValue)); | 164 .Validate("pref.path", list_value.get(), kExpectedListValue)); |
| 167 | 165 |
| 168 // Also test every value type together in the same dictionary. | 166 // Also test every value type together in the same dictionary. |
| 169 base::DictionaryValue everything; | 167 base::DictionaryValue everything; |
| 170 everything.Set("null", null_value.release()); | 168 everything.Set("null", null_value.release()); |
| 171 everything.Set("bool", bool_value.release()); | 169 everything.Set("bool", bool_value.release()); |
| 172 everything.Set("int", int_value.release()); | 170 everything.Set("int", int_value.release()); |
| 173 everything.Set("double", double_value.release()); | 171 everything.Set("double", double_value.release()); |
| 174 everything.Set("string", string_value.release()); | 172 everything.Set("string", string_value.release()); |
| 175 everything.Set("list", list_value.release()); | 173 everything.Set("list", list_value.release()); |
| 176 everything.Set("dict", dict_value.release()); | 174 everything.Set("dict", dict_value.release()); |
| 177 static const char kExpectedEverythingValue[] = | 175 static const char kExpectedEverythingValue[] = |
| 178 "B97D09BE7005693574DCBDD03D8D9E44FB51F4008B73FB56A49A9FA671A1999B"; | 176 "B97D09BE7005693574DCBDD03D8D9E44FB51F4008B73FB56A49A9FA671A1999B"; |
| 179 EXPECT_EQ(PrefHashCalculator::VALID, | 177 EXPECT_EQ(PrefHashCalculator::VALID, |
| 180 PrefHashCalculator(kSeed, kDeviceId).Validate( | 178 PrefHashCalculator(kSeed, kDeviceId) |
| 181 "pref.path", &everything, kExpectedEverythingValue)); | 179 .Validate("pref.path", &everything, kExpectedEverythingValue)); |
| 182 } | 180 } |
| 183 | 181 |
| 184 TEST(PrefHashCalculatorTest, TestCompatibilityWithLegacyPrefMetricsServiceId) { | 182 TEST(PrefHashCalculatorTest, TestCompatibilityWithLegacyPrefMetricsServiceId) { |
| 185 static const char kSeed[] = { | 183 static const char kSeed[] = { |
| 186 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | 184 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, |
| 187 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | 185 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, |
| 188 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | 186 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, |
| 189 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | 187 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, |
| 190 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | 188 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, |
| 191 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | 189 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; |
| 192 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
| 193 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F | |
| 194 }; | |
| 195 static const char kDeviceId[] = | 190 static const char kDeviceId[] = |
| 196 "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84"; | 191 "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84"; |
| 197 static const char kExpectedValue[] = | 192 static const char kExpectedValue[] = |
| 198 "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE"; | 193 "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE"; |
| 199 | 194 |
| 200 base::ListValue startup_urls; | 195 base::ListValue startup_urls; |
| 201 startup_urls.Set(0, new base::StringValue("http://www.chromium.org/")); | 196 startup_urls.Set(0, new base::StringValue("http://www.chromium.org/")); |
| 202 | 197 |
| 203 EXPECT_EQ(PrefHashCalculator::VALID_SECURE_LEGACY, | 198 EXPECT_EQ( |
| 204 PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId). | 199 PrefHashCalculator::VALID_SECURE_LEGACY, |
| 205 Validate("session.startup_urls", &startup_urls, kExpectedValue)); | 200 PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId) |
| 201 .Validate("session.startup_urls", &startup_urls, kExpectedValue)); |
| 206 } | 202 } |
| OLD | NEW |