Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / prefs / pref_hash_calculator_unittest.cc
blob128c39d8790271c93622c0c5d177e2e6697998f3
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.
5 #include "chrome/browser/prefs/pref_hash_calculator.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_util.h"
12 #include "base/values.h"
13 #include "chrome/browser/prefs/tracked/pref_hash_calculator_helper.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) {
17 base::StringValue string_value_1("string value 1");
18 base::StringValue string_value_2("string value 2");
19 base::DictionaryValue dictionary_value_1;
20 dictionary_value_1.SetInteger("int value", 1);
21 dictionary_value_1.Set("nested empty map", new base::DictionaryValue);
22 base::DictionaryValue dictionary_value_1_equivalent;
23 dictionary_value_1_equivalent.SetInteger("int value", 1);
24 base::DictionaryValue dictionary_value_2;
25 dictionary_value_2.SetInteger("int value", 2);
27 PrefHashCalculator calc1("seed1", "deviceid");
28 PrefHashCalculator calc1_dup("seed1", "deviceid");
29 PrefHashCalculator calc2("seed2", "deviceid");
30 PrefHashCalculator calc3("seed1", "deviceid2");
32 // Two calculators with same seed produce same hash.
33 ASSERT_EQ(calc1.Calculate("pref_path", &string_value_1),
34 calc1_dup.Calculate("pref_path", &string_value_1));
35 ASSERT_EQ(PrefHashCalculator::VALID,
36 calc1_dup.Validate(
37 "pref_path",
38 &string_value_1,
39 calc1.Calculate("pref_path", &string_value_1)));
41 // Different seeds, different hashes.
42 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
43 calc2.Calculate("pref_path", &string_value_1));
44 ASSERT_EQ(PrefHashCalculator::INVALID,
45 calc2.Validate(
46 "pref_path",
47 &string_value_1,
48 calc1.Calculate("pref_path", &string_value_1)));
50 // Different device IDs, different hashes.
51 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
52 calc3.Calculate("pref_path", &string_value_1));
54 // Different values, different hashes.
55 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
56 calc1.Calculate("pref_path", &string_value_2));
58 // Different paths, different hashes.
59 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
60 calc1.Calculate("pref_path_2", &string_value_1));
62 // Works for dictionaries.
63 ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
64 calc1.Calculate("pref_path", &dictionary_value_1));
65 ASSERT_NE(calc1.Calculate("pref_path", &dictionary_value_1),
66 calc1.Calculate("pref_path", &dictionary_value_2));
68 // Empty dictionary children are pruned.
69 ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
70 calc1.Calculate("pref_path", &dictionary_value_1_equivalent));
72 // NULL value is supported.
73 ASSERT_FALSE(calc1.Calculate("pref_path", NULL).empty());
76 // Tests the output against a known value to catch unexpected algorithm changes.
77 // The test hashes below must NEVER be updated, the serialization algorithm used
78 // must always be able to generate data that will produce these exact hashes.
79 TEST(PrefHashCalculatorTest, CatchHashChanges) {
80 static const char kSeed[] = "0123456789ABCDEF0123456789ABCDEF";
81 static const char kDeviceId[] = "test_device_id1";
83 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue());
84 scoped_ptr<base::Value> bool_value(base::Value::CreateBooleanValue(false));
85 scoped_ptr<base::Value> int_value(
86 base::Value::CreateIntegerValue(1234567890));
87 scoped_ptr<base::Value> double_value(
88 base::Value::CreateDoubleValue(123.0987654321));
89 scoped_ptr<base::Value> string_value(base::Value::CreateStringValue(
90 "testing with special chars:\n<>{}:^^@#$\\/"));
92 // For legacy reasons, we have to support pruning of empty lists/dictionaries
93 // and nested empty ists/dicts in the hash generation algorithm.
94 scoped_ptr<base::DictionaryValue> nested_empty_dict(
95 new base::DictionaryValue);
96 nested_empty_dict->Set("a", new base::DictionaryValue);
97 nested_empty_dict->Set("b", new base::ListValue);
98 scoped_ptr<base::ListValue> nested_empty_list(
99 new base::ListValue);
100 nested_empty_list->Append(new base::DictionaryValue);
101 nested_empty_list->Append(new base::ListValue);
102 nested_empty_list->Append(nested_empty_dict->DeepCopy());
104 // A dictionary with an empty dictionary, an empty list, and nested empty
105 // dictionaries/lists in it.
106 scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue);
107 dict_value->Set("a", new base::StringValue("foo"));
108 dict_value->Set("d", new base::ListValue);
109 dict_value->Set("b", new base::DictionaryValue);
110 dict_value->Set("c", new base::StringValue("baz"));
111 dict_value->Set("e", nested_empty_dict.release());
112 dict_value->Set("f", nested_empty_list.release());
114 scoped_ptr<base::ListValue> list_value(new base::ListValue);
115 list_value->AppendBoolean(true);
116 list_value->AppendInteger(100);
117 list_value->AppendDouble(1.0);
119 ASSERT_EQ(base::Value::TYPE_NULL, null_value->GetType());
120 ASSERT_EQ(base::Value::TYPE_BOOLEAN, bool_value->GetType());
121 ASSERT_EQ(base::Value::TYPE_INTEGER, int_value->GetType());
122 ASSERT_EQ(base::Value::TYPE_DOUBLE, double_value->GetType());
123 ASSERT_EQ(base::Value::TYPE_STRING, string_value->GetType());
124 ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict_value->GetType());
125 ASSERT_EQ(base::Value::TYPE_LIST, list_value->GetType());
127 // Test every value type independently. Intentionally omits TYPE_BINARY which
128 // isn't even allowed in JSONWriter's input.
129 static const char kExpectedNullValue[] =
130 "C2871D0AC76176E39948C50A9A562B863E610FDA90C675A6A8AD16B4DC4F53DC";
131 EXPECT_EQ(PrefHashCalculator::VALID,
132 PrefHashCalculator(kSeed, kDeviceId).Validate(
133 "pref.path", null_value.get(), kExpectedNullValue));
135 static const char kExpectedBooleanValue[] =
136 "A326E2F405CFE05D08289CDADD9DB4F529592F0945A8CE204289E4C930D8AA43";
137 EXPECT_EQ(PrefHashCalculator::VALID,
138 PrefHashCalculator(kSeed, kDeviceId).Validate(
139 "pref.path", bool_value.get(), kExpectedBooleanValue));
141 static const char kExpectedIntegerValue[] =
142 "4B69938F802A2A26D69467F3E1E4A474F6323C64EFC54DBDB4A5708A7D005042";
143 EXPECT_EQ(PrefHashCalculator::VALID,
144 PrefHashCalculator(kSeed, kDeviceId).Validate(
145 "pref.path", int_value.get(), kExpectedIntegerValue));
147 static const char kExpectedDoubleValue[] =
148 "1734C9C745B9C92D896B9A710994BF1B56D55BFB0F00C207EC995152AF02F08F";
149 EXPECT_EQ(PrefHashCalculator::VALID,
150 PrefHashCalculator(kSeed, kDeviceId).Validate(
151 "pref.path", double_value.get(), kExpectedDoubleValue));
153 static const char kExpectedStringValue[] =
154 "154D15522C856AA944BFA5A9E3FFB46925BF2B95A10199564651CA1C13E98433";
155 EXPECT_EQ(PrefHashCalculator::VALID,
156 PrefHashCalculator(kSeed, kDeviceId).Validate(
157 "pref.path", string_value.get(), kExpectedStringValue));
159 static const char kExpectedDictValue[] =
160 "597CECCBF930AF1FFABAC6AF3851C062867C134B4D5A06BDB3B03B988A182CBB";
161 EXPECT_EQ(PrefHashCalculator::VALID,
162 PrefHashCalculator(kSeed, kDeviceId).Validate(
163 "pref.path", dict_value.get(), kExpectedDictValue));
165 static const char kExpectedListValue[] =
166 "4E2CC0A9B8DF8C5049C53E8B139007792EC6295239545BC99BBF9CDE8A2F5E30";
167 EXPECT_EQ(PrefHashCalculator::VALID,
168 PrefHashCalculator(kSeed, kDeviceId).Validate(
169 "pref.path", list_value.get(), kExpectedListValue));
171 // Also test every value type together in the same dictionary.
172 base::DictionaryValue everything;
173 everything.Set("null", null_value.release());
174 everything.Set("bool", bool_value.release());
175 everything.Set("int", int_value.release());
176 everything.Set("double", double_value.release());
177 everything.Set("string", string_value.release());
178 everything.Set("list", list_value.release());
179 everything.Set("dict", dict_value.release());
180 static const char kExpectedEverythingValue[] =
181 "5A9D15E4D2FA909007EDE6A18605735E3EB712E2EDE83D6735CE5DD96A5AFBAA";
182 EXPECT_EQ(PrefHashCalculator::VALID,
183 PrefHashCalculator(kSeed, kDeviceId).Validate(
184 "pref.path", &everything, kExpectedEverythingValue));
187 TEST(PrefHashCalculatorTest, TestCompatibilityWithPrefMetricsService) {
188 static const char kSeed[] = {
189 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
190 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
191 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
192 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
193 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
194 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
195 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
196 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
198 static const char kDeviceId[] =
199 "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84";
200 static const char kExpectedValue[] =
201 "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE";
203 base::ListValue startup_urls;
204 startup_urls.Set(0, new base::StringValue("http://www.chromium.org/"));
206 EXPECT_EQ(PrefHashCalculator::VALID,
207 PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId).
208 Validate("session.startup_urls", &startup_urls, kExpectedValue));
211 TEST(PrefHashCalculatorTest, TestLegacyNoDeviceIdNoPathAlgorithm) {
212 static const char kTestedLegacyHash[] =
213 "C503FB7C65EEFD5C07185F616A0AA67923C069909933F362022B1F187E73E9A2";
214 static const char kDeviceId[] = "not_used";
216 base::DictionaryValue dict;
217 dict.Set("a", new base::StringValue("foo"));
218 dict.Set("d", new base::StringValue("bad"));
219 dict.Set("b", new base::StringValue("bar"));
220 dict.Set("c", new base::StringValue("baz"));
222 // 32 NULL bytes is the seed that was used to generate the legacy hash.
223 EXPECT_EQ(PrefHashCalculator::VALID_WEAK_LEGACY,
224 PrefHashCalculator(std::string(32u, 0), kDeviceId).Validate(
225 "unused_path", &dict, kTestedLegacyHash));
228 std::string MockGetLegacyDeviceId(const std::string& modern_device_id) {
229 if (modern_device_id.empty())
230 return std::string();
231 return modern_device_id + "_LEGACY";
234 TEST(PrefHashCalculatorTest, TestLegacyDeviceIdAlgorithm) {
235 // The full algorithm should kick in when the device id is non-empty and we
236 // should thus get VALID_SECURE_LEGACY on verification.
237 static const char kDeviceId[] = "DEVICE_ID";
238 static const char kSeed[] = "01234567890123456789012345678901";
239 static const char kPrefPath[] = "test.pref";
240 static const char kPrefValue[] = "http://example.com/";
241 // Test hash based on the mock legacy id (based on kDeviceId) + kPrefPath +
242 // kPrefValue under kSeed.
243 static const char kTestedHash[] =
244 "09ABD84B13E4366B24DFF898C8C4614E033514B4E2EF3C6810F50B63273C83AD";
246 const base::StringValue string_value(kPrefValue);
247 EXPECT_EQ(PrefHashCalculator::VALID_SECURE_LEGACY,
248 PrefHashCalculator(kSeed, kDeviceId,
249 base::Bind(&MockGetLegacyDeviceId)).Validate(
250 kPrefPath, &string_value, kTestedHash));
253 TEST(PrefHashCalculatorTest, TestLegacyDeviceIdAlgorithmOnEmptyDeviceId) {
254 // MockGetLegacyDeviceId will return a legacy device ID that is the same
255 // (empty) as the modern device ID here. So this MAC will be valid using
256 // either ID. The PrefHashCalculator should return VALID, not
257 // VALID_SECURE_LEGACY, in this case.
258 static const char kEmptyDeviceId[] = "";
259 static const char kSeed[] = "01234567890123456789012345678901";
260 static const char kPrefPath[] = "test.pref";
261 static const char kPrefValue[] = "http://example.com/";
262 // Test hash based on an empty legacy device id + kPrefPath + kPrefValue under
263 // kSeed.
264 static const char kTestedHash[] =
265 "842C71283B9C3D86AA934CD639FDB0428BF0E2B6EC8537A21575CC4C4FA0A615";
267 const base::StringValue string_value(kPrefValue);
268 EXPECT_EQ(PrefHashCalculator::VALID,
269 PrefHashCalculator(kSeed, kEmptyDeviceId,
270 base::Bind(&MockGetLegacyDeviceId)).Validate(
271 kPrefPath, &string_value, kTestedHash));