Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefs / pref_hash_calculator_unittest.cc
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.
4
5 #include "chrome/browser/prefs/pref_hash_calculator.h"
6
7 #include <string>
8
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"
13
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);
24
25   PrefHashCalculator calc1("seed1", "deviceid");
26   PrefHashCalculator calc1_dup("seed1", "deviceid");
27   PrefHashCalculator calc2("seed2", "deviceid");
28   PrefHashCalculator calc3("seed1", "deviceid2");
29
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)));
38
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)));
47
48   // Different device IDs, different hashes.
49   ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
50             calc3.Calculate("pref_path", &string_value_1));
51
52   // Different values, different hashes.
53   ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
54             calc1.Calculate("pref_path", &string_value_2));
55
56   // Different paths, different hashes.
57   ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
58             calc1.Calculate("pref_path_2", &string_value_1));
59
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));
65
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));
69
70   // NULL value is supported.
71   ASSERT_FALSE(calc1.Calculate("pref_path", NULL).empty());
72 }
73
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";
80
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<>{}:^^@#$\\/"));
88
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());
100
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());
110
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);
115
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());
123
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));
131
132   static const char kExpectedBooleanValue[] =
133       "A520D8F43EA307B0063736DC9358C330539D0A29417580514C8B9862632C4CCC";
134   EXPECT_EQ(PrefHashCalculator::VALID,
135             PrefHashCalculator(kSeed, kDeviceId).Validate(
136                 "pref.path", bool_value.get(), kExpectedBooleanValue));
137
138   static const char kExpectedIntegerValue[] =
139       "8D60DA1F10BF5AA29819D2D66D7CCEF9AABC5DA93C11A0D2BD21078D63D83682";
140   EXPECT_EQ(PrefHashCalculator::VALID,
141             PrefHashCalculator(kSeed, kDeviceId).Validate(
142                 "pref.path", int_value.get(), kExpectedIntegerValue));
143
144   static const char kExpectedDoubleValue[] =
145       "C9D94772516125BEEDAE68C109D44BC529E719EE020614E894CC7FB4098C545D";
146   EXPECT_EQ(PrefHashCalculator::VALID,
147             PrefHashCalculator(kSeed, kDeviceId).Validate(
148                 "pref.path", double_value.get(), kExpectedDoubleValue));
149
150   static const char kExpectedStringValue[] =
151       "05ACCBD3B05C45C36CD06190F63EC577112311929D8380E26E5F13182EB68318";
152   EXPECT_EQ(PrefHashCalculator::VALID,
153             PrefHashCalculator(kSeed, kDeviceId).Validate(
154                 "pref.path", string_value.get(), kExpectedStringValue));
155
156   static const char kExpectedDictValue[] =
157       "7A84DCC710D796C771F789A4DA82C952095AA956B6F1667EE42D0A19ECAA3C4A";
158   EXPECT_EQ(PrefHashCalculator::VALID,
159             PrefHashCalculator(kSeed, kDeviceId).Validate(
160                 "pref.path", dict_value.get(), kExpectedDictValue));
161
162   static const char kExpectedListValue[] =
163       "8D5A25972DF5AE20D041C780E7CA54E40F614AD53513A0724EE8D62D4F992740";
164   EXPECT_EQ(PrefHashCalculator::VALID,
165             PrefHashCalculator(kSeed, kDeviceId).Validate(
166                 "pref.path", list_value.get(), kExpectedListValue));
167
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));
182 }
183
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
194   };
195   static const char kDeviceId[] =
196       "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84";
197   static const char kExpectedValue[] =
198       "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE";
199
200   base::ListValue startup_urls;
201   startup_urls.Set(0, new base::StringValue("http://www.chromium.org/"));
202
203   EXPECT_EQ(PrefHashCalculator::VALID_SECURE_LEGACY,
204             PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId).
205             Validate("session.startup_urls", &startup_urls, kExpectedValue));
206 }