Home | History | Annotate | Download | only in metrics
      1 // Copyright (c) 2012 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 "base/metrics/field_trial.h"
      6 
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/rand_util.h"
      9 #include "base/run_loop.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace base {
     15 
     16 namespace {
     17 
     18 // Default group name used by several tests.
     19 const char kDefaultGroupName[] = "DefaultGroup";
     20 
     21 // Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date.
     22 scoped_refptr<base::FieldTrial> CreateFieldTrial(
     23     const std::string& trial_name,
     24     int total_probability,
     25     const std::string& default_group_name,
     26     int* default_group_number) {
     27   return FieldTrialList::FactoryGetFieldTrial(
     28       trial_name, total_probability, default_group_name,
     29       base::FieldTrialList::kNoExpirationYear, 1, 1,
     30       base::FieldTrial::SESSION_RANDOMIZED, default_group_number);
     31 }
     32 
     33 int GetLastYear() {
     34   Time last_year_time = Time::NowFromSystemTime() - TimeDelta::FromDays(365);
     35   Time::Exploded exploded;
     36   last_year_time.LocalExplode(&exploded);
     37   return exploded.year;
     38 }
     39 
     40 // FieldTrialList::Observer implementation for testing.
     41 class TestFieldTrialObserver : public FieldTrialList::Observer {
     42  public:
     43   TestFieldTrialObserver() {
     44     FieldTrialList::AddObserver(this);
     45   }
     46 
     47   virtual ~TestFieldTrialObserver() {
     48     FieldTrialList::RemoveObserver(this);
     49   }
     50 
     51   virtual void OnFieldTrialGroupFinalized(const std::string& trial,
     52                                           const std::string& group) OVERRIDE {
     53     trial_name_ = trial;
     54     group_name_ = group;
     55   }
     56 
     57   const std::string& trial_name() const { return trial_name_; }
     58   const std::string& group_name() const { return group_name_; }
     59 
     60  private:
     61   std::string trial_name_;
     62   std::string group_name_;
     63 
     64   DISALLOW_COPY_AND_ASSIGN(TestFieldTrialObserver);
     65 };
     66 
     67 }  // namespace
     68 
     69 class FieldTrialTest : public testing::Test {
     70  public:
     71   FieldTrialTest() : trial_list_(NULL) {}
     72 
     73  private:
     74   MessageLoop message_loop_;
     75   FieldTrialList trial_list_;
     76 };
     77 
     78 // Test registration, and also check that destructors are called for trials
     79 // (and that Valgrind doesn't catch us leaking).
     80 TEST_F(FieldTrialTest, Registration) {
     81   const char* name1 = "name 1 test";
     82   const char* name2 = "name 2 test";
     83   EXPECT_FALSE(FieldTrialList::Find(name1));
     84   EXPECT_FALSE(FieldTrialList::Find(name2));
     85 
     86   scoped_refptr<FieldTrial> trial1 =
     87       CreateFieldTrial(name1, 10, "default name 1 test", NULL);
     88   EXPECT_EQ(FieldTrial::kNotFinalized, trial1->group_);
     89   EXPECT_EQ(name1, trial1->trial_name());
     90   EXPECT_EQ("", trial1->group_name_internal());
     91 
     92   trial1->AppendGroup(std::string(), 7);
     93 
     94   EXPECT_EQ(trial1.get(), FieldTrialList::Find(name1));
     95   EXPECT_FALSE(FieldTrialList::Find(name2));
     96 
     97   scoped_refptr<FieldTrial> trial2 =
     98       CreateFieldTrial(name2, 10, "default name 2 test", NULL);
     99   EXPECT_EQ(FieldTrial::kNotFinalized, trial2->group_);
    100   EXPECT_EQ(name2, trial2->trial_name());
    101   EXPECT_EQ("", trial2->group_name_internal());
    102 
    103   trial2->AppendGroup("a first group", 7);
    104 
    105   EXPECT_EQ(trial1.get(), FieldTrialList::Find(name1));
    106   EXPECT_EQ(trial2.get(), FieldTrialList::Find(name2));
    107   // Note: FieldTrialList should delete the objects at shutdown.
    108 }
    109 
    110 TEST_F(FieldTrialTest, AbsoluteProbabilities) {
    111   char always_true[] = " always true";
    112   char default_always_true[] = " default always true";
    113   char always_false[] = " always false";
    114   char default_always_false[] = " default always false";
    115   for (int i = 1; i < 250; ++i) {
    116     // Try lots of names, by changing the first character of the name.
    117     always_true[0] = i;
    118     default_always_true[0] = i;
    119     always_false[0] = i;
    120     default_always_false[0] = i;
    121 
    122     scoped_refptr<FieldTrial> trial_true =
    123         CreateFieldTrial(always_true, 10, default_always_true, NULL);
    124     const std::string winner = "TheWinner";
    125     int winner_group = trial_true->AppendGroup(winner, 10);
    126 
    127     EXPECT_EQ(winner_group, trial_true->group());
    128     EXPECT_EQ(winner, trial_true->group_name());
    129 
    130     scoped_refptr<FieldTrial> trial_false =
    131         CreateFieldTrial(always_false, 10, default_always_false, NULL);
    132     int loser_group = trial_false->AppendGroup("ALoser", 0);
    133 
    134     EXPECT_NE(loser_group, trial_false->group());
    135   }
    136 }
    137 
    138 TEST_F(FieldTrialTest, RemainingProbability) {
    139   // First create a test that hasn't had a winner yet.
    140   const std::string winner = "Winner";
    141   const std::string loser = "Loser";
    142   scoped_refptr<FieldTrial> trial;
    143   int counter = 0;
    144   int default_group_number = -1;
    145   do {
    146     std::string name = StringPrintf("trial%d", ++counter);
    147     trial = CreateFieldTrial(name, 10, winner, &default_group_number);
    148     trial->AppendGroup(loser, 5);  // 50% chance of not being chosen.
    149     // If a group is not assigned, group_ will be kNotFinalized.
    150   } while (trial->group_ != FieldTrial::kNotFinalized);
    151 
    152   // And that 'default' group (winner) should always win.
    153   EXPECT_EQ(default_group_number, trial->group());
    154 
    155   // And that winner should ALWAYS win.
    156   EXPECT_EQ(winner, trial->group_name());
    157 }
    158 
    159 TEST_F(FieldTrialTest, FiftyFiftyProbability) {
    160   // Check that even with small divisors, we have the proper probabilities, and
    161   // all outcomes are possible.  Since this is a 50-50 test, it should get both
    162   // outcomes in a few tries, but we'll try no more than 100 times (and be flaky
    163   // with probability around 1 in 2^99).
    164   bool first_winner = false;
    165   bool second_winner = false;
    166   int counter = 0;
    167   do {
    168     std::string name = base::StringPrintf("FiftyFifty%d", ++counter);
    169     std::string default_group_name = base::StringPrintf("Default FiftyFifty%d",
    170                                                         ++counter);
    171     scoped_refptr<FieldTrial> trial =
    172         CreateFieldTrial(name, 2, default_group_name, NULL);
    173     trial->AppendGroup("first", 1);  // 50% chance of being chosen.
    174     // If group_ is kNotFinalized, then a group assignement hasn't been done.
    175     if (trial->group_ != FieldTrial::kNotFinalized) {
    176       first_winner = true;
    177       continue;
    178     }
    179     trial->AppendGroup("second", 1);  // Always chosen at this point.
    180     EXPECT_NE(FieldTrial::kNotFinalized, trial->group());
    181     second_winner = true;
    182   } while ((!second_winner || !first_winner) && counter < 100);
    183   EXPECT_TRUE(second_winner);
    184   EXPECT_TRUE(first_winner);
    185 }
    186 
    187 TEST_F(FieldTrialTest, MiddleProbabilities) {
    188   char name[] = " same name";
    189   char default_group_name[] = " default same name";
    190   bool false_event_seen = false;
    191   bool true_event_seen = false;
    192   for (int i = 1; i < 250; ++i) {
    193     name[0] = i;
    194     default_group_name[0] = i;
    195     scoped_refptr<FieldTrial> trial =
    196         CreateFieldTrial(name, 10, default_group_name, NULL);
    197     int might_win = trial->AppendGroup("MightWin", 5);
    198 
    199     if (trial->group() == might_win) {
    200       true_event_seen = true;
    201     } else {
    202       false_event_seen = true;
    203     }
    204     if (false_event_seen && true_event_seen)
    205       return;  // Successful test!!!
    206   }
    207   // Very surprising to get here. Probability should be around 1 in 2 ** 250.
    208   // One of the following will fail.
    209   EXPECT_TRUE(false_event_seen);
    210   EXPECT_TRUE(true_event_seen);
    211 }
    212 
    213 TEST_F(FieldTrialTest, OneWinner) {
    214   char name[] = "Some name";
    215   char default_group_name[] = "Default some name";
    216   int group_count(10);
    217 
    218   int default_group_number = -1;
    219   scoped_refptr<FieldTrial> trial =
    220       CreateFieldTrial(name, group_count, default_group_name, NULL);
    221   int winner_index(-2);
    222   std::string winner_name;
    223 
    224   for (int i = 1; i <= group_count; ++i) {
    225     int might_win = trial->AppendGroup(std::string(), 1);
    226 
    227     // Because we keep appending groups, we want to see if the last group that
    228     // was added has been assigned or not.
    229     if (trial->group_ == might_win) {
    230       EXPECT_EQ(-2, winner_index);
    231       winner_index = might_win;
    232       StringAppendF(&winner_name, "%d", might_win);
    233       EXPECT_EQ(winner_name, trial->group_name());
    234     }
    235   }
    236   EXPECT_GE(winner_index, 0);
    237   // Since all groups cover the total probability, we should not have
    238   // chosen the default group.
    239   EXPECT_NE(trial->group(), default_group_number);
    240   EXPECT_EQ(trial->group(), winner_index);
    241   EXPECT_EQ(trial->group_name(), winner_name);
    242 }
    243 
    244 TEST_F(FieldTrialTest, DisableProbability) {
    245   const std::string default_group_name = "Default group";
    246   const std::string loser = "Loser";
    247   const std::string name = "Trial";
    248 
    249   // Create a field trail that has expired.
    250   int default_group_number = -1;
    251   FieldTrial* trial = FieldTrialList::FactoryGetFieldTrial(
    252       name, 1000000000, default_group_name, GetLastYear(), 1, 1,
    253       FieldTrial::SESSION_RANDOMIZED,
    254       &default_group_number);
    255   trial->AppendGroup(loser, 999999999);  // 99.9999999% chance of being chosen.
    256 
    257   // Because trial has expired, we should always be in the default group.
    258   EXPECT_EQ(default_group_number, trial->group());
    259 
    260   // And that default_group_name should ALWAYS win.
    261   EXPECT_EQ(default_group_name, trial->group_name());
    262 }
    263 
    264 TEST_F(FieldTrialTest, ActiveGroups) {
    265   std::string no_group("No Group");
    266   scoped_refptr<FieldTrial> trial =
    267       CreateFieldTrial(no_group, 10, "Default", NULL);
    268 
    269   // There is no winner yet, so no NameGroupId should be returned.
    270   FieldTrial::ActiveGroup active_group;
    271   EXPECT_FALSE(trial->GetActiveGroup(&active_group));
    272 
    273   // Create a single winning group.
    274   std::string one_winner("One Winner");
    275   trial = CreateFieldTrial(one_winner, 10, "Default", NULL);
    276   std::string winner("Winner");
    277   trial->AppendGroup(winner, 10);
    278   EXPECT_FALSE(trial->GetActiveGroup(&active_group));
    279   // Finalize the group selection by accessing the selected group.
    280   trial->group();
    281   EXPECT_TRUE(trial->GetActiveGroup(&active_group));
    282   EXPECT_EQ(one_winner, active_group.trial_name);
    283   EXPECT_EQ(winner, active_group.group_name);
    284 
    285   std::string multi_group("MultiGroup");
    286   scoped_refptr<FieldTrial> multi_group_trial =
    287       CreateFieldTrial(multi_group, 9, "Default", NULL);
    288 
    289   multi_group_trial->AppendGroup("Me", 3);
    290   multi_group_trial->AppendGroup("You", 3);
    291   multi_group_trial->AppendGroup("Them", 3);
    292   EXPECT_FALSE(multi_group_trial->GetActiveGroup(&active_group));
    293   // Finalize the group selection by accessing the selected group.
    294   multi_group_trial->group();
    295   EXPECT_TRUE(multi_group_trial->GetActiveGroup(&active_group));
    296   EXPECT_EQ(multi_group, active_group.trial_name);
    297   EXPECT_EQ(multi_group_trial->group_name(), active_group.group_name);
    298 
    299   // Now check if the list is built properly...
    300   FieldTrial::ActiveGroups active_groups;
    301   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    302   EXPECT_EQ(2U, active_groups.size());
    303   for (size_t i = 0; i < active_groups.size(); ++i) {
    304     // Order is not guaranteed, so check all values.
    305     EXPECT_NE(no_group, active_groups[i].trial_name);
    306     EXPECT_TRUE(one_winner != active_groups[i].trial_name ||
    307                 winner == active_groups[i].group_name);
    308     EXPECT_TRUE(multi_group != active_groups[i].trial_name ||
    309                 multi_group_trial->group_name() == active_groups[i].group_name);
    310   }
    311 }
    312 
    313 TEST_F(FieldTrialTest, ActiveGroupsNotFinalized) {
    314   const char kTrialName[] = "TestTrial";
    315   const char kSecondaryGroupName[] = "SecondaryGroup";
    316 
    317   int default_group = -1;
    318   scoped_refptr<FieldTrial> trial =
    319       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    320   const int secondary_group = trial->AppendGroup(kSecondaryGroupName, 50);
    321 
    322   // Before |group()| is called, |GetActiveGroup()| should return false.
    323   FieldTrial::ActiveGroup active_group;
    324   EXPECT_FALSE(trial->GetActiveGroup(&active_group));
    325 
    326   // |GetActiveFieldTrialGroups()| should also not include the trial.
    327   FieldTrial::ActiveGroups active_groups;
    328   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    329   EXPECT_TRUE(active_groups.empty());
    330 
    331   // After |group()| has been called, both APIs should succeed.
    332   const int chosen_group = trial->group();
    333   EXPECT_TRUE(chosen_group == default_group || chosen_group == secondary_group);
    334 
    335   EXPECT_TRUE(trial->GetActiveGroup(&active_group));
    336   EXPECT_EQ(kTrialName, active_group.trial_name);
    337   if (chosen_group == default_group)
    338     EXPECT_EQ(kDefaultGroupName, active_group.group_name);
    339   else
    340     EXPECT_EQ(kSecondaryGroupName, active_group.group_name);
    341 
    342   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    343   ASSERT_EQ(1U, active_groups.size());
    344   EXPECT_EQ(kTrialName, active_groups[0].trial_name);
    345   EXPECT_EQ(active_group.group_name, active_groups[0].group_name);
    346 }
    347 
    348 TEST_F(FieldTrialTest, Save) {
    349   std::string save_string;
    350 
    351   scoped_refptr<FieldTrial> trial =
    352       CreateFieldTrial("Some name", 10, "Default some name", NULL);
    353   // There is no winner yet, so no textual group name is associated with trial.
    354   // In this case, the trial should not be included.
    355   EXPECT_EQ("", trial->group_name_internal());
    356   FieldTrialList::StatesToString(&save_string);
    357   EXPECT_EQ("", save_string);
    358   save_string.clear();
    359 
    360   // Create a winning group.
    361   trial->AppendGroup("Winner", 10);
    362   // Finalize the group selection by accessing the selected group.
    363   trial->group();
    364   FieldTrialList::StatesToString(&save_string);
    365   EXPECT_EQ("Some name/Winner/", save_string);
    366   save_string.clear();
    367 
    368   // Create a second trial and winning group.
    369   scoped_refptr<FieldTrial> trial2 =
    370       CreateFieldTrial("xxx", 10, "Default xxx", NULL);
    371   trial2->AppendGroup("yyyy", 10);
    372   // Finalize the group selection by accessing the selected group.
    373   trial2->group();
    374 
    375   FieldTrialList::StatesToString(&save_string);
    376   // We assume names are alphabetized... though this is not critical.
    377   EXPECT_EQ("Some name/Winner/xxx/yyyy/", save_string);
    378   save_string.clear();
    379 
    380   // Create a third trial with only the default group.
    381   scoped_refptr<FieldTrial> trial3 =
    382       CreateFieldTrial("zzz", 10, "default", NULL);
    383   // Finalize the group selection by accessing the selected group.
    384   trial3->group();
    385 
    386   FieldTrialList::StatesToString(&save_string);
    387   EXPECT_EQ("Some name/Winner/xxx/yyyy/zzz/default/", save_string);
    388 }
    389 
    390 TEST_F(FieldTrialTest, Restore) {
    391   ASSERT_FALSE(FieldTrialList::TrialExists("Some_name"));
    392   ASSERT_FALSE(FieldTrialList::TrialExists("xxx"));
    393 
    394   FieldTrialList::CreateTrialsFromString("Some_name/Winner/xxx/yyyy/",
    395                                          FieldTrialList::DONT_ACTIVATE_TRIALS,
    396                                          std::set<std::string>());
    397 
    398   FieldTrial* trial = FieldTrialList::Find("Some_name");
    399   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    400   EXPECT_EQ("Winner", trial->group_name());
    401   EXPECT_EQ("Some_name", trial->trial_name());
    402 
    403   trial = FieldTrialList::Find("xxx");
    404   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    405   EXPECT_EQ("yyyy", trial->group_name());
    406   EXPECT_EQ("xxx", trial->trial_name());
    407 }
    408 
    409 TEST_F(FieldTrialTest, RestoreNotEndingWithSlash) {
    410   EXPECT_TRUE(FieldTrialList::CreateTrialsFromString(
    411       "tname/gname", FieldTrialList::DONT_ACTIVATE_TRIALS,
    412       std::set<std::string>()));
    413 
    414   FieldTrial* trial = FieldTrialList::Find("tname");
    415   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    416   EXPECT_EQ("gname", trial->group_name());
    417   EXPECT_EQ("tname", trial->trial_name());
    418 }
    419 
    420 TEST_F(FieldTrialTest, BogusRestore) {
    421   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString(
    422       "MissingSlash", FieldTrialList::DONT_ACTIVATE_TRIALS,
    423       std::set<std::string>()));
    424   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString(
    425       "MissingGroupName/", FieldTrialList::DONT_ACTIVATE_TRIALS,
    426       std::set<std::string>()));
    427   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString(
    428       "noname, only group/", FieldTrialList::DONT_ACTIVATE_TRIALS,
    429       std::set<std::string>()));
    430 }
    431 
    432 TEST_F(FieldTrialTest, DuplicateRestore) {
    433   scoped_refptr<FieldTrial> trial =
    434       CreateFieldTrial("Some name", 10, "Default", NULL);
    435   trial->AppendGroup("Winner", 10);
    436   // Finalize the group selection by accessing the selected group.
    437   trial->group();
    438   std::string save_string;
    439   FieldTrialList::StatesToString(&save_string);
    440   EXPECT_EQ("Some name/Winner/", save_string);
    441 
    442   // It is OK if we redundantly specify a winner.
    443   EXPECT_TRUE(FieldTrialList::CreateTrialsFromString(
    444       save_string, FieldTrialList::DONT_ACTIVATE_TRIALS,
    445       std::set<std::string>()));
    446 
    447   // But it is an error to try to change to a different winner.
    448   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString(
    449       "Some name/Loser/", FieldTrialList::DONT_ACTIVATE_TRIALS,
    450       std::set<std::string>()));
    451 }
    452 
    453 TEST_F(FieldTrialTest, CreateTrialsFromStringActive) {
    454   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    455   ASSERT_FALSE(FieldTrialList::TrialExists("Xyz"));
    456   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString(
    457       "Abc/def/Xyz/zyx/", FieldTrialList::ACTIVATE_TRIALS,
    458       std::set<std::string>()));
    459 
    460   FieldTrial::ActiveGroups active_groups;
    461   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    462   ASSERT_EQ(2U, active_groups.size());
    463   EXPECT_EQ("Abc", active_groups[0].trial_name);
    464   EXPECT_EQ("def", active_groups[0].group_name);
    465   EXPECT_EQ("Xyz", active_groups[1].trial_name);
    466   EXPECT_EQ("zyx", active_groups[1].group_name);
    467 }
    468 
    469 TEST_F(FieldTrialTest, CreateTrialsFromStringNotActive) {
    470   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    471   ASSERT_FALSE(FieldTrialList::TrialExists("Xyz"));
    472   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString(
    473       "Abc/def/Xyz/zyx/", FieldTrialList::DONT_ACTIVATE_TRIALS,
    474       std::set<std::string>()));
    475 
    476   FieldTrial::ActiveGroups active_groups;
    477   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    478   ASSERT_TRUE(active_groups.empty());
    479 
    480   // Check that the values still get returned and querying them activates them.
    481   EXPECT_EQ("def", FieldTrialList::FindFullName("Abc"));
    482   EXPECT_EQ("zyx", FieldTrialList::FindFullName("Xyz"));
    483 
    484   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    485   ASSERT_EQ(2U, active_groups.size());
    486   EXPECT_EQ("Abc", active_groups[0].trial_name);
    487   EXPECT_EQ("def", active_groups[0].group_name);
    488   EXPECT_EQ("Xyz", active_groups[1].trial_name);
    489   EXPECT_EQ("zyx", active_groups[1].group_name);
    490 }
    491 
    492 TEST_F(FieldTrialTest, CreateTrialsFromStringActiveObserver) {
    493   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    494 
    495   TestFieldTrialObserver observer;
    496   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString(
    497       "Abc/def/", FieldTrialList::ACTIVATE_TRIALS, std::set<std::string>()));
    498 
    499   RunLoop().RunUntilIdle();
    500   EXPECT_EQ("Abc", observer.trial_name());
    501   EXPECT_EQ("def", observer.group_name());
    502 }
    503 
    504 TEST_F(FieldTrialTest, CreateTrialsFromStringNotActiveObserver) {
    505   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    506 
    507   TestFieldTrialObserver observer;
    508   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString(
    509       "Abc/def/", FieldTrialList::DONT_ACTIVATE_TRIALS,
    510       std::set<std::string>()));
    511   RunLoop().RunUntilIdle();
    512   // Observer shouldn't be notified.
    513   EXPECT_TRUE(observer.trial_name().empty());
    514 
    515   // Check that the values still get returned and querying them activates them.
    516   EXPECT_EQ("def", FieldTrialList::FindFullName("Abc"));
    517 
    518   RunLoop().RunUntilIdle();
    519   EXPECT_EQ("Abc", observer.trial_name());
    520   EXPECT_EQ("def", observer.group_name());
    521 }
    522 
    523 TEST_F(FieldTrialTest, CreateTrialsFromStringWithIgnoredFieldTrials) {
    524   ASSERT_FALSE(FieldTrialList::TrialExists("Unaccepted1"));
    525   ASSERT_FALSE(FieldTrialList::TrialExists("Foo"));
    526   ASSERT_FALSE(FieldTrialList::TrialExists("Unaccepted2"));
    527   ASSERT_FALSE(FieldTrialList::TrialExists("Bar"));
    528   ASSERT_FALSE(FieldTrialList::TrialExists("Unaccepted3"));
    529 
    530   std::set<std::string> ignored_trial_names;
    531   ignored_trial_names.insert("Unaccepted1");
    532   ignored_trial_names.insert("Unaccepted2");
    533   ignored_trial_names.insert("Unaccepted3");
    534 
    535   FieldTrialList::CreateTrialsFromString(
    536       "Unaccepted1/Unaccepted1_name/"
    537       "Foo/Foo_name/"
    538       "Unaccepted2/Unaccepted2_name/"
    539       "Bar/Bar_name/"
    540       "Unaccepted3/Unaccepted3_name/",
    541       FieldTrialList::DONT_ACTIVATE_TRIALS,
    542       ignored_trial_names);
    543 
    544   EXPECT_FALSE(FieldTrialList::TrialExists("Unaccepted1"));
    545   EXPECT_TRUE(FieldTrialList::TrialExists("Foo"));
    546   EXPECT_FALSE(FieldTrialList::TrialExists("Unaccepted2"));
    547   EXPECT_TRUE(FieldTrialList::TrialExists("Bar"));
    548   EXPECT_FALSE(FieldTrialList::TrialExists("Unaccepted3"));
    549 
    550   FieldTrial::ActiveGroups active_groups;
    551   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    552   EXPECT_TRUE(active_groups.empty());
    553 
    554   FieldTrial* trial = FieldTrialList::Find("Foo");
    555   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    556   EXPECT_EQ("Foo", trial->trial_name());
    557   EXPECT_EQ("Foo_name", trial->group_name());
    558 
    559   trial = FieldTrialList::Find("Bar");
    560   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    561   EXPECT_EQ("Bar", trial->trial_name());
    562   EXPECT_EQ("Bar_name", trial->group_name());
    563 }
    564 
    565 TEST_F(FieldTrialTest, CreateFieldTrial) {
    566   ASSERT_FALSE(FieldTrialList::TrialExists("Some_name"));
    567 
    568   FieldTrialList::CreateFieldTrial("Some_name", "Winner");
    569 
    570   FieldTrial* trial = FieldTrialList::Find("Some_name");
    571   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    572   EXPECT_EQ("Winner", trial->group_name());
    573   EXPECT_EQ("Some_name", trial->trial_name());
    574 }
    575 
    576 TEST_F(FieldTrialTest, CreateFieldTrialIsNotActive) {
    577   const char kTrialName[] = "CreateFieldTrialIsActiveTrial";
    578   const char kWinnerGroup[] = "Winner";
    579   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    580   FieldTrialList::CreateFieldTrial(kTrialName, kWinnerGroup);
    581 
    582   FieldTrial::ActiveGroups active_groups;
    583   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    584   EXPECT_TRUE(active_groups.empty());
    585 }
    586 
    587 TEST_F(FieldTrialTest, DuplicateFieldTrial) {
    588   scoped_refptr<FieldTrial> trial =
    589       CreateFieldTrial("Some_name", 10, "Default", NULL);
    590   trial->AppendGroup("Winner", 10);
    591 
    592   // It is OK if we redundantly specify a winner.
    593   FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("Some_name", "Winner");
    594   EXPECT_TRUE(trial1 != NULL);
    595 
    596   // But it is an error to try to change to a different winner.
    597   FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("Some_name", "Loser");
    598   EXPECT_TRUE(trial2 == NULL);
    599 }
    600 
    601 TEST_F(FieldTrialTest, DisableImmediately) {
    602   int default_group_number = -1;
    603   scoped_refptr<FieldTrial> trial =
    604       CreateFieldTrial("trial", 100, "default", &default_group_number);
    605   trial->Disable();
    606   ASSERT_EQ("default", trial->group_name());
    607   ASSERT_EQ(default_group_number, trial->group());
    608 }
    609 
    610 TEST_F(FieldTrialTest, DisableAfterInitialization) {
    611   scoped_refptr<FieldTrial> trial =
    612       CreateFieldTrial("trial", 100, "default", NULL);
    613   trial->AppendGroup("non_default", 100);
    614   trial->Disable();
    615   ASSERT_EQ("default", trial->group_name());
    616 }
    617 
    618 TEST_F(FieldTrialTest, ForcedFieldTrials) {
    619   // Validate we keep the forced choice.
    620   FieldTrial* forced_trial = FieldTrialList::CreateFieldTrial("Use the",
    621                                                               "Force");
    622   EXPECT_STREQ("Force", forced_trial->group_name().c_str());
    623 
    624   int default_group_number = -1;
    625   scoped_refptr<FieldTrial> factory_trial =
    626       CreateFieldTrial("Use the", 1000, "default", &default_group_number);
    627   EXPECT_EQ(factory_trial.get(), forced_trial);
    628 
    629   int chosen_group = factory_trial->AppendGroup("Force", 100);
    630   EXPECT_EQ(chosen_group, factory_trial->group());
    631   int not_chosen_group = factory_trial->AppendGroup("Dark Side", 100);
    632   EXPECT_NE(chosen_group, not_chosen_group);
    633 
    634   // Since we didn't force the default group, we should not be returned the
    635   // chosen group as the default group.
    636   EXPECT_NE(default_group_number, chosen_group);
    637   int new_group = factory_trial->AppendGroup("Duck Tape", 800);
    638   EXPECT_NE(chosen_group, new_group);
    639   // The new group should not be the default group either.
    640   EXPECT_NE(default_group_number, new_group);
    641 }
    642 
    643 TEST_F(FieldTrialTest, ForcedFieldTrialsDefaultGroup) {
    644   // Forcing the default should use the proper group ID.
    645   FieldTrial* forced_trial = FieldTrialList::CreateFieldTrial("Trial Name",
    646                                                               "Default");
    647   int default_group_number = -1;
    648   scoped_refptr<FieldTrial> factory_trial =
    649       CreateFieldTrial("Trial Name", 1000, "Default", &default_group_number);
    650   EXPECT_EQ(forced_trial, factory_trial.get());
    651 
    652   int other_group = factory_trial->AppendGroup("Not Default", 100);
    653   EXPECT_STREQ("Default", factory_trial->group_name().c_str());
    654   EXPECT_EQ(default_group_number, factory_trial->group());
    655   EXPECT_NE(other_group, factory_trial->group());
    656 
    657   int new_other_group = factory_trial->AppendGroup("Not Default Either", 800);
    658   EXPECT_NE(new_other_group, factory_trial->group());
    659 }
    660 
    661 TEST_F(FieldTrialTest, SetForced) {
    662   // Start by setting a trial for which we ensure a winner...
    663   int default_group_number = -1;
    664   scoped_refptr<FieldTrial> forced_trial =
    665       CreateFieldTrial("Use the", 1, "default", &default_group_number);
    666   EXPECT_EQ(forced_trial, forced_trial);
    667 
    668   int forced_group = forced_trial->AppendGroup("Force", 1);
    669   EXPECT_EQ(forced_group, forced_trial->group());
    670 
    671   // Now force it.
    672   forced_trial->SetForced();
    673 
    674   // Now try to set it up differently as a hard coded registration would.
    675   scoped_refptr<FieldTrial> hard_coded_trial =
    676       CreateFieldTrial("Use the", 1, "default", &default_group_number);
    677   EXPECT_EQ(hard_coded_trial, forced_trial);
    678 
    679   int would_lose_group = hard_coded_trial->AppendGroup("Force", 0);
    680   EXPECT_EQ(forced_group, hard_coded_trial->group());
    681   EXPECT_EQ(forced_group, would_lose_group);
    682 
    683   // Same thing if we would have done it to win again.
    684   scoped_refptr<FieldTrial> other_hard_coded_trial =
    685       CreateFieldTrial("Use the", 1, "default", &default_group_number);
    686   EXPECT_EQ(other_hard_coded_trial, forced_trial);
    687 
    688   int would_win_group = other_hard_coded_trial->AppendGroup("Force", 1);
    689   EXPECT_EQ(forced_group, other_hard_coded_trial->group());
    690   EXPECT_EQ(forced_group, would_win_group);
    691 }
    692 
    693 TEST_F(FieldTrialTest, SetForcedDefaultOnly) {
    694   const char kTrialName[] = "SetForcedDefaultOnly";
    695   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    696 
    697   int default_group = -1;
    698   scoped_refptr<FieldTrial> trial =
    699       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    700   trial->SetForced();
    701 
    702   trial = CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    703   EXPECT_EQ(default_group, trial->group());
    704   EXPECT_EQ(kDefaultGroupName, trial->group_name());
    705 }
    706 
    707 TEST_F(FieldTrialTest, SetForcedDefaultWithExtraGroup) {
    708   const char kTrialName[] = "SetForcedDefaultWithExtraGroup";
    709   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    710 
    711   int default_group = -1;
    712   scoped_refptr<FieldTrial> trial =
    713       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    714   trial->SetForced();
    715 
    716   trial = CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    717   const int extra_group = trial->AppendGroup("Extra", 100);
    718   EXPECT_EQ(default_group, trial->group());
    719   EXPECT_NE(extra_group, trial->group());
    720   EXPECT_EQ(kDefaultGroupName, trial->group_name());
    721 }
    722 
    723 TEST_F(FieldTrialTest, SetForcedTurnFeatureOn) {
    724   const char kTrialName[] = "SetForcedTurnFeatureOn";
    725   const char kExtraGroupName[] = "Extra";
    726   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    727 
    728   // Simulate a server-side (forced) config that turns the feature on when the
    729   // original hard-coded config had it disabled.
    730   scoped_refptr<FieldTrial> forced_trial =
    731       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    732   forced_trial->AppendGroup(kExtraGroupName, 100);
    733   forced_trial->SetForced();
    734 
    735   int default_group = -1;
    736   scoped_refptr<FieldTrial> client_trial =
    737       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    738   const int extra_group = client_trial->AppendGroup(kExtraGroupName, 0);
    739   EXPECT_NE(default_group, extra_group);
    740 
    741   EXPECT_FALSE(client_trial->group_reported_);
    742   EXPECT_EQ(extra_group, client_trial->group());
    743   EXPECT_TRUE(client_trial->group_reported_);
    744   EXPECT_EQ(kExtraGroupName, client_trial->group_name());
    745 }
    746 
    747 TEST_F(FieldTrialTest, SetForcedTurnFeatureOff) {
    748   const char kTrialName[] = "SetForcedTurnFeatureOff";
    749   const char kExtraGroupName[] = "Extra";
    750   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    751 
    752   // Simulate a server-side (forced) config that turns the feature off when the
    753   // original hard-coded config had it enabled.
    754   scoped_refptr<FieldTrial> forced_trial =
    755       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    756   forced_trial->AppendGroup(kExtraGroupName, 0);
    757   forced_trial->SetForced();
    758 
    759   int default_group = -1;
    760   scoped_refptr<FieldTrial> client_trial =
    761       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    762   const int extra_group = client_trial->AppendGroup(kExtraGroupName, 100);
    763   EXPECT_NE(default_group, extra_group);
    764 
    765   EXPECT_FALSE(client_trial->group_reported_);
    766   EXPECT_EQ(default_group, client_trial->group());
    767   EXPECT_TRUE(client_trial->group_reported_);
    768   EXPECT_EQ(kDefaultGroupName, client_trial->group_name());
    769 }
    770 
    771 TEST_F(FieldTrialTest, SetForcedChangeDefault_Default) {
    772   const char kTrialName[] = "SetForcedDefaultGroupChange";
    773   const char kGroupAName[] = "A";
    774   const char kGroupBName[] = "B";
    775   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    776 
    777   // Simulate a server-side (forced) config that switches which group is default
    778   // and ensures that the non-forced code receives the correct group numbers.
    779   scoped_refptr<FieldTrial> forced_trial =
    780       CreateFieldTrial(kTrialName, 100, kGroupAName, NULL);
    781   forced_trial->AppendGroup(kGroupBName, 100);
    782   forced_trial->SetForced();
    783 
    784   int default_group = -1;
    785   scoped_refptr<FieldTrial> client_trial =
    786       CreateFieldTrial(kTrialName, 100, kGroupBName, &default_group);
    787   const int extra_group = client_trial->AppendGroup(kGroupAName, 50);
    788   EXPECT_NE(default_group, extra_group);
    789 
    790   EXPECT_FALSE(client_trial->group_reported_);
    791   EXPECT_EQ(default_group, client_trial->group());
    792   EXPECT_TRUE(client_trial->group_reported_);
    793   EXPECT_EQ(kGroupBName, client_trial->group_name());
    794 }
    795 
    796 TEST_F(FieldTrialTest, SetForcedChangeDefault_NonDefault) {
    797   const char kTrialName[] = "SetForcedDefaultGroupChange";
    798   const char kGroupAName[] = "A";
    799   const char kGroupBName[] = "B";
    800   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    801 
    802   // Simulate a server-side (forced) config that switches which group is default
    803   // and ensures that the non-forced code receives the correct group numbers.
    804   scoped_refptr<FieldTrial> forced_trial =
    805       CreateFieldTrial(kTrialName, 100, kGroupAName, NULL);
    806   forced_trial->AppendGroup(kGroupBName, 0);
    807   forced_trial->SetForced();
    808 
    809   int default_group = -1;
    810   scoped_refptr<FieldTrial> client_trial =
    811       CreateFieldTrial(kTrialName, 100, kGroupBName, &default_group);
    812   const int extra_group = client_trial->AppendGroup(kGroupAName, 50);
    813   EXPECT_NE(default_group, extra_group);
    814 
    815   EXPECT_FALSE(client_trial->group_reported_);
    816   EXPECT_EQ(extra_group, client_trial->group());
    817   EXPECT_TRUE(client_trial->group_reported_);
    818   EXPECT_EQ(kGroupAName, client_trial->group_name());
    819 }
    820 
    821 TEST_F(FieldTrialTest, Observe) {
    822   const char kTrialName[] = "TrialToObserve1";
    823   const char kSecondaryGroupName[] = "SecondaryGroup";
    824 
    825   TestFieldTrialObserver observer;
    826   int default_group = -1;
    827   scoped_refptr<FieldTrial> trial =
    828       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    829   const int secondary_group = trial->AppendGroup(kSecondaryGroupName, 50);
    830   const int chosen_group = trial->group();
    831   EXPECT_TRUE(chosen_group == default_group || chosen_group == secondary_group);
    832 
    833   RunLoop().RunUntilIdle();
    834   EXPECT_EQ(kTrialName, observer.trial_name());
    835   if (chosen_group == default_group)
    836     EXPECT_EQ(kDefaultGroupName, observer.group_name());
    837   else
    838     EXPECT_EQ(kSecondaryGroupName, observer.group_name());
    839 }
    840 
    841 TEST_F(FieldTrialTest, ObserveDisabled) {
    842   const char kTrialName[] = "TrialToObserve2";
    843 
    844   TestFieldTrialObserver observer;
    845   int default_group = -1;
    846   scoped_refptr<FieldTrial> trial =
    847       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    848   trial->AppendGroup("A", 25);
    849   trial->AppendGroup("B", 25);
    850   trial->AppendGroup("C", 25);
    851   trial->Disable();
    852 
    853   // Observer shouldn't be notified of a disabled trial.
    854   RunLoop().RunUntilIdle();
    855   EXPECT_TRUE(observer.trial_name().empty());
    856   EXPECT_TRUE(observer.group_name().empty());
    857 
    858   // Observer shouldn't be notified even after a |group()| call.
    859   EXPECT_EQ(default_group, trial->group());
    860   RunLoop().RunUntilIdle();
    861   EXPECT_TRUE(observer.trial_name().empty());
    862   EXPECT_TRUE(observer.group_name().empty());
    863 }
    864 
    865 TEST_F(FieldTrialTest, ObserveForcedDisabled) {
    866   const char kTrialName[] = "TrialToObserve3";
    867 
    868   TestFieldTrialObserver observer;
    869   int default_group = -1;
    870   scoped_refptr<FieldTrial> trial =
    871       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    872   trial->AppendGroup("A", 25);
    873   trial->AppendGroup("B", 25);
    874   trial->AppendGroup("C", 25);
    875   trial->SetForced();
    876   trial->Disable();
    877 
    878   // Observer shouldn't be notified of a disabled trial, even when forced.
    879   RunLoop().RunUntilIdle();
    880   EXPECT_TRUE(observer.trial_name().empty());
    881   EXPECT_TRUE(observer.group_name().empty());
    882 
    883   // Observer shouldn't be notified even after a |group()| call.
    884   EXPECT_EQ(default_group, trial->group());
    885   RunLoop().RunUntilIdle();
    886   EXPECT_TRUE(observer.trial_name().empty());
    887   EXPECT_TRUE(observer.group_name().empty());
    888 }
    889 
    890 TEST_F(FieldTrialTest, DisabledTrialNotActive) {
    891   const char kTrialName[] = "DisabledTrial";
    892   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    893 
    894   scoped_refptr<FieldTrial> trial =
    895       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    896   trial->AppendGroup("X", 50);
    897   trial->Disable();
    898 
    899   // Ensure the trial is not listed as active.
    900   FieldTrial::ActiveGroups active_groups;
    901   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    902   EXPECT_TRUE(active_groups.empty());
    903 
    904   // Ensure the trial is not listed in the |StatesToString()| result.
    905   std::string states;
    906   FieldTrialList::StatesToString(&states);
    907   EXPECT_TRUE(states.empty());
    908 }
    909 
    910 TEST_F(FieldTrialTest, ExpirationYearNotExpired) {
    911   const char kTrialName[] = "NotExpired";
    912   const char kGroupName[] = "Group2";
    913   const int kProbability = 100;
    914   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    915 
    916   scoped_refptr<FieldTrial> trial =
    917       CreateFieldTrial(kTrialName, kProbability, kDefaultGroupName, NULL);
    918   trial->AppendGroup(kGroupName, kProbability);
    919   EXPECT_EQ(kGroupName, trial->group_name());
    920 }
    921 
    922 TEST_F(FieldTrialTest, FloatBoundariesGiveEqualGroupSizes) {
    923   const int kBucketCount = 100;
    924 
    925   // Try each boundary value |i / 100.0| as the entropy value.
    926   for (int i = 0; i < kBucketCount; ++i) {
    927     const double entropy = i / static_cast<double>(kBucketCount);
    928 
    929     scoped_refptr<base::FieldTrial> trial(
    930         new base::FieldTrial("test", kBucketCount, "default", entropy));
    931     for (int j = 0; j < kBucketCount; ++j)
    932       trial->AppendGroup(base::StringPrintf("%d", j), 1);
    933 
    934     EXPECT_EQ(base::StringPrintf("%d", i), trial->group_name());
    935   }
    936 }
    937 
    938 TEST_F(FieldTrialTest, DoesNotSurpassTotalProbability) {
    939   const double kEntropyValue = 1.0 - 1e-9;
    940   ASSERT_LT(kEntropyValue, 1.0);
    941 
    942   scoped_refptr<base::FieldTrial> trial(
    943       new base::FieldTrial("test", 2, "default", kEntropyValue));
    944   trial->AppendGroup("1", 1);
    945   trial->AppendGroup("2", 1);
    946 
    947   EXPECT_EQ("2", trial->group_name());
    948 }
    949 
    950 TEST_F(FieldTrialTest, CreateSimulatedFieldTrial) {
    951   const char kTrialName[] = "CreateSimulatedFieldTrial";
    952   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    953 
    954   // Different cases to test, e.g. default vs. non default group being chosen.
    955   struct {
    956     double entropy_value;
    957     const char* expected_group;
    958   } test_cases[] = {
    959     { 0.4, "A" },
    960     { 0.85, "B" },
    961     { 0.95, kDefaultGroupName },
    962   };
    963 
    964   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
    965     TestFieldTrialObserver observer;
    966     scoped_refptr<FieldTrial> trial(
    967        FieldTrial::CreateSimulatedFieldTrial(kTrialName, 100, kDefaultGroupName,
    968                                              test_cases[i].entropy_value));
    969     trial->AppendGroup("A", 80);
    970     trial->AppendGroup("B", 10);
    971     EXPECT_EQ(test_cases[i].expected_group, trial->group_name());
    972 
    973     // Field trial shouldn't have been registered with the list.
    974     EXPECT_FALSE(FieldTrialList::TrialExists(kTrialName));
    975     EXPECT_EQ(0u, FieldTrialList::GetFieldTrialCount());
    976 
    977     // Observer shouldn't have been notified.
    978     RunLoop().RunUntilIdle();
    979     EXPECT_TRUE(observer.trial_name().empty());
    980 
    981     // The trial shouldn't be in the active set of trials.
    982     FieldTrial::ActiveGroups active_groups;
    983     FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    984     EXPECT_TRUE(active_groups.empty());
    985 
    986     // The trial shouldn't be listed in the |StatesToString()| result.
    987     std::string states;
    988     FieldTrialList::StatesToString(&states);
    989     EXPECT_TRUE(states.empty());
    990   }
    991 }
    992 
    993 }  // namespace base
    994