Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: components/variations/variations_seed_processor_unittest.cc

Issue 1984003002: Use low entropy for studies that send experiment IDs to Google properties. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
11 #include <memory> 11 #include <memory>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/bind.h" 15 #include "base/bind.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/feature_list.h" 17 #include "base/feature_list.h"
18 #include "base/format_macros.h" 18 #include "base/format_macros.h"
19 #include "base/macros.h" 19 #include "base/macros.h"
20 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
23 #include "base/test/mock_entropy_provider.h"
23 #include "components/variations/processed_study.h" 24 #include "components/variations/processed_study.h"
24 #include "components/variations/study_filtering.h" 25 #include "components/variations/study_filtering.h"
25 #include "components/variations/variations_associated_data.h" 26 #include "components/variations/variations_associated_data.h"
26 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
27 28
28 namespace variations { 29 namespace variations {
29 30
30 namespace { 31 namespace {
31 32
32 // Converts |time| to Study proto format. 33 // Converts |time| to Study proto format.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 ~VariationsSeedProcessorTest() override { 114 ~VariationsSeedProcessorTest() override {
114 // Ensure that the maps are cleared between tests, since they are stored as 115 // Ensure that the maps are cleared between tests, since they are stored as
115 // process singletons. 116 // process singletons.
116 testing::ClearAllVariationIDs(); 117 testing::ClearAllVariationIDs();
117 testing::ClearAllVariationParams(); 118 testing::ClearAllVariationParams();
118 119
119 base::FeatureList::ClearInstanceForTesting(); 120 base::FeatureList::ClearInstanceForTesting();
120 } 121 }
121 122
122 bool CreateTrialFromStudy(const Study& study) { 123 bool CreateTrialFromStudy(const Study& study) {
123 return CreateTrialFromStudyWithFeatureList(study, &feature_list_); 124 return CreateTrialFromStudyWithFeatureListAndEntropyOverride(
125 study, nullptr, &feature_list_);
126 }
127
128 bool CreateTrialFromStudyWithEntropyOverride(
129 const Study& study,
130 const base::FieldTrial::EntropyProvider* override_entropy_provider) {
131 return CreateTrialFromStudyWithFeatureListAndEntropyOverride(
132 study, override_entropy_provider, &feature_list_);
124 } 133 }
125 134
126 bool CreateTrialFromStudyWithFeatureList(const Study& study, 135 bool CreateTrialFromStudyWithFeatureList(const Study& study,
127 base::FeatureList* feature_list) { 136 base::FeatureList* feature_list) {
137 return CreateTrialFromStudyWithFeatureListAndEntropyOverride(study, nullptr,
138 feature_list);
139 }
140
141 bool CreateTrialFromStudyWithFeatureListAndEntropyOverride(
142 const Study& study,
143 const base::FieldTrial::EntropyProvider* override_entropy_provider,
144 base::FeatureList* feature_list) {
128 ProcessedStudy processed_study; 145 ProcessedStudy processed_study;
129 const bool is_expired = internal::IsStudyExpired(study, base::Time::Now()); 146 const bool is_expired = internal::IsStudyExpired(study, base::Time::Now());
130 if (processed_study.Init(&study, is_expired)) { 147 if (processed_study.Init(&study, is_expired)) {
131 VariationsSeedProcessor().CreateTrialFromStudy( 148 VariationsSeedProcessor().CreateTrialFromStudy(
132 processed_study, override_callback_.callback(), feature_list); 149 processed_study, override_callback_.callback(),
150 override_entropy_provider, feature_list);
133 return true; 151 return true;
134 } 152 }
135 return false; 153 return false;
136 } 154 }
137 155
138 protected: 156 protected:
139 base::FeatureList feature_list_; 157 base::FeatureList feature_list_;
140 TestOverrideStringCallback override_callback_; 158 TestOverrideStringCallback override_callback_;
141 159
142 private: 160 private:
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 251
234 // Check that adding [expired, non-expired] activates the non-expired one. 252 // Check that adding [expired, non-expired] activates the non-expired one.
235 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName)); 253 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName));
236 { 254 {
237 base::FeatureList feature_list; 255 base::FeatureList feature_list;
238 base::FieldTrialList field_trial_list(nullptr); 256 base::FieldTrialList field_trial_list(nullptr);
239 study1->set_expiry_date(TimeToProtoTime(year_ago)); 257 study1->set_expiry_date(TimeToProtoTime(year_ago));
240 seed_processor.CreateTrialsFromSeed( 258 seed_processor.CreateTrialsFromSeed(
241 seed, "en-CA", base::Time::Now(), version, Study_Channel_STABLE, 259 seed, "en-CA", base::Time::Now(), version, Study_Channel_STABLE,
242 Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback(), 260 Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback(),
243 &feature_list); 261 nullptr, &feature_list);
244 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName)); 262 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName));
245 } 263 }
246 264
247 // Check that adding [non-expired, expired] activates the non-expired one. 265 // Check that adding [non-expired, expired] activates the non-expired one.
248 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName)); 266 ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName));
249 { 267 {
250 base::FeatureList feature_list; 268 base::FeatureList feature_list;
251 base::FieldTrialList field_trial_list(nullptr); 269 base::FieldTrialList field_trial_list(nullptr);
252 study1->clear_expiry_date(); 270 study1->clear_expiry_date();
253 study2->set_expiry_date(TimeToProtoTime(year_ago)); 271 study2->set_expiry_date(TimeToProtoTime(year_ago));
254 seed_processor.CreateTrialsFromSeed( 272 seed_processor.CreateTrialsFromSeed(
255 seed, "en-CA", base::Time::Now(), version, Study_Channel_STABLE, 273 seed, "en-CA", base::Time::Now(), version, Study_Channel_STABLE,
256 Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback(), 274 Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback(),
257 &feature_list); 275 nullptr, &feature_list);
258 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName)); 276 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName));
259 } 277 }
260 } 278 }
261 279
262 TEST_F(VariationsSeedProcessorTest, OverrideUIStrings) { 280 TEST_F(VariationsSeedProcessorTest, OverrideUIStrings) {
263 base::FieldTrialList field_trial_list(nullptr); 281 base::FieldTrialList field_trial_list(nullptr);
264 282
265 Study study; 283 Study study;
266 study.set_name("Study1"); 284 study.set_name("Study1");
267 study.set_default_experiment_name("B"); 285 study.set_default_experiment_name("B");
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 study3->set_name("C"); 513 study3->set_name("C");
496 study3->set_default_experiment_name("Default"); 514 study3->set_default_experiment_name("Default");
497 AddExperiment("CC", 100, study3); 515 AddExperiment("CC", 100, study3);
498 AddExperiment("Default", 0, study3); 516 AddExperiment("Default", 0, study3);
499 study3->set_activation_type(Study_ActivationType_ACTIVATION_EXPLICIT); 517 study3->set_activation_type(Study_ActivationType_ACTIVATION_EXPLICIT);
500 518
501 VariationsSeedProcessor seed_processor; 519 VariationsSeedProcessor seed_processor;
502 seed_processor.CreateTrialsFromSeed( 520 seed_processor.CreateTrialsFromSeed(
503 seed, "en-CA", base::Time::Now(), base::Version("20.0.0.0"), 521 seed, "en-CA", base::Time::Now(), base::Version("20.0.0.0"),
504 Study_Channel_STABLE, Study_FormFactor_DESKTOP, "", "", "", 522 Study_Channel_STABLE, Study_FormFactor_DESKTOP, "", "", "",
505 override_callback_.callback(), &feature_list_); 523 override_callback_.callback(), nullptr, &feature_list_);
506 524
507 // Non-specified and ACTIVATION_EXPLICIT should not start active, but 525 // Non-specified and ACTIVATION_EXPLICIT should not start active, but
508 // ACTIVATION_AUTO should. 526 // ACTIVATION_AUTO should.
509 EXPECT_FALSE(base::FieldTrialList::IsTrialActive("A")); 527 EXPECT_FALSE(base::FieldTrialList::IsTrialActive("A"));
510 EXPECT_TRUE(base::FieldTrialList::IsTrialActive("B")); 528 EXPECT_TRUE(base::FieldTrialList::IsTrialActive("B"));
511 EXPECT_FALSE(base::FieldTrialList::IsTrialActive("C")); 529 EXPECT_FALSE(base::FieldTrialList::IsTrialActive("C"));
512 530
513 EXPECT_EQ("AA", base::FieldTrialList::FindFullName("A")); 531 EXPECT_EQ("AA", base::FieldTrialList::FindFullName("A"));
514 EXPECT_EQ("BB", base::FieldTrialList::FindFullName("B")); 532 EXPECT_EQ("BB", base::FieldTrialList::FindFullName("B"));
515 EXPECT_EQ("CC", base::FieldTrialList::FindFullName("C")); 533 EXPECT_EQ("CC", base::FieldTrialList::FindFullName("C"));
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 823
806 EXPECT_TRUE(CreateTrialFromStudyWithFeatureList(study, feature_list.get())); 824 EXPECT_TRUE(CreateTrialFromStudyWithFeatureList(study, feature_list.get()));
807 base::FeatureList::SetInstance(std::move(feature_list)); 825 base::FeatureList::SetInstance(std::move(feature_list));
808 826
809 // Tthe feature should not be enabled, because the study is expired. 827 // Tthe feature should not be enabled, because the study is expired.
810 EXPECT_EQ(test_case.expected_feature_enabled, 828 EXPECT_EQ(test_case.expected_feature_enabled,
811 base::FeatureList::IsEnabled(test_case.feature)); 829 base::FeatureList::IsEnabled(test_case.feature));
812 } 830 }
813 } 831 }
814 832
833 TEST_F(VariationsSeedProcessorTest, LowEntropyStudyTest) {
834 const std::string kTrial1Name = "A";
835 const std::string kTrial2Name = "B";
836 const std::string kGroup1Name = "AA";
837 const std::string kDefaultName = "Default";
838
839 VariationsSeed seed;
840 Study* study1 = seed.add_study();
841 study1->set_name(kTrial1Name);
842 study1->set_consistency(variations::Study_Consistency_PERMANENT);
843 study1->set_default_experiment_name(kDefaultName);
844 AddExperiment(kGroup1Name, 50, study1);
845 AddExperiment(kDefaultName, 50, study1);
846 Study* study2 = seed.add_study();
847 study2->set_name(kTrial2Name);
848 study2->set_consistency(variations::Study_Consistency_PERMANENT);
849 study2->set_default_experiment_name(kDefaultName);
850 AddExperiment(kGroup1Name, 50, study2);
851 AddExperiment(kDefaultName, 50, study2);
852 study2->mutable_experiment(0)->set_google_web_experiment_id(kExperimentId);
853
854 // An entorpy value of 0.1 will cause the AA group to be chosen, since AA is
855 // the only non-default group, and has a probability percent above 0.1.
856 base::MockEntropyProvider* mock_high_entropy_provider =
857 new base::MockEntropyProvider(0.1);
858
859 // The field trial list takes ownership of the provider.
860 base::FieldTrialList field_trial_list(mock_high_entropy_provider);
861
862 // Use a stack instance, since nothing takes ownership of this provider.
863 // This entropy value will cause the default group to be chosen since it's a
864 // 50/50 trial.
865 base::MockEntropyProvider mock_low_entropy_provider(0.9);
866
867 EXPECT_TRUE(CreateTrialFromStudyWithEntropyOverride(
868 *study1, &mock_low_entropy_provider));
869 EXPECT_TRUE(CreateTrialFromStudyWithEntropyOverride(
870 *study2, &mock_low_entropy_provider));
871
872 // Since no experiment in study1 sends experiment IDs, it will use the high
873 // entropy provider, which selects the non-default group.
874 EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrial1Name));
875
876 // Since an experiment in study2 has google_web_experiment_id set, it will use
877 // the low entropy provider, which selects the default group.
878 EXPECT_EQ(kDefaultName, base::FieldTrialList::FindFullName(kTrial2Name));
879 }
880
815 } // namespace variations 881 } // namespace variations
OLDNEW
« no previous file with comments | « components/variations/variations_seed_processor.cc ('k') | components/variations/variations_seed_simulator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698