Added a SetForced method to allow forcing a new set of group bucketting.
This will be needed by the Finch client (soon to be known as the Variations Service) that will get updated information about FieldTrials and pre-feed the field trial list based on this information.
So this is different from CreateFieldTrial, which forced a group choice, this new method allows forcing a new set of appended groups.
BUG=121695
TEST=build\Debug\base_unittests.exe --gtest_filter=FieldTrialTest.SetForced
Review URL: https://chromiumcodereview.appspot.com/10382018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135748 0039d316-1c4b-4281-b951-d872f2087c98
CrOS-Libchrome-Original-Commit: 0284bf7c813d9c57864048123abc7d456ee4f38a
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index 245f2bf..6d4f2eb 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -170,6 +170,21 @@
enable_benchmarking_ = true;
}
+void FieldTrial::SetForced() {
+ // We might have been forced before (e.g., by CreateFieldTrial) and it's
+ // first come first served, e.g., command line switch has precedence.
+ if (forced_)
+ return;
+ // Explicit forcing should only be for cases where we want to set the group
+ // probabilities before the hard coded field trial setup is executed. So
+ // there must have been at least one non-default group appended at that point.
+ DCHECK_GT(next_group_number_, kDefaultGroupNumber + 1);
+
+ // And we must finalize the group choice before we mark ourselves as forced.
+ group();
+ forced_ = true;
+}
+
FieldTrial::~FieldTrial() {}
void FieldTrial::SetGroupChoice(const std::string& name, int number) {
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index 87683a1..4807187 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -152,6 +152,16 @@
// Enable benchmarking sets field trials to a common setting.
static void EnableBenchmarking();
+ // Set the field trial as forced, meaning that it was setup earlier than
+ // the hard coded registration of the field trial to override it.
+ // This allows the code that was hard coded to register the field trial to
+ // still succeed even though the field trial has already been registered.
+ // This must be called after appending all the groups, since we will make
+ // the group choice here. Note that this is a NOOP for already forced trials.
+ // And, as the rest of the FieldTrial code, this is not thread safe and must
+ // be done from the UI thread.
+ void SetForced();
+
private:
// Allow tests to access our innards for testing purposes.
FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration);
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc
index 51e9aaa..f5c03c4 100644
--- a/base/metrics/field_trial_unittest.cc
+++ b/base/metrics/field_trial_unittest.cc
@@ -522,4 +522,36 @@
EXPECT_NE(new_other_group, factory_trial->group());
}
+TEST_F(FieldTrialTest, SetForced) {
+ // Start by setting a trial for which we ensure a winner...
+ int default_group_number = -1;
+ FieldTrial* forced_trial = FieldTrialList::FactoryGetFieldTrial(
+ "Use the", 1, "default", next_year_, 12, 31, &default_group_number);
+ EXPECT_EQ(forced_trial, forced_trial);
+
+ int forced_group = forced_trial->AppendGroup("Force", 1);
+ EXPECT_EQ(forced_group, forced_trial->group());
+
+ // Now force it.
+ forced_trial->SetForced();
+
+ // Now try to set it up differently as a hard coded registration would.
+ FieldTrial* hard_coded_trial = FieldTrialList::FactoryGetFieldTrial(
+ "Use the", 1, "default", next_year_, 12, 31, &default_group_number);
+ EXPECT_EQ(hard_coded_trial, forced_trial);
+
+ int would_lose_group = hard_coded_trial->AppendGroup("Force", 0);
+ EXPECT_EQ(forced_group, hard_coded_trial->group());
+ EXPECT_EQ(forced_group, would_lose_group);
+
+ // Same thing if we would have done it to win again.
+ FieldTrial* other_hard_coded_trial = FieldTrialList::FactoryGetFieldTrial(
+ "Use the", 1, "default", next_year_, 12, 31, &default_group_number);
+ EXPECT_EQ(other_hard_coded_trial, forced_trial);
+
+ int would_win_group = other_hard_coded_trial->AppendGroup("Force", 1);
+ EXPECT_EQ(forced_group, other_hard_coded_trial->group());
+ EXPECT_EQ(forced_group, would_win_group);
+}
+
} // namespace base