OLD | NEW |
(Empty) | |
| 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 "components/variations/variations_seed_simulator.h" |
| 6 |
| 7 #include <map> |
| 8 |
| 9 #include "components/variations/processed_study.h" |
| 10 #include "components/variations/proto/study.pb.h" |
| 11 #include "components/variations/variations_associated_data.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 |
| 14 namespace chrome_variations { |
| 15 |
| 16 namespace { |
| 17 |
| 18 // An implementation of EntropyProvider that always returns a specific entropy |
| 19 // value, regardless of field trial. |
| 20 class TestEntropyProvider : public base::FieldTrial::EntropyProvider { |
| 21 public: |
| 22 explicit TestEntropyProvider(double entropy_value) |
| 23 : entropy_value_(entropy_value) {} |
| 24 virtual ~TestEntropyProvider() {} |
| 25 |
| 26 // base::FieldTrial::EntropyProvider implementation: |
| 27 virtual double GetEntropyForTrial(const std::string& trial_name, |
| 28 uint32 randomization_seed) const OVERRIDE { |
| 29 return entropy_value_; |
| 30 } |
| 31 |
| 32 private: |
| 33 const double entropy_value_; |
| 34 |
| 35 DISALLOW_COPY_AND_ASSIGN(TestEntropyProvider); |
| 36 }; |
| 37 |
| 38 // Creates and activates a single-group field trial with name |trial_name| and |
| 39 // group |group_name| and variations |params| (if not NULL). |
| 40 void CreateTrial(const std::string& trial_name, |
| 41 const std::string& group_name, |
| 42 const std::map<std::string, std::string>* params) { |
| 43 base::FieldTrialList::CreateFieldTrial(trial_name, group_name); |
| 44 if (params != NULL) |
| 45 AssociateVariationParams(trial_name, group_name, *params); |
| 46 base::FieldTrialList::FindFullName(trial_name); |
| 47 } |
| 48 |
| 49 // Creates a study with the given |study_name| and |consistency|. |
| 50 Study CreateStudy(const std::string& study_name, |
| 51 Study_Consistency consistency) { |
| 52 Study study; |
| 53 study.set_name(study_name); |
| 54 study.set_consistency(consistency); |
| 55 return study; |
| 56 } |
| 57 |
| 58 // Adds an experiment to |study| with the specified |experiment_name| and |
| 59 // |probability| values and sets it as the study's default experiment. |
| 60 Study_Experiment* AddExperiment(const std::string& experiment_name, |
| 61 int probability, |
| 62 Study* study) { |
| 63 Study_Experiment* experiment = study->add_experiment(); |
| 64 experiment->set_name(experiment_name); |
| 65 experiment->set_probability_weight(probability); |
| 66 study->set_default_experiment_name(experiment_name); |
| 67 return experiment; |
| 68 } |
| 69 |
| 70 // Add an experiment param with |param_name| and |param_value| to |experiment|. |
| 71 Study_Experiment_Param* AddExperimentParam(const std::string& param_name, |
| 72 const std::string& param_value, |
| 73 Study_Experiment* experiment) { |
| 74 Study_Experiment_Param* param = experiment->add_param(); |
| 75 param->set_name(param_name); |
| 76 param->set_value(param_value); |
| 77 return param; |
| 78 } |
| 79 |
| 80 // Uses a VariationsSeedSimulator to simulate the differences between |studies| |
| 81 // and the current field trial state. |
| 82 int SimulateDifferences(const std::vector<ProcessedStudy>& studies) { |
| 83 TestEntropyProvider provider(0.5); |
| 84 VariationsSeedSimulator seed_simulator(provider); |
| 85 return seed_simulator.ComputeDifferences(studies); |
| 86 } |
| 87 |
| 88 class VariationsSeedSimulatorTest : public ::testing::Test { |
| 89 public: |
| 90 VariationsSeedSimulatorTest() : field_trial_list_(NULL) { |
| 91 } |
| 92 |
| 93 virtual ~VariationsSeedSimulatorTest() { |
| 94 // Ensure that the maps are cleared between tests, since they are stored as |
| 95 // process singletons. |
| 96 testing::ClearAllVariationIDs(); |
| 97 testing::ClearAllVariationParams(); |
| 98 } |
| 99 |
| 100 private: |
| 101 base::FieldTrialList field_trial_list_; |
| 102 |
| 103 DISALLOW_COPY_AND_ASSIGN(VariationsSeedSimulatorTest); |
| 104 }; |
| 105 |
| 106 } // namespace |
| 107 |
| 108 TEST_F(VariationsSeedSimulatorTest, PermanentNoChanges) { |
| 109 CreateTrial("A", "B", NULL); |
| 110 |
| 111 std::vector<ProcessedStudy> processed_studies; |
| 112 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 113 AddExperiment("B", 100, &study); |
| 114 |
| 115 std::vector<ProcessedStudy> studies; |
| 116 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 117 |
| 118 EXPECT_EQ(0, SimulateDifferences(studies)); |
| 119 } |
| 120 |
| 121 TEST_F(VariationsSeedSimulatorTest, PermanentGroupChange) { |
| 122 CreateTrial("A", "B", NULL); |
| 123 |
| 124 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 125 AddExperiment("C", 100, &study); |
| 126 |
| 127 std::vector<ProcessedStudy> studies; |
| 128 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 129 |
| 130 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 131 } |
| 132 |
| 133 TEST_F(VariationsSeedSimulatorTest, PermanentExpired) { |
| 134 CreateTrial("A", "B", NULL); |
| 135 |
| 136 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 137 AddExperiment("B", 1, &study); |
| 138 AddExperiment("C", 0, &study); |
| 139 |
| 140 std::vector<ProcessedStudy> studies; |
| 141 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, true, &studies)); |
| 142 EXPECT_TRUE(studies[0].is_expired()); |
| 143 |
| 144 // There should be a difference because the study is expired, which should |
| 145 // result in the default group "D" being chosen. |
| 146 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 147 } |
| 148 |
| 149 TEST_F(VariationsSeedSimulatorTest, SessionRandomized) { |
| 150 CreateTrial("A", "B", NULL); |
| 151 |
| 152 Study study = CreateStudy("A", Study_Consistency_SESSION); |
| 153 AddExperiment("B", 1, &study); |
| 154 AddExperiment("C", 1, &study); |
| 155 AddExperiment("D", 1, &study); |
| 156 |
| 157 std::vector<ProcessedStudy> studies; |
| 158 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 159 |
| 160 // There should be no differences, since a session randomized study can result |
| 161 // in any of the groups being chosen on startup. |
| 162 EXPECT_EQ(0, SimulateDifferences(studies)); |
| 163 } |
| 164 |
| 165 TEST_F(VariationsSeedSimulatorTest, SessionRandomizedGroupRemoved) { |
| 166 CreateTrial("A", "B", NULL); |
| 167 |
| 168 Study study = CreateStudy("A", Study_Consistency_SESSION); |
| 169 AddExperiment("C", 1, &study); |
| 170 AddExperiment("D", 1, &study); |
| 171 |
| 172 std::vector<ProcessedStudy> studies; |
| 173 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 174 |
| 175 // There should be a difference since there is no group "B" in the new config. |
| 176 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 177 } |
| 178 |
| 179 TEST_F(VariationsSeedSimulatorTest, SessionRandomizedGroupProbabilityZero) { |
| 180 CreateTrial("A", "B", NULL); |
| 181 |
| 182 Study study = CreateStudy("A", Study_Consistency_SESSION); |
| 183 AddExperiment("B", 0, &study); |
| 184 AddExperiment("C", 1, &study); |
| 185 AddExperiment("D", 1, &study); |
| 186 |
| 187 std::vector<ProcessedStudy> studies; |
| 188 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 189 |
| 190 // There should be a difference since there is group "B" has probability 0. |
| 191 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 192 } |
| 193 |
| 194 TEST_F(VariationsSeedSimulatorTest, SessionRandomizedExpired) { |
| 195 CreateTrial("A", "B", NULL); |
| 196 |
| 197 Study study = CreateStudy("A", Study_Consistency_SESSION); |
| 198 AddExperiment("B", 1, &study); |
| 199 AddExperiment("C", 1, &study); |
| 200 AddExperiment("D", 1, &study); |
| 201 |
| 202 std::vector<ProcessedStudy> studies; |
| 203 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, true, &studies)); |
| 204 EXPECT_TRUE(studies[0].is_expired()); |
| 205 |
| 206 // There should be a difference because the study is expired, which should |
| 207 // result in the default group "D" being chosen. |
| 208 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 209 } |
| 210 |
| 211 TEST_F(VariationsSeedSimulatorTest, ParamsUnchanged) { |
| 212 std::map<std::string, std::string> params; |
| 213 params["p1"] = "x"; |
| 214 params["p2"] = "y"; |
| 215 params["p3"] = "z"; |
| 216 CreateTrial("A", "B", ¶ms); |
| 217 |
| 218 std::vector<ProcessedStudy> processed_studies; |
| 219 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 220 Study_Experiment* experiment = AddExperiment("B", 100, &study); |
| 221 AddExperimentParam("p2", "y", experiment); |
| 222 AddExperimentParam("p1", "x", experiment); |
| 223 AddExperimentParam("p3", "z", experiment); |
| 224 |
| 225 std::vector<ProcessedStudy> studies; |
| 226 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 227 |
| 228 EXPECT_EQ(0, SimulateDifferences(studies)); |
| 229 } |
| 230 |
| 231 TEST_F(VariationsSeedSimulatorTest, ParamsChanged) { |
| 232 std::map<std::string, std::string> params; |
| 233 params["p1"] = "x"; |
| 234 params["p2"] = "y"; |
| 235 params["p3"] = "z"; |
| 236 CreateTrial("A", "B", ¶ms); |
| 237 |
| 238 std::vector<ProcessedStudy> processed_studies; |
| 239 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 240 Study_Experiment* experiment = AddExperiment("B", 100, &study); |
| 241 AddExperimentParam("p2", "test", experiment); |
| 242 AddExperimentParam("p1", "x", experiment); |
| 243 AddExperimentParam("p3", "z", experiment); |
| 244 |
| 245 std::vector<ProcessedStudy> studies; |
| 246 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 247 |
| 248 // The param lists differ. |
| 249 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 250 } |
| 251 |
| 252 TEST_F(VariationsSeedSimulatorTest, ParamsRemoved) { |
| 253 std::map<std::string, std::string> params; |
| 254 params["p1"] = "x"; |
| 255 params["p2"] = "y"; |
| 256 params["p3"] = "z"; |
| 257 CreateTrial("A", "B", ¶ms); |
| 258 |
| 259 std::vector<ProcessedStudy> processed_studies; |
| 260 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 261 AddExperiment("B", 100, &study); |
| 262 |
| 263 std::vector<ProcessedStudy> studies; |
| 264 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 265 |
| 266 // The current group has params, but the new config doesn't have any. |
| 267 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 268 } |
| 269 |
| 270 TEST_F(VariationsSeedSimulatorTest, ParamsAdded) { |
| 271 CreateTrial("A", "B", NULL); |
| 272 |
| 273 std::vector<ProcessedStudy> processed_studies; |
| 274 Study study = CreateStudy("A", Study_Consistency_PERMANENT); |
| 275 Study_Experiment* experiment = AddExperiment("B", 100, &study); |
| 276 AddExperimentParam("p2", "y", experiment); |
| 277 AddExperimentParam("p1", "x", experiment); |
| 278 AddExperimentParam("p3", "z", experiment); |
| 279 |
| 280 std::vector<ProcessedStudy> studies; |
| 281 EXPECT_TRUE(ProcessedStudy::ValidateAndAppendStudy(&study, false, &studies)); |
| 282 |
| 283 // The current group has no params, but the config has added some. |
| 284 EXPECT_EQ(1, SimulateDifferences(studies)); |
| 285 } |
| 286 |
| 287 } // namespace chrome_variations |
OLD | NEW |