OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/metrics/variations/variations_seed_store.h" | 5 #include "chrome/browser/metrics/variations/variations_seed_store.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/prefs/testing_pref_service.h" | 8 #include "base/prefs/testing_pref_service.h" |
9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 private: | 37 private: |
38 DISALLOW_COPY_AND_ASSIGN(TestVariationsSeedStore); | 38 DISALLOW_COPY_AND_ASSIGN(TestVariationsSeedStore); |
39 }; | 39 }; |
40 | 40 |
41 | 41 |
42 // Populates |seed| with simple test data. The resulting seed will contain one | 42 // Populates |seed| with simple test data. The resulting seed will contain one |
43 // study called "test", which contains one experiment called "abc" with | 43 // study called "test", which contains one experiment called "abc" with |
44 // probability weight 100. |seed|'s study field will be cleared before adding | 44 // probability weight 100. |seed|'s study field will be cleared before adding |
45 // the new study. | 45 // the new study. |
46 variations::VariationsSeed CreateTestSeed() { | 46 VariationsSeed CreateTestSeed() { |
47 variations::VariationsSeed seed; | 47 VariationsSeed seed; |
48 variations::Study* study = seed.add_study(); | 48 Study* study = seed.add_study(); |
49 study->set_name("test"); | 49 study->set_name("test"); |
50 study->set_default_experiment_name("abc"); | 50 study->set_default_experiment_name("abc"); |
51 variations::Study_Experiment* experiment = study->add_experiment(); | 51 Study_Experiment* experiment = study->add_experiment(); |
52 experiment->set_name("abc"); | 52 experiment->set_name("abc"); |
53 experiment->set_probability_weight(100); | 53 experiment->set_probability_weight(100); |
54 seed.set_serial_number("123"); | 54 seed.set_serial_number("123"); |
55 return seed; | 55 return seed; |
56 } | 56 } |
57 | 57 |
58 // Serializes |seed| to protobuf binary format. | 58 // Serializes |seed| to protobuf binary format. |
59 std::string SerializeSeed(const variations::VariationsSeed& seed) { | 59 std::string SerializeSeed(const VariationsSeed& seed) { |
60 std::string serialized_seed; | 60 std::string serialized_seed; |
61 seed.SerializeToString(&serialized_seed); | 61 seed.SerializeToString(&serialized_seed); |
62 return serialized_seed; | 62 return serialized_seed; |
63 } | 63 } |
64 | 64 |
65 // Serializes |seed| to base64-encoded protobuf binary format. | 65 // Serializes |seed| to base64-encoded protobuf binary format. |
66 std::string SerializeSeedBase64(const variations::VariationsSeed& seed, | 66 std::string SerializeSeedBase64(const VariationsSeed& seed, std::string* hash) { |
67 std::string* hash) { | |
68 std::string serialized_seed = SerializeSeed(seed); | 67 std::string serialized_seed = SerializeSeed(seed); |
69 if (hash != NULL) { | 68 if (hash != NULL) { |
70 std::string sha1 = base::SHA1HashString(serialized_seed); | 69 std::string sha1 = base::SHA1HashString(serialized_seed); |
71 *hash = base::HexEncode(sha1.data(), sha1.size()); | 70 *hash = base::HexEncode(sha1.data(), sha1.size()); |
72 } | 71 } |
73 std::string base64_serialized_seed; | 72 std::string base64_serialized_seed; |
74 base::Base64Encode(serialized_seed, &base64_serialized_seed); | 73 base::Base64Encode(serialized_seed, &base64_serialized_seed); |
75 return base64_serialized_seed; | 74 return base64_serialized_seed; |
76 } | 75 } |
77 | 76 |
78 // Checks whether the pref with name |pref_name| is at its default value in | 77 // Checks whether the pref with name |pref_name| is at its default value in |
79 // |prefs|. | 78 // |prefs|. |
80 bool PrefHasDefaultValue(const TestingPrefServiceSimple& prefs, | 79 bool PrefHasDefaultValue(const TestingPrefServiceSimple& prefs, |
81 const char* pref_name) { | 80 const char* pref_name) { |
82 return prefs.FindPreference(pref_name)->IsDefaultValue(); | 81 return prefs.FindPreference(pref_name)->IsDefaultValue(); |
83 } | 82 } |
84 | 83 |
85 } // namespace | 84 } // namespace |
86 | 85 |
87 TEST(VariationsSeedStoreTest, LoadSeed) { | 86 TEST(VariationsSeedStoreTest, LoadSeed) { |
88 // Store good seed data to test if loading from prefs works. | 87 // Store good seed data to test if loading from prefs works. |
89 const variations::VariationsSeed seed = CreateTestSeed(); | 88 const VariationsSeed seed = CreateTestSeed(); |
90 std::string seed_hash; | 89 std::string seed_hash; |
91 const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash); | 90 const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash); |
92 | 91 |
93 TestingPrefServiceSimple prefs; | 92 TestingPrefServiceSimple prefs; |
94 VariationsSeedStore::RegisterPrefs(prefs.registry()); | 93 VariationsSeedStore::RegisterPrefs(prefs.registry()); |
95 prefs.SetString(prefs::kVariationsSeed, base64_seed); | 94 prefs.SetString(prefs::kVariationsSeed, base64_seed); |
96 | 95 |
97 TestVariationsSeedStore seed_store(&prefs); | 96 TestVariationsSeedStore seed_store(&prefs); |
98 | 97 |
99 variations::VariationsSeed loaded_seed; | 98 VariationsSeed loaded_seed; |
100 // Check that loading a seed without a hash pref set works correctly. | 99 // Check that loading a seed without a hash pref set works correctly. |
101 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed)); | 100 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed)); |
102 | 101 |
103 // Check that the loaded data is the same as the original. | 102 // Check that the loaded data is the same as the original. |
104 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); | 103 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); |
105 // Make sure the pref hasn't been changed. | 104 // Make sure the pref hasn't been changed. |
106 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 105 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
107 EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed)); | 106 EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed)); |
108 | 107 |
109 // Check that loading a seed with the correct hash works. | 108 // Check that loading a seed with the correct hash works. |
(...skipping 10 matching lines...) Expand all Loading... |
120 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 119 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
121 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); | 120 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); |
122 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); | 121 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); |
123 | 122 |
124 // Check that having no seed in prefs results in a return value of false. | 123 // Check that having no seed in prefs results in a return value of false. |
125 prefs.ClearPref(prefs::kVariationsSeed); | 124 prefs.ClearPref(prefs::kVariationsSeed); |
126 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); | 125 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); |
127 } | 126 } |
128 | 127 |
129 TEST(VariationsSeedStoreTest, StoreSeedData) { | 128 TEST(VariationsSeedStoreTest, StoreSeedData) { |
130 const variations::VariationsSeed seed = CreateTestSeed(); | 129 const VariationsSeed seed = CreateTestSeed(); |
131 const std::string serialized_seed = SerializeSeed(seed); | 130 const std::string serialized_seed = SerializeSeed(seed); |
132 | 131 |
133 TestingPrefServiceSimple prefs; | 132 TestingPrefServiceSimple prefs; |
134 VariationsSeedStore::RegisterPrefs(prefs.registry()); | 133 VariationsSeedStore::RegisterPrefs(prefs.registry()); |
135 | 134 |
136 TestVariationsSeedStore seed_store(&prefs); | 135 TestVariationsSeedStore seed_store(&prefs); |
137 | 136 |
138 EXPECT_TRUE(seed_store.StoreSeedForTesting(serialized_seed)); | 137 EXPECT_TRUE(seed_store.StoreSeedForTesting(serialized_seed)); |
139 // Make sure the pref was actually set. | 138 // Make sure the pref was actually set. |
140 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 139 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
141 | 140 |
142 std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed); | 141 std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed); |
143 std::string decoded_serialized_seed; | 142 std::string decoded_serialized_seed; |
144 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed, | 143 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed, |
145 &decoded_serialized_seed)); | 144 &decoded_serialized_seed)); |
146 // Make sure the stored seed from pref is the same as the seed we created. | 145 // Make sure the stored seed from pref is the same as the seed we created. |
147 EXPECT_EQ(serialized_seed, decoded_serialized_seed); | 146 EXPECT_EQ(serialized_seed, decoded_serialized_seed); |
148 | 147 |
149 // Check if trying to store a bad seed leaves the pref unchanged. | 148 // Check if trying to store a bad seed leaves the pref unchanged. |
150 prefs.ClearPref(prefs::kVariationsSeed); | 149 prefs.ClearPref(prefs::kVariationsSeed); |
151 EXPECT_FALSE(seed_store.StoreSeedForTesting("should fail")); | 150 EXPECT_FALSE(seed_store.StoreSeedForTesting("should fail")); |
152 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 151 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
153 } | 152 } |
154 | 153 |
155 TEST(VariationsSeedStoreTest, StoreSeedData_ParsedSeed) { | 154 TEST(VariationsSeedStoreTest, StoreSeedData_ParsedSeed) { |
156 const variations::VariationsSeed seed = CreateTestSeed(); | 155 const VariationsSeed seed = CreateTestSeed(); |
157 const std::string serialized_seed = SerializeSeed(seed); | 156 const std::string serialized_seed = SerializeSeed(seed); |
158 | 157 |
159 TestingPrefServiceSimple prefs; | 158 TestingPrefServiceSimple prefs; |
160 VariationsSeedStore::RegisterPrefs(prefs.registry()); | 159 VariationsSeedStore::RegisterPrefs(prefs.registry()); |
161 TestVariationsSeedStore seed_store(&prefs); | 160 TestVariationsSeedStore seed_store(&prefs); |
162 | 161 |
163 variations::VariationsSeed parsed_seed; | 162 VariationsSeed parsed_seed; |
164 EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), | 163 EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), |
165 base::Time::Now(), &parsed_seed)); | 164 base::Time::Now(), &parsed_seed)); |
166 EXPECT_EQ(serialized_seed, SerializeSeed(parsed_seed)); | 165 EXPECT_EQ(serialized_seed, SerializeSeed(parsed_seed)); |
167 } | 166 } |
168 | 167 |
169 TEST(VariationsSeedStoreTest, VerifySeedSignature) { | 168 TEST(VariationsSeedStoreTest, VerifySeedSignature) { |
170 // The below seed and signature pair were generated using the server's | 169 // The below seed and signature pair were generated using the server's |
171 // private key. | 170 // private key. |
172 const std::string base64_seed_data = | 171 const std::string base64_seed_data = |
173 "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5p" | 172 "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5p" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 seed_store.VerifySeedSignature(seed_data, base64_seed_data)); | 214 seed_store.VerifySeedSignature(seed_data, base64_seed_data)); |
216 #endif | 215 #endif |
217 | 216 |
218 // Using a different seed should not match the signature. | 217 // Using a different seed should not match the signature. |
219 seed_data[0] = 'x'; | 218 seed_data[0] = 'x'; |
220 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_INVALID_SEED, | 219 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_INVALID_SEED, |
221 seed_store.VerifySeedSignature(seed_data, base64_seed_signature)); | 220 seed_store.VerifySeedSignature(seed_data, base64_seed_signature)); |
222 } | 221 } |
223 | 222 |
224 } // namespace chrome_variations | 223 } // namespace chrome_variations |
OLD | NEW |