Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / prefs / tracked / pref_hash_calculator_unittest.cc
blob71f9a44dd3a60ff77110042f3004c3a48b60ef32
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/tracked/pref_hash_calculator.h"
7 #include <string>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_util.h"
11 #include "base/values.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) {
15 base::StringValue string_value_1("string value 1");
16 base::StringValue string_value_2("string value 2");
17 base::DictionaryValue dictionary_value_1;
18 dictionary_value_1.SetInteger("int value", 1);
19 dictionary_value_1.Set("nested empty map", new base::DictionaryValue);
20 base::DictionaryValue dictionary_value_1_equivalent;
21 dictionary_value_1_equivalent.SetInteger("int value", 1);
22 base::DictionaryValue dictionary_value_2;
23 dictionary_value_2.SetInteger("int value", 2);
25 PrefHashCalculator calc1("seed1", "deviceid");
26 PrefHashCalculator calc1_dup("seed1", "deviceid");
27 PrefHashCalculator calc2("seed2", "deviceid");
28 PrefHashCalculator calc3("seed1", "deviceid2");
30 // Two calculators with same seed produce same hash.
31 ASSERT_EQ(calc1.Calculate("pref_path", &string_value_1),
32 calc1_dup.Calculate("pref_path", &string_value_1));
33 ASSERT_EQ(PrefHashCalculator::VALID,
34 calc1_dup.Validate(
35 "pref_path",
36 &string_value_1,
37 calc1.Calculate("pref_path", &string_value_1)));
39 // Different seeds, different hashes.
40 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
41 calc2.Calculate("pref_path", &string_value_1));
42 ASSERT_EQ(PrefHashCalculator::INVALID,
43 calc2.Validate(
44 "pref_path",
45 &string_value_1,
46 calc1.Calculate("pref_path", &string_value_1)));
48 // Different device IDs, different hashes.
49 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
50 calc3.Calculate("pref_path", &string_value_1));
52 // Different values, different hashes.
53 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
54 calc1.Calculate("pref_path", &string_value_2));
56 // Different paths, different hashes.
57 ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
58 calc1.Calculate("pref_path_2", &string_value_1));
60 // Works for dictionaries.
61 ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
62 calc1.Calculate("pref_path", &dictionary_value_1));
63 ASSERT_NE(calc1.Calculate("pref_path", &dictionary_value_1),
64 calc1.Calculate("pref_path", &dictionary_value_2));
66 // Empty dictionary children are pruned.
67 ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
68 calc1.Calculate("pref_path", &dictionary_value_1_equivalent));
70 // NULL value is supported.
71 ASSERT_FALSE(calc1.Calculate("pref_path", NULL).empty());
74 // Tests the output against a known value to catch unexpected algorithm changes.
75 // The test hashes below must NEVER be updated, the serialization algorithm used
76 // must always be able to generate data that will produce these exact hashes.
77 TEST(PrefHashCalculatorTest, CatchHashChanges) {
78 static const char kSeed[] = "0123456789ABCDEF0123456789ABCDEF";
79 static const char kDeviceId[] = "test_device_id1";
81 scoped_ptr<base::Value> null_value = base::Value::CreateNullValue();
82 scoped_ptr<base::Value> bool_value(new base::FundamentalValue(false));
83 scoped_ptr<base::Value> int_value(new base::FundamentalValue(1234567890));
84 scoped_ptr<base::Value> double_value(
85 new base::FundamentalValue(123.0987654321));
86 scoped_ptr<base::Value> string_value(
87 new base::StringValue("testing with special chars:\n<>{}:^^@#$\\/"));
89 // For legacy reasons, we have to support pruning of empty lists/dictionaries
90 // and nested empty ists/dicts in the hash generation algorithm.
91 scoped_ptr<base::DictionaryValue> nested_empty_dict(
92 new base::DictionaryValue);
93 nested_empty_dict->Set("a", new base::DictionaryValue);
94 nested_empty_dict->Set("b", new base::ListValue);
95 scoped_ptr<base::ListValue> nested_empty_list(
96 new base::ListValue);
97 nested_empty_list->Append(new base::DictionaryValue);
98 nested_empty_list->Append(new base::ListValue);
99 nested_empty_list->Append(nested_empty_dict->DeepCopy());
101 // A dictionary with an empty dictionary, an empty list, and nested empty
102 // dictionaries/lists in it.
103 scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue);
104 dict_value->Set("a", new base::StringValue("foo"));
105 dict_value->Set("d", new base::ListValue);
106 dict_value->Set("b", new base::DictionaryValue);
107 dict_value->Set("c", new base::StringValue("baz"));
108 dict_value->Set("e", nested_empty_dict.release());
109 dict_value->Set("f", nested_empty_list.release());
111 scoped_ptr<base::ListValue> list_value(new base::ListValue);
112 list_value->AppendBoolean(true);
113 list_value->AppendInteger(100);
114 list_value->AppendDouble(1.0);
116 ASSERT_EQ(base::Value::TYPE_NULL, null_value->GetType());
117 ASSERT_EQ(base::Value::TYPE_BOOLEAN, bool_value->GetType());
118 ASSERT_EQ(base::Value::TYPE_INTEGER, int_value->GetType());
119 ASSERT_EQ(base::Value::TYPE_DOUBLE, double_value->GetType());
120 ASSERT_EQ(base::Value::TYPE_STRING, string_value->GetType());
121 ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict_value->GetType());
122 ASSERT_EQ(base::Value::TYPE_LIST, list_value->GetType());
124 // Test every value type independently. Intentionally omits TYPE_BINARY which
125 // isn't even allowed in JSONWriter's input.
126 static const char kExpectedNullValue[] =
127 "82A9F3BBC7F9FF84C76B033C854E79EEB162783FA7B3E99FF9372FA8E12C44F7";
128 EXPECT_EQ(PrefHashCalculator::VALID,
129 PrefHashCalculator(kSeed, kDeviceId).Validate(
130 "pref.path", null_value.get(), kExpectedNullValue));
132 static const char kExpectedBooleanValue[] =
133 "A520D8F43EA307B0063736DC9358C330539D0A29417580514C8B9862632C4CCC";
134 EXPECT_EQ(PrefHashCalculator::VALID,
135 PrefHashCalculator(kSeed, kDeviceId).Validate(
136 "pref.path", bool_value.get(), kExpectedBooleanValue));
138 static const char kExpectedIntegerValue[] =
139 "8D60DA1F10BF5AA29819D2D66D7CCEF9AABC5DA93C11A0D2BD21078D63D83682";
140 EXPECT_EQ(PrefHashCalculator::VALID,
141 PrefHashCalculator(kSeed, kDeviceId).Validate(
142 "pref.path", int_value.get(), kExpectedIntegerValue));
144 static const char kExpectedDoubleValue[] =
145 "C9D94772516125BEEDAE68C109D44BC529E719EE020614E894CC7FB4098C545D";
146 EXPECT_EQ(PrefHashCalculator::VALID,
147 PrefHashCalculator(kSeed, kDeviceId).Validate(
148 "pref.path", double_value.get(), kExpectedDoubleValue));
150 static const char kExpectedStringValue[] =
151 "05ACCBD3B05C45C36CD06190F63EC577112311929D8380E26E5F13182EB68318";
152 EXPECT_EQ(PrefHashCalculator::VALID,
153 PrefHashCalculator(kSeed, kDeviceId).Validate(
154 "pref.path", string_value.get(), kExpectedStringValue));
156 static const char kExpectedDictValue[] =
157 "7A84DCC710D796C771F789A4DA82C952095AA956B6F1667EE42D0A19ECAA3C4A";
158 EXPECT_EQ(PrefHashCalculator::VALID,
159 PrefHashCalculator(kSeed, kDeviceId).Validate(
160 "pref.path", dict_value.get(), kExpectedDictValue));
162 static const char kExpectedListValue[] =
163 "8D5A25972DF5AE20D041C780E7CA54E40F614AD53513A0724EE8D62D4F992740";
164 EXPECT_EQ(PrefHashCalculator::VALID,
165 PrefHashCalculator(kSeed, kDeviceId).Validate(
166 "pref.path", list_value.get(), kExpectedListValue));
168 // Also test every value type together in the same dictionary.
169 base::DictionaryValue everything;
170 everything.Set("null", null_value.release());
171 everything.Set("bool", bool_value.release());
172 everything.Set("int", int_value.release());
173 everything.Set("double", double_value.release());
174 everything.Set("string", string_value.release());
175 everything.Set("list", list_value.release());
176 everything.Set("dict", dict_value.release());
177 static const char kExpectedEverythingValue[] =
178 "B97D09BE7005693574DCBDD03D8D9E44FB51F4008B73FB56A49A9FA671A1999B";
179 EXPECT_EQ(PrefHashCalculator::VALID,
180 PrefHashCalculator(kSeed, kDeviceId).Validate(
181 "pref.path", &everything, kExpectedEverythingValue));
184 TEST(PrefHashCalculatorTest, TestCompatibilityWithLegacyPrefMetricsServiceId) {
185 static const char kSeed[] = {
186 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
187 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
188 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
189 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
190 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
191 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
195 static const char kDeviceId[] =
196 "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84";
197 static const char kExpectedValue[] =
198 "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE";
200 base::ListValue startup_urls;
201 startup_urls.Set(0, new base::StringValue("http://www.chromium.org/"));
203 EXPECT_EQ(PrefHashCalculator::VALID_SECURE_LEGACY,
204 PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId).
205 Validate("session.startup_urls", &startup_urls, kExpectedValue));