summaryrefslogtreecommitdiffstats
path: root/base/metrics
diff options
context:
space:
mode:
authorjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-06 00:52:39 +0000
committerjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-06 00:52:39 +0000
commit5557b198f9815a758cf5a27d463e077b8bbbbfd8 (patch)
tree72d192231b743092b69ba1cbb5bb4501aa324e41 /base/metrics
parentdc86fccde35745d2b1501fcc08d9aa42ea1ee1cc (diff)
downloadchromium_src-5557b198f9815a758cf5a27d463e077b8bbbbfd8.zip
chromium_src-5557b198f9815a758cf5a27d463e077b8bbbbfd8.tar.gz
chromium_src-5557b198f9815a758cf5a27d463e077b8bbbbfd8.tar.bz2
Revert 84197 - Add one-time randomization support for FieldTrial, and the ability to
disable field trials. I am going to have a need for both soon. Cleaning up some comments about empty trial names, adding static method TrialExists() and simplifying many call sites by using this method. While I'm in there and needing base/OWNERS approval, add an OWNERS file for base/metrics that adds jar@chromium.org as an owner for that directory. BUG=none TEST=base_unittests TBR=jam@chromium.org R=jar@chromium.org,phajdan.jr@chromium.org,mark@chromium.org,wtc@chromium.org Reason for revert: See http://crbug.com/81750 BUG=81750 TBR=joi@chromium.org Review URL: http://codereview.chromium.org/6931048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84373 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/metrics')
-rw-r--r--base/metrics/OWNERS1
-rw-r--r--base/metrics/field_trial.cc98
-rw-r--r--base/metrics/field_trial.h115
-rw-r--r--base/metrics/field_trial_unittest.cc125
4 files changed, 50 insertions, 289 deletions
diff --git a/base/metrics/OWNERS b/base/metrics/OWNERS
deleted file mode 100644
index 844a032..0000000
--- a/base/metrics/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-jar@chromium.org
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index b86b9cc..03e5809 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -6,8 +6,6 @@
#include "base/logging.h"
#include "base/rand_util.h"
-#include "base/sha1.h"
-#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
@@ -43,13 +41,11 @@ FieldTrial::FieldTrial(const std::string& name,
: name_(name),
divisor_(total_probability),
default_group_name_(default_group_name),
- random_(static_cast<Probability>(divisor_ * RandDouble())),
+ random_(static_cast<Probability>(divisor_ * base::RandDouble())),
accumulated_group_probability_(0),
- next_group_number_(kDefaultGroupNumber + 1),
- group_(kNotFinalized),
- enable_field_trial_(true) {
+ next_group_number_(kDefaultGroupNumber+1),
+ group_(kNotFinalized) {
DCHECK_GT(total_probability, 0);
- DCHECK(!name_.empty());
DCHECK(!default_group_name_.empty());
FieldTrialList::Register(this);
@@ -59,7 +55,7 @@ FieldTrial::FieldTrial(const std::string& name,
DCHECK_GT(day_of_month, 0);
DCHECK_LT(day_of_month, 32);
- Time::Exploded exploded;
+ base::Time::Exploded exploded;
exploded.year = year;
exploded.month = month;
exploded.day_of_week = 0; // Should be unused.
@@ -69,33 +65,8 @@ FieldTrial::FieldTrial(const std::string& name,
exploded.second = 0;
exploded.millisecond = 0;
- Time expiration_time = Time::FromLocalExploded(exploded);
- if (GetBuildTime() > expiration_time)
- Disable();
-}
-
-void FieldTrial::UseOneTimeRandomization() {
- DCHECK_EQ(group_, kNotFinalized);
- DCHECK_EQ(kDefaultGroupNumber + 1, next_group_number_);
- if (!FieldTrialList::IsOneTimeRandomizationEnabled()) {
- NOTREACHED();
- Disable();
- return;
- }
-
- random_ = static_cast<Probability>(
- divisor_ * HashClientId(FieldTrialList::client_id(), name_));
-}
-
-void FieldTrial::Disable() {
- enable_field_trial_ = false;
-
- // In case we are disabled after initialization, we need to switch
- // the trial to the default group.
- if (group_ != kNotFinalized) {
- group_ = kDefaultGroupNumber;
- group_name_ = default_group_name_;
- }
+ base::Time expiration_time = Time::FromLocalExploded(exploded);
+ disable_field_trial_ = (GetBuildTime() > expiration_time) ? true : false;
}
int FieldTrial::AppendGroup(const std::string& name,
@@ -103,7 +74,7 @@ int FieldTrial::AppendGroup(const std::string& name,
DCHECK_LE(group_probability, divisor_);
DCHECK_GE(group_probability, 0);
- if (enable_benchmarking_ || !enable_field_trial_)
+ if (enable_benchmarking_ || disable_field_trial_)
group_probability = 0;
accumulated_group_probability_ += group_probability;
@@ -113,7 +84,7 @@ int FieldTrial::AppendGroup(const std::string& name,
// This is the group that crossed the random line, so we do the assignment.
group_ = next_group_number_;
if (name.empty())
- StringAppendF(&group_name_, "%d", group_);
+ base::StringAppendF(&group_name_, "%d", group_);
else
group_name_ = name;
FieldTrialList::NotifyFieldTrialGroupSelection(name_, group_name_);
@@ -132,8 +103,7 @@ int FieldTrial::group() {
}
std::string FieldTrial::group_name() {
- group(); // call group() to make sure group assignment was done.
- DCHECK(!group_name_.empty());
+ group(); // call group() to make group assignment was done.
return group_name_;
}
@@ -163,25 +133,6 @@ Time FieldTrial::GetBuildTime() {
return integral_build_time;
}
-// static
-double FieldTrial::HashClientId(const std::string& client_id,
- const std::string& trial_name) {
- // SHA-1 is designed to produce a uniformly random spread in its output space,
- // even for nearly-identical inputs, so it helps massage whatever client_id
- // and trial_name we get into something with a uniform distribution, which
- // is desirable so that we don't skew any part of the 0-100% spectrum.
- std::string input(client_id + trial_name);
- unsigned char sha1_hash[SHA1_LENGTH];
- SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()),
- input.size(),
- sha1_hash);
-
- COMPILE_ASSERT(sizeof(uint64) < sizeof(sha1_hash), need_more_data);
- uint64* bits = reinterpret_cast<uint64*>(&sha1_hash[0]);
-
- return BitsToOpenEndedUnitInterval(*bits);
-}
-
//------------------------------------------------------------------------------
// FieldTrialList methods and members.
@@ -191,9 +142,8 @@ FieldTrialList* FieldTrialList::global_ = NULL;
// static
bool FieldTrialList::register_without_global_ = false;
-FieldTrialList::FieldTrialList(const std::string& client_id)
+FieldTrialList::FieldTrialList()
: application_start_time_(TimeTicks::Now()),
- client_id_(client_id),
observer_list_(ObserverList<Observer>::NOTIFY_EXISTING_ONLY) {
DCHECK(!global_);
DCHECK(!register_without_global_);
@@ -254,23 +204,19 @@ std::string FieldTrialList::FindFullName(const std::string& name) {
}
// static
-bool FieldTrialList::TrialExists(const std::string& name) {
- return Find(name) != NULL;
-}
-
-// static
void FieldTrialList::StatesToString(std::string* output) {
if (!global_)
return;
DCHECK(output->empty());
AutoLock auto_lock(global_->lock_);
-
for (RegistrationList::iterator it = global_->registered_.begin();
it != global_->registered_.end(); ++it) {
const std::string name = it->first;
std::string group_name = it->second->group_name_internal();
if (group_name.empty())
- continue; // Should not include uninitialized trials.
+ // No definitive winner in this trial, use default_group_name as the
+ // group_name.
+ group_name = it->second->default_group_name();
DCHECK_EQ(name.find(kPersistentStringSeparator), std::string::npos);
DCHECK_EQ(group_name.find(kPersistentStringSeparator), std::string::npos);
output->append(name);
@@ -367,24 +313,6 @@ size_t FieldTrialList::GetFieldTrialCount() {
return global_->registered_.size();
}
-// static
-bool FieldTrialList::IsOneTimeRandomizationEnabled() {
- DCHECK(global_);
- if (!global_)
- return false;
-
- return !global_->client_id_.empty();
-}
-
-// static
-const std::string& FieldTrialList::client_id() {
- DCHECK(global_);
- if (!global_)
- return EmptyString();
-
- return global_->client_id_;
-}
-
FieldTrial* FieldTrialList::PreLockedFind(const std::string& name) {
RegistrationList::iterator it = registered_.find(name);
if (registered_.end() == it)
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index 4e89ccf..b8ab0c5 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -13,13 +13,12 @@
// pseudo-randomly selected).
//
// States are typically generated randomly, either based on a one time
-// randomization (which will yield the same results, in terms of selecting
-// the client for a field trial or not, for every run of the program on a
-// given machine), or by a startup randomization (generated each time the
-// application starts up, but held constant during the duration of the
-// process), or by continuous randomization across a run (where the state
-// can be recalculated again and again, many times during a process).
-// Continuous randomization is not yet implemented.
+// randomization (generated randomly once, and then persistently reused in the
+// client during each future run of the program), or by a startup randomization
+// (generated each time the application starts up, but held constant during the
+// duration of the process), or by continuous randomization across a run (where
+// the state can be recalculated again and again, many times during a process).
+// Only startup randomization is implemented thus far.
//------------------------------------------------------------------------------
// Example: Suppose we have an experiment involving memory, such as determining
@@ -53,9 +52,10 @@
// to randomly be assigned:
// HISTOGRAM_COUNTS("Memory.RendererTotal", count); // The original histogram.
-// static const bool memory_renderer_total_trial_exists =
-// FieldTrialList::TrialExists("Memory.RendererTotal");
-// if (memory_renderer_total_trial_exists) {
+// static bool use_memoryexperiment_histogram(
+// base::FieldTrialList::Find("MemoryExperiment") &&
+// !base::FieldTrialList::Find("MemoryExperiment")->group_name().empty());
+// if (use_memoryexperiment_histogram) {
// HISTOGRAM_COUNTS(FieldTrial::MakeName("Memory.RendererTotal",
// "MemoryExperiment"), count);
// }
@@ -103,35 +103,15 @@ class BASE_API FieldTrial : public RefCounted<FieldTrial> {
// The name is used to register the instance with the FieldTrialList class,
// and can be used to find the trial (only one trial can be present for each
- // name). |name| and |default_group_name| may not be empty.
- //
+ // name).
// Group probabilities that are later supplied must sum to less than or equal
// to the total_probability. Arguments year, month and day_of_month specify
// the expiration time. If the build time is after the expiration time then
// the field trial reverts to the 'default' group.
- //
- // Using this constructor creates a startup-randomized FieldTrial. If you
- // want a one-time randomized trial, call UseOneTimeRandomization() right
- // after construction.
FieldTrial(const std::string& name, Probability total_probability,
const std::string& default_group_name, const int year,
const int month, const int day_of_month);
- // Changes the field trial to use one-time randomization, i.e. produce the
- // same result for the current trial on every run of this client. Must be
- // called right after construction.
- //
- // Before using this method, |FieldTrialList::EnableOneTimeRandomization()|
- // must be called exactly once.
- void UseOneTimeRandomization();
-
- // Disables this trial, meaning it always determines the default group
- // has been selected. May be called immediately after construction, or
- // at any time after initialization (should not be interleaved with
- // AppendGroup calls). Once disabled, there is no way to re-enable a
- // trial.
- void Disable();
-
// Establish the name and probability of the next group in this trial.
// Sometimes, based on construction randomization, this call may cause the
// provided group to be *THE* group selected for use in this instance.
@@ -144,17 +124,18 @@ class BASE_API FieldTrial : public RefCounted<FieldTrial> {
// Return the randomly selected group number that was assigned.
// Return kDefaultGroupNumber if the instance is in the 'default' group.
// Note that this will force an instance to participate, and make it illegal
- // to attempt to probabilistically add any other groups to the trial.
+ // to attempt to probabalistically add any other groups to the trial.
int group();
- // If the group's name is empty, a string version containing the group
+ // If the field trial is not in an experiment, this returns the empty string.
+ // if the group's name is empty, a name of "_" concatenated with the group
// number is used as the group name.
std::string group_name();
// Return the default group name of the FieldTrial.
std::string default_group_name() const { return default_group_name_; }
- // Helper function for the most common use: as an argument to specify the
+ // Helper function for the most common use: as an argument to specifiy the
// name of a HISTOGRAM. Use the original histogram name as the name_prefix.
static std::string MakeName(const std::string& name_prefix,
const std::string& trial_name);
@@ -174,9 +155,6 @@ class BASE_API FieldTrial : public RefCounted<FieldTrial> {
FRIEND_TEST(FieldTrialTest, Save);
FRIEND_TEST(FieldTrialTest, DuplicateRestore);
FRIEND_TEST(FieldTrialTest, MakeName);
- FRIEND_TEST(FieldTrialTest, HashClientId);
- FRIEND_TEST(FieldTrialTest, HashClientIdIsUniform);
- FRIEND_TEST(FieldTrialTest, UseOneTimeRandomization);
friend class base::FieldTrialList;
@@ -190,13 +168,8 @@ class BASE_API FieldTrial : public RefCounted<FieldTrial> {
// Get build time.
static Time GetBuildTime();
- // Calculates a uniformly-distributed double between [0.0, 1.0) given
- // a |client_id| and a |trial_name| (the latter is used as salt to avoid
- // separate one-time randomized trials from all having the same results).
- static double HashClientId(const std::string& client_id,
- const std::string& trial_name);
-
// The name of the field trial, as can be found via the FieldTrialList.
+ // This is empty of the trial is not in the experiment.
const std::string name_;
// The maximum sum of all probabilities supplied, which corresponds to 100%.
@@ -209,7 +182,7 @@ class BASE_API FieldTrial : public RefCounted<FieldTrial> {
// The randomly selected probability that is used to select a group (or have
// the instance not participate). It is the product of divisor_ and a random
// number between [0, 1).
- Probability random_;
+ const Probability random_;
// Sum of the probabilities of all appended groups.
Probability accumulated_group_probability_;
@@ -220,13 +193,13 @@ class BASE_API FieldTrial : public RefCounted<FieldTrial> {
// This is kNotFinalized if no group has been assigned.
int group_;
- // A textual name for the randomly selected group. Valid after |group()|
- // has been called.
+ // A textual name for the randomly selected group. If this Trial is not a
+ // member of an group, this string is empty.
std::string group_name_;
- // When enable_field_trial_ is false, field trial reverts to the 'default'
+ // When disable_field_trial_ is true, field trial reverts to the 'default'
// group.
- bool enable_field_trial_;
+ bool disable_field_trial_;
// When benchmarking is enabled, field trials all revert to the 'default'
// group.
@@ -261,12 +234,7 @@ class BASE_API FieldTrialList {
};
// This singleton holds the global list of registered FieldTrials.
- //
- // |client_id| should be an opaque, diverse ID for this client that does not
- // change between sessions, to enable one-time randomized trials. The empty
- // string may be provided, in which case one-time randomized trials will
- // not be available.
- explicit FieldTrialList(const std::string& client_id);
+ FieldTrialList();
// Destructor Release()'s references to all registered FieldTrial instances.
~FieldTrialList();
@@ -278,22 +246,15 @@ class BASE_API FieldTrialList {
// registered, or to retrieve a pointer to it from the global map.
static FieldTrial* Find(const std::string& name);
- // Returns the group number chosen for the named trial, or
- // FieldTrial::kNotFinalized if the trial does not exist.
static int FindValue(const std::string& name);
- // Returns the group name chosen for the named trial, or the
- // empty string if the trial does not exist.
static std::string FindFullName(const std::string& name);
- // Returns true if the named trial has been registered.
- static bool TrialExists(const std::string& name);
-
- // Create a persistent representation of all FieldTrial instances and the
- // |client_id()| state for resurrection in another process. This allows
- // randomization to be done in one process, and secondary processes can by
- // synchronized on the result. The resulting string contains the
- // |client_id()|, the names, the trial name, and a "/" separator.
+ // Create a persistent representation of all FieldTrial instances for
+ // resurrection in another process. This allows randomization to be done in
+ // one process, and secondary processes can by synchronized on the result.
+ // The resulting string contains only the names, the trial name, and a "/"
+ // separator.
static void StatesToString(std::string* output);
// Use a previously generated state string (re: StatesToString()) augment the
@@ -302,9 +263,7 @@ class BASE_API FieldTrialList {
// is commonly used in a non-browser process, to carry randomly selected state
// in a browser process into this non-browser process. This method calls
// CreateFieldTrial to create the FieldTrial in the non-browser process.
- // Currently only the group_name_ and name_ are restored, as well as the
- // |client_id()| state, that could be used for one-time randomized trials
- // set up only in child processes.
+ // Currently only the group_name_ and name_ are restored.
static bool CreateTrialsInChildProcess(const std::string& prior_trials);
// Create a FieldTrial with the given |name| and using 100% probability for
@@ -344,17 +303,6 @@ class BASE_API FieldTrialList {
// Return the number of active field trials.
static size_t GetFieldTrialCount();
- // Returns true if you can call |FieldTrial::UseOneTimeRandomization()|
- // without error, i.e. if a non-empty string was provided as the client_id
- // when constructing the FieldTrialList singleton.
- static bool IsOneTimeRandomizationEnabled();
-
- // Returns an opaque, diverse ID for this client that does not change
- // between sessions.
- //
- // Returns the empty string if one-time randomization is not enabled.
- static const std::string& client_id();
-
private:
// A map from FieldTrial names to the actual instances.
typedef std::map<std::string, FieldTrial*> RegistrationList;
@@ -369,7 +317,7 @@ class BASE_API FieldTrialList {
// is created after that.
static bool register_without_global_;
- // A helper value made available to users, that shows when the FieldTrialList
+ // A helper value made availabel to users, that shows when the FieldTrialList
// was initialized. Note that this is a singleton instance, and hence is a
// good approximation to the start of the process.
TimeTicks application_start_time_;
@@ -378,10 +326,6 @@ class BASE_API FieldTrialList {
base::Lock lock_;
RegistrationList registered_;
- // An opaque, diverse ID for this client that does not change
- // between sessions, or the empty string if not initialized.
- std::string client_id_;
-
// List of observers to be notified when a group is selected for a FieldTrial.
ObserverList<Observer> observer_list_;
@@ -391,3 +335,4 @@ class BASE_API FieldTrialList {
} // namespace base
#endif // BASE_METRICS_FIELD_TRIAL_H_
+
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc
index a790add..3357085 100644
--- a/base/metrics/field_trial_unittest.cc
+++ b/base/metrics/field_trial_unittest.cc
@@ -6,18 +6,14 @@
#include "base/metrics/field_trial.h"
-#include "base/rand_util.h"
#include "base/stringprintf.h"
-#include "base/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include <limits>
-
namespace base {
class FieldTrialTest : public testing::Test {
public:
- FieldTrialTest() : trial_list_("client_id") {
+ FieldTrialTest() : trial_list_() {
Time now = Time::NowFromSystemTime();
TimeDelta oneYear = TimeDelta::FromDays(365);
Time::Exploded exploded;
@@ -228,10 +224,9 @@ TEST_F(FieldTrialTest, Save) {
new FieldTrial(
"Some name", 10, "Default some name", next_year_, 12, 31);
// There is no winner yet, so no textual group name is associated with trial.
- // In this case, the trial should not be included.
EXPECT_EQ("", trial->group_name_internal());
FieldTrialList::StatesToString(&save_string);
- EXPECT_EQ("", save_string);
+ EXPECT_EQ("Some name/Default some name/", save_string);
save_string.clear();
// Create a winning group.
@@ -270,10 +265,10 @@ TEST_F(FieldTrialTest, Restore) {
TEST_F(FieldTrialTest, BogusRestore) {
EXPECT_FALSE(FieldTrialList::CreateTrialsInChildProcess("MissingSlash"));
EXPECT_FALSE(FieldTrialList::CreateTrialsInChildProcess("MissingGroupName/"));
- EXPECT_FALSE(FieldTrialList::CreateTrialsInChildProcess(
- "MissingFinalSlash/gname"));
- EXPECT_FALSE(FieldTrialList::CreateTrialsInChildProcess(
- "noname, only group/"));
+ EXPECT_FALSE(
+ FieldTrialList::CreateTrialsInChildProcess("MissingFinalSlash/gname"));
+ EXPECT_FALSE(
+ FieldTrialList::CreateTrialsInChildProcess("/noname, only group/"));
}
TEST_F(FieldTrialTest, DuplicateRestore) {
@@ -289,8 +284,7 @@ TEST_F(FieldTrialTest, DuplicateRestore) {
EXPECT_TRUE(FieldTrialList::CreateTrialsInChildProcess(save_string));
// But it is an error to try to change to a different winner.
- EXPECT_FALSE(FieldTrialList::CreateTrialsInChildProcess(
- "Some name/Loser/"));
+ EXPECT_FALSE(FieldTrialList::CreateTrialsInChildProcess("Some name/Loser/"));
}
TEST_F(FieldTrialTest, CreateFieldTrial) {
@@ -327,109 +321,4 @@ TEST_F(FieldTrialTest, MakeName) {
FieldTrial::MakeName("Histogram", "Field Trial"));
}
-TEST_F(FieldTrialTest, HashClientId) {
- double results[] = {
- FieldTrial::HashClientId("hi", "1"),
- FieldTrial::HashClientId("there", "1"),
- };
- ASSERT_NE(results[0], results[1]);
- for (size_t i = 0; i < arraysize(results); ++i) {
- ASSERT_LE(0.0, results[i]);
- ASSERT_GT(1.0, results[i]);
- }
-
- ASSERT_EQ(FieldTrial::HashClientId("yo", "1"),
- FieldTrial::HashClientId("yo", "1"));
- ASSERT_NE(FieldTrial::HashClientId("yo", "something"),
- FieldTrial::HashClientId("yo", "else"));
-}
-
-TEST_F(FieldTrialTest, HashClientIdIsUniform) {
- // Choose a random start number but go sequentially from there, so
- // that each test tries a different range but we never provide uniformly
- // distributed input data.
- int current_number = RandInt(0, std::numeric_limits<int>::max());
-
- // The expected value of a random distribution is the average over all
- // samples as the number of samples approaches infinity. For a uniform
- // distribution from [0.0, 1.0) this would be 0.5.
- //
- // We do kSamplesBetweenChecks at a time and check if the value has converged
- // to a narrow interval around 0.5. A non-uniform distribution would likely
- // converge at something different, or not converge consistently within this
- // range (i.e. the test would start timing out occasionally).
- int kSamplesBetweenChecks = 300;
- int num_samples = 0;
- double total_value = 0.0;
- while (true) {
- for (int i = 0; i < kSamplesBetweenChecks; ++i) {
- total_value += FieldTrial::HashClientId(
- IntToString(current_number++), "salt");
- num_samples++;
- }
-
- double average = total_value / num_samples;
- double kExpectedMin = 0.48;
- double kExpectedMax = 0.52;
-
- if (num_samples > 1000 &&
- (average < kExpectedMin || average > kExpectedMax)) {
- // Only printed once we have enough samples that it's very unlikely
- // things haven't converged.
- printf("After %d samples, the average was %f, outside the expected\n"
- "range (%f, %f). We will add more samples and check after every\n"
- "%d samples. If the average does not converge, something\n"
- "is broken. If it does converge, the test will pass.\n",
- num_samples, average,
- kExpectedMin, kExpectedMax, kSamplesBetweenChecks);
- } else {
- // Success.
- break;
- }
- }
-}
-
-TEST_F(FieldTrialTest, UseOneTimeRandomization) {
- // Simply asserts that two trials using one-time randomization
- // that have different names, normally generate different results.
- //
- // Note that depending on the one-time random initialization, they
- // _might_ actually give the same result, but we know that given
- // the particular client_id we use for unit tests they won't.
- scoped_refptr<FieldTrial> trials[] = {
- new FieldTrial("one", 100, "default", next_year_, 1, 1),
- new FieldTrial("two", 100, "default", next_year_, 1, 1),
- };
-
- for (size_t i = 0; i < arraysize(trials); ++i) {
- trials[i]->UseOneTimeRandomization();
-
- for (int j = 0; j < 100; ++j) {
- trials[i]->AppendGroup("", 1);
- }
- }
-
- // The trials are most likely to give different results since they have
- // different names.
- ASSERT_NE(trials[0]->group(), trials[1]->group());
- ASSERT_NE(trials[0]->group_name(), trials[1]->group_name());
-}
-
-TEST_F(FieldTrialTest, DisableImmediately) {
- FieldTrial* trial =
- new FieldTrial("trial", 100, "default", next_year_, 12, 31);
- trial->Disable();
- ASSERT_EQ("default", trial->group_name());
- ASSERT_EQ(FieldTrial::kDefaultGroupNumber, trial->group());
-}
-
-TEST_F(FieldTrialTest, DisableAfterInitialization) {
- FieldTrial* trial =
- new FieldTrial("trial", 100, "default", next_year_, 12, 31);
- trial->AppendGroup("non_default", 100);
- ASSERT_EQ("non_default", trial->group_name());
- trial->Disable();
- ASSERT_EQ("default", trial->group_name());
-}
-
} // namespace base