| 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 VariationsSeed CreateTestSeed() { | 46 variations::VariationsSeed CreateTestSeed() { |
| 47 VariationsSeed seed; | 47 variations::VariationsSeed seed; |
| 48 Study* study = seed.add_study(); | 48 variations::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 Study_Experiment* experiment = study->add_experiment(); | 51 variations::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 VariationsSeed& seed) { | 59 std::string SerializeSeed(const variations::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 VariationsSeed& seed, std::string* hash) { | 66 std::string SerializeSeedBase64(const variations::VariationsSeed& seed, |
| 67 std::string* hash) { |
| 67 std::string serialized_seed = SerializeSeed(seed); | 68 std::string serialized_seed = SerializeSeed(seed); |
| 68 if (hash != NULL) { | 69 if (hash != NULL) { |
| 69 std::string sha1 = base::SHA1HashString(serialized_seed); | 70 std::string sha1 = base::SHA1HashString(serialized_seed); |
| 70 *hash = base::HexEncode(sha1.data(), sha1.size()); | 71 *hash = base::HexEncode(sha1.data(), sha1.size()); |
| 71 } | 72 } |
| 72 std::string base64_serialized_seed; | 73 std::string base64_serialized_seed; |
| 73 base::Base64Encode(serialized_seed, &base64_serialized_seed); | 74 base::Base64Encode(serialized_seed, &base64_serialized_seed); |
| 74 return base64_serialized_seed; | 75 return base64_serialized_seed; |
| 75 } | 76 } |
| 76 | 77 |
| 77 // Checks whether the pref with name |pref_name| is at its default value in | 78 // Checks whether the pref with name |pref_name| is at its default value in |
| 78 // |prefs|. | 79 // |prefs|. |
| 79 bool PrefHasDefaultValue(const TestingPrefServiceSimple& prefs, | 80 bool PrefHasDefaultValue(const TestingPrefServiceSimple& prefs, |
| 80 const char* pref_name) { | 81 const char* pref_name) { |
| 81 return prefs.FindPreference(pref_name)->IsDefaultValue(); | 82 return prefs.FindPreference(pref_name)->IsDefaultValue(); |
| 82 } | 83 } |
| 83 | 84 |
| 84 } // namespace | 85 } // namespace |
| 85 | 86 |
| 86 TEST(VariationsSeedStoreTest, LoadSeed) { | 87 TEST(VariationsSeedStoreTest, LoadSeed) { |
| 87 // Store good seed data to test if loading from prefs works. | 88 // Store good seed data to test if loading from prefs works. |
| 88 const VariationsSeed seed = CreateTestSeed(); | 89 const variations::VariationsSeed seed = CreateTestSeed(); |
| 89 std::string seed_hash; | 90 std::string seed_hash; |
| 90 const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash); | 91 const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash); |
| 91 | 92 |
| 92 TestingPrefServiceSimple prefs; | 93 TestingPrefServiceSimple prefs; |
| 93 VariationsSeedStore::RegisterPrefs(prefs.registry()); | 94 VariationsSeedStore::RegisterPrefs(prefs.registry()); |
| 94 prefs.SetString(prefs::kVariationsSeed, base64_seed); | 95 prefs.SetString(prefs::kVariationsSeed, base64_seed); |
| 95 | 96 |
| 96 TestVariationsSeedStore seed_store(&prefs); | 97 TestVariationsSeedStore seed_store(&prefs); |
| 97 | 98 |
| 98 VariationsSeed loaded_seed; | 99 variations::VariationsSeed loaded_seed; |
| 99 // Check that loading a seed without a hash pref set works correctly. | 100 // Check that loading a seed without a hash pref set works correctly. |
| 100 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed)); | 101 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed)); |
| 101 | 102 |
| 102 // Check that the loaded data is the same as the original. | 103 // Check that the loaded data is the same as the original. |
| 103 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); | 104 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); |
| 104 // Make sure the pref hasn't been changed. | 105 // Make sure the pref hasn't been changed. |
| 105 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 106 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
| 106 EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed)); | 107 EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed)); |
| 107 | 108 |
| 108 // Check that loading a seed with the correct hash works. | 109 // Check that loading a seed with the correct hash works. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 119 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 120 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
| 120 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); | 121 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); |
| 121 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); | 122 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); |
| 122 | 123 |
| 123 // Check that having no seed in prefs results in a return value of false. | 124 // Check that having no seed in prefs results in a return value of false. |
| 124 prefs.ClearPref(prefs::kVariationsSeed); | 125 prefs.ClearPref(prefs::kVariationsSeed); |
| 125 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); | 126 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); |
| 126 } | 127 } |
| 127 | 128 |
| 128 TEST(VariationsSeedStoreTest, StoreSeedData) { | 129 TEST(VariationsSeedStoreTest, StoreSeedData) { |
| 129 const VariationsSeed seed = CreateTestSeed(); | 130 const variations::VariationsSeed seed = CreateTestSeed(); |
| 130 const std::string serialized_seed = SerializeSeed(seed); | 131 const std::string serialized_seed = SerializeSeed(seed); |
| 131 | 132 |
| 132 TestingPrefServiceSimple prefs; | 133 TestingPrefServiceSimple prefs; |
| 133 VariationsSeedStore::RegisterPrefs(prefs.registry()); | 134 VariationsSeedStore::RegisterPrefs(prefs.registry()); |
| 134 | 135 |
| 135 TestVariationsSeedStore seed_store(&prefs); | 136 TestVariationsSeedStore seed_store(&prefs); |
| 136 | 137 |
| 137 EXPECT_TRUE(seed_store.StoreSeedForTesting(serialized_seed)); | 138 EXPECT_TRUE(seed_store.StoreSeedForTesting(serialized_seed)); |
| 138 // Make sure the pref was actually set. | 139 // Make sure the pref was actually set. |
| 139 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 140 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
| 140 | 141 |
| 141 std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed); | 142 std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed); |
| 142 std::string decoded_serialized_seed; | 143 std::string decoded_serialized_seed; |
| 143 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed, | 144 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed, |
| 144 &decoded_serialized_seed)); | 145 &decoded_serialized_seed)); |
| 145 // Make sure the stored seed from pref is the same as the seed we created. | 146 // Make sure the stored seed from pref is the same as the seed we created. |
| 146 EXPECT_EQ(serialized_seed, decoded_serialized_seed); | 147 EXPECT_EQ(serialized_seed, decoded_serialized_seed); |
| 147 | 148 |
| 148 // Check if trying to store a bad seed leaves the pref unchanged. | 149 // Check if trying to store a bad seed leaves the pref unchanged. |
| 149 prefs.ClearPref(prefs::kVariationsSeed); | 150 prefs.ClearPref(prefs::kVariationsSeed); |
| 150 EXPECT_FALSE(seed_store.StoreSeedForTesting("should fail")); | 151 EXPECT_FALSE(seed_store.StoreSeedForTesting("should fail")); |
| 151 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); | 152 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); |
| 152 } | 153 } |
| 153 | 154 |
| 154 TEST(VariationsSeedStoreTest, StoreSeedData_ParsedSeed) { | 155 TEST(VariationsSeedStoreTest, StoreSeedData_ParsedSeed) { |
| 155 const VariationsSeed seed = CreateTestSeed(); | 156 const variations::VariationsSeed seed = CreateTestSeed(); |
| 156 const std::string serialized_seed = SerializeSeed(seed); | 157 const std::string serialized_seed = SerializeSeed(seed); |
| 157 | 158 |
| 158 TestingPrefServiceSimple prefs; | 159 TestingPrefServiceSimple prefs; |
| 159 VariationsSeedStore::RegisterPrefs(prefs.registry()); | 160 VariationsSeedStore::RegisterPrefs(prefs.registry()); |
| 160 TestVariationsSeedStore seed_store(&prefs); | 161 TestVariationsSeedStore seed_store(&prefs); |
| 161 | 162 |
| 162 VariationsSeed parsed_seed; | 163 variations::VariationsSeed parsed_seed; |
| 163 EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), | 164 EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), |
| 164 base::Time::Now(), &parsed_seed)); | 165 base::Time::Now(), &parsed_seed)); |
| 165 EXPECT_EQ(serialized_seed, SerializeSeed(parsed_seed)); | 166 EXPECT_EQ(serialized_seed, SerializeSeed(parsed_seed)); |
| 166 } | 167 } |
| 167 | 168 |
| 168 TEST(VariationsSeedStoreTest, VerifySeedSignature) { | 169 TEST(VariationsSeedStoreTest, VerifySeedSignature) { |
| 169 // The below seed and signature pair were generated using the server's | 170 // The below seed and signature pair were generated using the server's |
| 170 // private key. | 171 // private key. |
| 171 const std::string base64_seed_data = | 172 const std::string base64_seed_data = |
| 172 "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5p" | 173 "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5p" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 seed_store.VerifySeedSignature(seed_data, base64_seed_data)); | 215 seed_store.VerifySeedSignature(seed_data, base64_seed_data)); |
| 215 #endif | 216 #endif |
| 216 | 217 |
| 217 // Using a different seed should not match the signature. | 218 // Using a different seed should not match the signature. |
| 218 seed_data[0] = 'x'; | 219 seed_data[0] = 'x'; |
| 219 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_INVALID_SEED, | 220 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_INVALID_SEED, |
| 220 seed_store.VerifySeedSignature(seed_data, base64_seed_signature)); | 221 seed_store.VerifySeedSignature(seed_data, base64_seed_signature)); |
| 221 } | 222 } |
| 222 | 223 |
| 223 } // namespace chrome_variations | 224 } // namespace chrome_variations |
| OLD | NEW |