OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "components/variations/variations_seed_processor.h" | 5 #include "components/variations/variations_seed_processor.h" |
6 | 6 |
| 7 #include <map> |
7 #include <vector> | 8 #include <vector> |
8 | 9 |
| 10 #include "base/bind.h" |
9 #include "base/command_line.h" | 11 #include "base/command_line.h" |
10 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/strings/utf_string_conversions.h" |
11 #include "components/variations/processed_study.h" | 14 #include "components/variations/processed_study.h" |
12 #include "components/variations/variations_associated_data.h" | 15 #include "components/variations/variations_associated_data.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
14 | 17 |
15 namespace chrome_variations { | 18 namespace chrome_variations { |
16 | 19 |
17 namespace { | 20 namespace { |
18 | 21 |
19 // Converts |time| to Study proto format. | 22 // Converts |time| to Study proto format. |
20 int64 TimeToProtoTime(const base::Time& time) { | 23 int64 TimeToProtoTime(const base::Time& time) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 bool IsFieldTrialActive(const std::string& trial_name) { | 70 bool IsFieldTrialActive(const std::string& trial_name) { |
68 base::FieldTrial::ActiveGroups active_groups; | 71 base::FieldTrial::ActiveGroups active_groups; |
69 base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups); | 72 base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups); |
70 for (size_t i = 0; i < active_groups.size(); ++i) { | 73 for (size_t i = 0; i < active_groups.size(); ++i) { |
71 if (active_groups[i].trial_name == trial_name) | 74 if (active_groups[i].trial_name == trial_name) |
72 return true; | 75 return true; |
73 } | 76 } |
74 return false; | 77 return false; |
75 } | 78 } |
76 | 79 |
| 80 class TestOverrideStringCallback { |
| 81 public: |
| 82 typedef std::map<uint32_t, base::string16> OverrideMap; |
| 83 |
| 84 TestOverrideStringCallback() : |
| 85 callback_(base::Bind( |
| 86 &TestOverrideStringCallback::Override, base::Unretained(this))) { |
| 87 } |
| 88 |
| 89 virtual ~TestOverrideStringCallback() {} |
| 90 |
| 91 const VariationsSeedProcessor::UIStringOverrideCallback& callback() const { |
| 92 return callback_; |
| 93 } |
| 94 |
| 95 const OverrideMap& overrides() const { return overrides_; } |
| 96 |
| 97 private: |
| 98 void Override(uint32_t hash, const base::string16& string) { |
| 99 overrides_[hash] = string; |
| 100 } |
| 101 |
| 102 VariationsSeedProcessor::UIStringOverrideCallback callback_; |
| 103 OverrideMap overrides_; |
| 104 |
| 105 DISALLOW_COPY_AND_ASSIGN(TestOverrideStringCallback); |
| 106 }; |
| 107 |
77 } // namespace | 108 } // namespace |
78 | 109 |
79 class VariationsSeedProcessorTest : public ::testing::Test { | 110 class VariationsSeedProcessorTest : public ::testing::Test { |
80 public: | 111 public: |
81 VariationsSeedProcessorTest() { | 112 VariationsSeedProcessorTest() { |
82 } | 113 } |
83 | 114 |
84 virtual ~VariationsSeedProcessorTest() { | 115 virtual ~VariationsSeedProcessorTest() { |
85 // Ensure that the maps are cleared between tests, since they are stored as | 116 // Ensure that the maps are cleared between tests, since they are stored as |
86 // process singletons. | 117 // process singletons. |
87 testing::ClearAllVariationIDs(); | 118 testing::ClearAllVariationIDs(); |
88 testing::ClearAllVariationParams(); | 119 testing::ClearAllVariationParams(); |
89 } | 120 } |
90 | 121 |
91 bool CreateTrialFromStudy(const Study* study) { | 122 bool CreateTrialFromStudy(const Study* study) { |
92 ProcessedStudy processed_study; | 123 ProcessedStudy processed_study; |
93 if (processed_study.Init(study, false)) { | 124 if (processed_study.Init(study, false)) { |
94 VariationsSeedProcessor().CreateTrialFromStudy(processed_study); | 125 VariationsSeedProcessor().CreateTrialFromStudy( |
| 126 processed_study, override_callback_.callback()); |
95 return true; | 127 return true; |
96 } | 128 } |
97 return false; | 129 return false; |
98 } | 130 } |
99 | 131 |
| 132 protected: |
| 133 TestOverrideStringCallback override_callback_; |
| 134 |
100 private: | 135 private: |
101 DISALLOW_COPY_AND_ASSIGN(VariationsSeedProcessorTest); | 136 DISALLOW_COPY_AND_ASSIGN(VariationsSeedProcessorTest); |
102 }; | 137 }; |
103 | 138 |
104 TEST_F(VariationsSeedProcessorTest, AllowForceGroupAndVariationId) { | 139 TEST_F(VariationsSeedProcessorTest, AllowForceGroupAndVariationId) { |
105 CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag1); | 140 CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag1); |
106 | 141 |
107 base::FieldTrialList field_trial_list(NULL); | 142 base::FieldTrialList field_trial_list(NULL); |
108 | 143 |
109 Study study = CreateStudyWithFlagGroups(100, 0, 0); | 144 Study study = CreateStudyWithFlagGroups(100, 0, 0); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 | 224 |
190 const base::Version version("20.0.0.0"); | 225 const base::Version version("20.0.0.0"); |
191 | 226 |
192 // Check that adding [expired, non-expired] activates the non-expired one. | 227 // Check that adding [expired, non-expired] activates the non-expired one. |
193 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName)); | 228 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName)); |
194 { | 229 { |
195 base::FieldTrialList field_trial_list(NULL); | 230 base::FieldTrialList field_trial_list(NULL); |
196 study1->set_expiry_date(TimeToProtoTime(year_ago)); | 231 study1->set_expiry_date(TimeToProtoTime(year_ago)); |
197 seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(), | 232 seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(), |
198 version, Study_Channel_STABLE, | 233 version, Study_Channel_STABLE, |
199 Study_FormFactor_DESKTOP, ""); | 234 Study_FormFactor_DESKTOP, "", |
| 235 override_callback_.callback()); |
200 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName)); | 236 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName)); |
201 } | 237 } |
202 | 238 |
203 // Check that adding [non-expired, expired] activates the non-expired one. | 239 // Check that adding [non-expired, expired] activates the non-expired one. |
204 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName)); | 240 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName)); |
205 { | 241 { |
206 base::FieldTrialList field_trial_list(NULL); | 242 base::FieldTrialList field_trial_list(NULL); |
207 study1->clear_expiry_date(); | 243 study1->clear_expiry_date(); |
208 study2->set_expiry_date(TimeToProtoTime(year_ago)); | 244 study2->set_expiry_date(TimeToProtoTime(year_ago)); |
209 seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(), | 245 seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(), |
210 version, Study_Channel_STABLE, | 246 version, Study_Channel_STABLE, |
211 Study_FormFactor_DESKTOP, ""); | 247 Study_FormFactor_DESKTOP, "", |
| 248 override_callback_.callback()); |
212 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName)); | 249 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName)); |
213 } | 250 } |
214 } | 251 } |
215 | 252 |
| 253 TEST_F(VariationsSeedProcessorTest, OverrideUIStrings) { |
| 254 base::FieldTrialList field_trial_list(NULL); |
| 255 |
| 256 Study study; |
| 257 study.set_name("Study1"); |
| 258 study.set_default_experiment_name("B"); |
| 259 study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); |
| 260 |
| 261 Study_Experiment* experiment1 = AddExperiment("A", 0, &study); |
| 262 Study_Experiment_OverrideUIString* override = |
| 263 experiment1->add_override_ui_string(); |
| 264 |
| 265 override->set_name_hash(1234); |
| 266 override->set_value("test"); |
| 267 |
| 268 Study_Experiment* experiment2 = AddExperiment("B", 1, &study); |
| 269 |
| 270 EXPECT_TRUE(CreateTrialFromStudy(&study)); |
| 271 |
| 272 const TestOverrideStringCallback::OverrideMap& overrides = |
| 273 override_callback_.overrides(); |
| 274 |
| 275 EXPECT_TRUE(overrides.empty()); |
| 276 |
| 277 study.set_name("Study2"); |
| 278 experiment1->set_probability_weight(1); |
| 279 experiment2->set_probability_weight(0); |
| 280 |
| 281 EXPECT_TRUE(CreateTrialFromStudy(&study)); |
| 282 |
| 283 EXPECT_EQ(1u, overrides.size()); |
| 284 TestOverrideStringCallback::OverrideMap::const_iterator it = |
| 285 overrides.find(1234); |
| 286 EXPECT_NE(overrides.end(), it); |
| 287 EXPECT_EQ(base::ASCIIToUTF16("test"), it->second); |
| 288 } |
| 289 |
| 290 TEST_F(VariationsSeedProcessorTest, OverrideUIStringsWithForcingFlag) { |
| 291 Study study = CreateStudyWithFlagGroups(100, 0, 0); |
| 292 ASSERT_EQ(kForcingFlag1, study.experiment(1).forcing_flag()); |
| 293 |
| 294 study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); |
| 295 Study_Experiment_OverrideUIString* override = |
| 296 study.mutable_experiment(1)->add_override_ui_string(); |
| 297 override->set_name_hash(1234); |
| 298 override->set_value("test"); |
| 299 |
| 300 CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag1); |
| 301 base::FieldTrialList field_trial_list(NULL); |
| 302 EXPECT_TRUE(CreateTrialFromStudy(&study)); |
| 303 EXPECT_EQ(kFlagGroup1Name, base::FieldTrialList::FindFullName(study.name())); |
| 304 |
| 305 const TestOverrideStringCallback::OverrideMap& overrides = |
| 306 override_callback_.overrides(); |
| 307 EXPECT_EQ(1u, overrides.size()); |
| 308 TestOverrideStringCallback::OverrideMap::const_iterator it = |
| 309 overrides.find(1234); |
| 310 EXPECT_NE(overrides.end(), it); |
| 311 EXPECT_EQ(base::ASCIIToUTF16("test"), it->second); |
| 312 } |
| 313 |
216 TEST_F(VariationsSeedProcessorTest, ValidateStudy) { | 314 TEST_F(VariationsSeedProcessorTest, ValidateStudy) { |
217 Study study; | 315 Study study; |
218 study.set_default_experiment_name("def"); | 316 study.set_default_experiment_name("def"); |
219 AddExperiment("abc", 100, &study); | 317 AddExperiment("abc", 100, &study); |
220 Study_Experiment* default_group = AddExperiment("def", 200, &study); | 318 Study_Experiment* default_group = AddExperiment("def", 200, &study); |
221 | 319 |
222 ProcessedStudy processed_study; | 320 ProcessedStudy processed_study; |
223 EXPECT_TRUE(processed_study.Init(&study, false)); | 321 EXPECT_TRUE(processed_study.Init(&study, false)); |
224 EXPECT_EQ(300, processed_study.total_probability()); | 322 EXPECT_EQ(300, processed_study.total_probability()); |
225 | 323 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 study3->set_name("C"); | 414 study3->set_name("C"); |
317 study3->set_default_experiment_name("Default"); | 415 study3->set_default_experiment_name("Default"); |
318 AddExperiment("CC", 100, study3); | 416 AddExperiment("CC", 100, study3); |
319 AddExperiment("Default", 0, study3); | 417 AddExperiment("Default", 0, study3); |
320 study3->set_activation_type(Study_ActivationType_ACTIVATION_EXPLICIT); | 418 study3->set_activation_type(Study_ActivationType_ACTIVATION_EXPLICIT); |
321 | 419 |
322 VariationsSeedProcessor seed_processor; | 420 VariationsSeedProcessor seed_processor; |
323 seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(), | 421 seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(), |
324 base::Version("20.0.0.0"), | 422 base::Version("20.0.0.0"), |
325 Study_Channel_STABLE, | 423 Study_Channel_STABLE, |
326 Study_FormFactor_DESKTOP, ""); | 424 Study_FormFactor_DESKTOP, "", |
| 425 override_callback_.callback()); |
327 | 426 |
328 // Non-specified and ACTIVATION_EXPLICIT should not start active, but | 427 // Non-specified and ACTIVATION_EXPLICIT should not start active, but |
329 // ACTIVATION_AUTO should. | 428 // ACTIVATION_AUTO should. |
330 EXPECT_FALSE(IsFieldTrialActive("A")); | 429 EXPECT_FALSE(IsFieldTrialActive("A")); |
331 EXPECT_TRUE(IsFieldTrialActive("B")); | 430 EXPECT_TRUE(IsFieldTrialActive("B")); |
332 EXPECT_FALSE(IsFieldTrialActive("C")); | 431 EXPECT_FALSE(IsFieldTrialActive("C")); |
333 | 432 |
334 EXPECT_EQ("AA", base::FieldTrialList::FindFullName("A")); | 433 EXPECT_EQ("AA", base::FieldTrialList::FindFullName("A")); |
335 EXPECT_EQ("BB", base::FieldTrialList::FindFullName("B")); | 434 EXPECT_EQ("BB", base::FieldTrialList::FindFullName("B")); |
336 EXPECT_EQ("CC", base::FieldTrialList::FindFullName("C")); | 435 EXPECT_EQ("CC", base::FieldTrialList::FindFullName("C")); |
(...skipping 13 matching lines...) Expand all Loading... |
350 study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); | 449 study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); |
351 | 450 |
352 EXPECT_TRUE(CreateTrialFromStudy(&study)); | 451 EXPECT_TRUE(CreateTrialFromStudy(&study)); |
353 EXPECT_TRUE(IsFieldTrialActive(kFlagStudyName)); | 452 EXPECT_TRUE(IsFieldTrialActive(kFlagStudyName)); |
354 | 453 |
355 EXPECT_EQ(kFlagGroup1Name, | 454 EXPECT_EQ(kFlagGroup1Name, |
356 base::FieldTrialList::FindFullName(kFlagStudyName)); | 455 base::FieldTrialList::FindFullName(kFlagStudyName)); |
357 } | 456 } |
358 | 457 |
359 } // namespace chrome_variations | 458 } // namespace chrome_variations |
OLD | NEW |