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 <stddef.h>
      8 
      9 #include "base/base_switches.h"
     10 #include "base/build_time.h"
     11 #include "base/feature_list.h"
     12 #include "base/macros.h"
     13 #include "base/memory/ptr_util.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "base/metrics/field_trial_param_associator.h"
     16 #include "base/rand_util.h"
     17 #include "base/run_loop.h"
     18 #include "base/strings/string_number_conversions.h"
     19 #include "base/strings/stringprintf.h"
     20 #include "base/test/gtest_util.h"
     21 #include "base/test/mock_entropy_provider.h"
     22 #include "base/test/scoped_feature_list.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 
     25 namespace base {
     26 
     27 namespace {
     28 
     29 // Default group name used by several tests.
     30 const char kDefaultGroupName[] = "DefaultGroup";
     31 
     32 // Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date.
     33 scoped_refptr<base::FieldTrial> CreateFieldTrial(
     34     const std::string& trial_name,
     35     int total_probability,
     36     const std::string& default_group_name,
     37     int* default_group_number) {
     38   return FieldTrialList::FactoryGetFieldTrial(
     39       trial_name, total_probability, default_group_name,
     40       base::FieldTrialList::kNoExpirationYear, 1, 1,
     41       base::FieldTrial::SESSION_RANDOMIZED, default_group_number);
     42 }
     43 
     44 int OneYearBeforeBuildTime() {
     45   Time one_year_before_build_time = GetBuildTime() - TimeDelta::FromDays(365);
     46   Time::Exploded exploded;
     47   one_year_before_build_time.LocalExplode(&exploded);
     48   return exploded.year;
     49 }
     50 
     51 // FieldTrialList::Observer implementation for testing.
     52 class TestFieldTrialObserver : public FieldTrialList::Observer {
     53  public:
     54   TestFieldTrialObserver() {
     55     FieldTrialList::AddObserver(this);
     56   }
     57 
     58   ~TestFieldTrialObserver() override { FieldTrialList::RemoveObserver(this); }
     59 
     60   void OnFieldTrialGroupFinalized(const std::string& trial,
     61                                   const std::string& group) override {
     62     trial_name_ = trial;
     63     group_name_ = group;
     64   }
     65 
     66   const std::string& trial_name() const { return trial_name_; }
     67   const std::string& group_name() const { return group_name_; }
     68 
     69  private:
     70   std::string trial_name_;
     71   std::string group_name_;
     72 
     73   DISALLOW_COPY_AND_ASSIGN(TestFieldTrialObserver);
     74 };
     75 
     76 }  // namespace
     77 
     78 class FieldTrialTest : public testing::Test {
     79  public:
     80   FieldTrialTest() : trial_list_(NULL) {}
     81 
     82  private:
     83   MessageLoop message_loop_;
     84   FieldTrialList trial_list_;
     85 
     86   DISALLOW_COPY_AND_ASSIGN(FieldTrialTest);
     87 };
     88 
     89 // Test registration, and also check that destructors are called for trials
     90 // (and that Valgrind doesn't catch us leaking).
     91 TEST_F(FieldTrialTest, Registration) {
     92   const char name1[] = "name 1 test";
     93   const char name2[] = "name 2 test";
     94   EXPECT_FALSE(FieldTrialList::Find(name1));
     95   EXPECT_FALSE(FieldTrialList::Find(name2));
     96 
     97   scoped_refptr<FieldTrial> trial1 =
     98       CreateFieldTrial(name1, 10, "default name 1 test", NULL);
     99   EXPECT_EQ(FieldTrial::kNotFinalized, trial1->group_);
    100   EXPECT_EQ(name1, trial1->trial_name());
    101   EXPECT_EQ("", trial1->group_name_internal());
    102 
    103   trial1->AppendGroup(std::string(), 7);
    104 
    105   EXPECT_EQ(trial1.get(), FieldTrialList::Find(name1));
    106   EXPECT_FALSE(FieldTrialList::Find(name2));
    107 
    108   scoped_refptr<FieldTrial> trial2 =
    109       CreateFieldTrial(name2, 10, "default name 2 test", NULL);
    110   EXPECT_EQ(FieldTrial::kNotFinalized, trial2->group_);
    111   EXPECT_EQ(name2, trial2->trial_name());
    112   EXPECT_EQ("", trial2->group_name_internal());
    113 
    114   trial2->AppendGroup("a first group", 7);
    115 
    116   EXPECT_EQ(trial1.get(), FieldTrialList::Find(name1));
    117   EXPECT_EQ(trial2.get(), FieldTrialList::Find(name2));
    118   // Note: FieldTrialList should delete the objects at shutdown.
    119 }
    120 
    121 TEST_F(FieldTrialTest, AbsoluteProbabilities) {
    122   char always_true[] = " always true";
    123   char default_always_true[] = " default always true";
    124   char always_false[] = " always false";
    125   char default_always_false[] = " default always false";
    126   for (int i = 1; i < 250; ++i) {
    127     // Try lots of names, by changing the first character of the name.
    128     char c = static_cast<char>(i);
    129     always_true[0] = c;
    130     default_always_true[0] = c;
    131     always_false[0] = c;
    132     default_always_false[0] = c;
    133 
    134     scoped_refptr<FieldTrial> trial_true =
    135         CreateFieldTrial(always_true, 10, default_always_true, NULL);
    136     const std::string winner = "TheWinner";
    137     int winner_group = trial_true->AppendGroup(winner, 10);
    138 
    139     EXPECT_EQ(winner_group, trial_true->group());
    140     EXPECT_EQ(winner, trial_true->group_name());
    141 
    142     scoped_refptr<FieldTrial> trial_false =
    143         CreateFieldTrial(always_false, 10, default_always_false, NULL);
    144     int loser_group = trial_false->AppendGroup("ALoser", 0);
    145 
    146     EXPECT_NE(loser_group, trial_false->group());
    147   }
    148 }
    149 
    150 TEST_F(FieldTrialTest, RemainingProbability) {
    151   // First create a test that hasn't had a winner yet.
    152   const std::string winner = "Winner";
    153   const std::string loser = "Loser";
    154   scoped_refptr<FieldTrial> trial;
    155   int counter = 0;
    156   int default_group_number = -1;
    157   do {
    158     std::string name = StringPrintf("trial%d", ++counter);
    159     trial = CreateFieldTrial(name, 10, winner, &default_group_number);
    160     trial->AppendGroup(loser, 5);  // 50% chance of not being chosen.
    161     // If a group is not assigned, group_ will be kNotFinalized.
    162   } while (trial->group_ != FieldTrial::kNotFinalized);
    163 
    164   // And that 'default' group (winner) should always win.
    165   EXPECT_EQ(default_group_number, trial->group());
    166 
    167   // And that winner should ALWAYS win.
    168   EXPECT_EQ(winner, trial->group_name());
    169 }
    170 
    171 TEST_F(FieldTrialTest, FiftyFiftyProbability) {
    172   // Check that even with small divisors, we have the proper probabilities, and
    173   // all outcomes are possible.  Since this is a 50-50 test, it should get both
    174   // outcomes in a few tries, but we'll try no more than 100 times (and be flaky
    175   // with probability around 1 in 2^99).
    176   bool first_winner = false;
    177   bool second_winner = false;
    178   int counter = 0;
    179   do {
    180     std::string name = base::StringPrintf("FiftyFifty%d", ++counter);
    181     std::string default_group_name = base::StringPrintf("Default FiftyFifty%d",
    182                                                         ++counter);
    183     scoped_refptr<FieldTrial> trial =
    184         CreateFieldTrial(name, 2, default_group_name, NULL);
    185     trial->AppendGroup("first", 1);  // 50% chance of being chosen.
    186     // If group_ is kNotFinalized, then a group assignement hasn't been done.
    187     if (trial->group_ != FieldTrial::kNotFinalized) {
    188       first_winner = true;
    189       continue;
    190     }
    191     trial->AppendGroup("second", 1);  // Always chosen at this point.
    192     EXPECT_NE(FieldTrial::kNotFinalized, trial->group());
    193     second_winner = true;
    194   } while ((!second_winner || !first_winner) && counter < 100);
    195   EXPECT_TRUE(second_winner);
    196   EXPECT_TRUE(first_winner);
    197 }
    198 
    199 TEST_F(FieldTrialTest, MiddleProbabilities) {
    200   char name[] = " same name";
    201   char default_group_name[] = " default same name";
    202   bool false_event_seen = false;
    203   bool true_event_seen = false;
    204   for (int i = 1; i < 250; ++i) {
    205     char c = static_cast<char>(i);
    206     name[0] = c;
    207     default_group_name[0] = c;
    208     scoped_refptr<FieldTrial> trial =
    209         CreateFieldTrial(name, 10, default_group_name, NULL);
    210     int might_win = trial->AppendGroup("MightWin", 5);
    211 
    212     if (trial->group() == might_win) {
    213       true_event_seen = true;
    214     } else {
    215       false_event_seen = true;
    216     }
    217     if (false_event_seen && true_event_seen)
    218       return;  // Successful test!!!
    219   }
    220   // Very surprising to get here. Probability should be around 1 in 2 ** 250.
    221   // One of the following will fail.
    222   EXPECT_TRUE(false_event_seen);
    223   EXPECT_TRUE(true_event_seen);
    224 }
    225 
    226 TEST_F(FieldTrialTest, OneWinner) {
    227   char name[] = "Some name";
    228   char default_group_name[] = "Default some name";
    229   int group_count(10);
    230 
    231   int default_group_number = -1;
    232   scoped_refptr<FieldTrial> trial =
    233       CreateFieldTrial(name, group_count, default_group_name, NULL);
    234   int winner_index(-2);
    235   std::string winner_name;
    236 
    237   for (int i = 1; i <= group_count; ++i) {
    238     int might_win = trial->AppendGroup(std::string(), 1);
    239 
    240     // Because we keep appending groups, we want to see if the last group that
    241     // was added has been assigned or not.
    242     if (trial->group_ == might_win) {
    243       EXPECT_EQ(-2, winner_index);
    244       winner_index = might_win;
    245       StringAppendF(&winner_name, "%d", might_win);
    246       EXPECT_EQ(winner_name, trial->group_name());
    247     }
    248   }
    249   EXPECT_GE(winner_index, 0);
    250   // Since all groups cover the total probability, we should not have
    251   // chosen the default group.
    252   EXPECT_NE(trial->group(), default_group_number);
    253   EXPECT_EQ(trial->group(), winner_index);
    254   EXPECT_EQ(trial->group_name(), winner_name);
    255 }
    256 
    257 TEST_F(FieldTrialTest, DisableProbability) {
    258   const std::string default_group_name = "Default group";
    259   const std::string loser = "Loser";
    260   const std::string name = "Trial";
    261 
    262   // Create a field trail that has expired.
    263   int default_group_number = -1;
    264   FieldTrial* trial = FieldTrialList::FactoryGetFieldTrial(
    265       name, 1000000000, default_group_name, OneYearBeforeBuildTime(), 1, 1,
    266       FieldTrial::SESSION_RANDOMIZED,
    267       &default_group_number);
    268   trial->AppendGroup(loser, 999999999);  // 99.9999999% chance of being chosen.
    269 
    270   // Because trial has expired, we should always be in the default group.
    271   EXPECT_EQ(default_group_number, trial->group());
    272 
    273   // And that default_group_name should ALWAYS win.
    274   EXPECT_EQ(default_group_name, trial->group_name());
    275 }
    276 
    277 TEST_F(FieldTrialTest, ActiveGroups) {
    278   std::string no_group("No Group");
    279   scoped_refptr<FieldTrial> trial =
    280       CreateFieldTrial(no_group, 10, "Default", NULL);
    281 
    282   // There is no winner yet, so no NameGroupId should be returned.
    283   FieldTrial::ActiveGroup active_group;
    284   EXPECT_FALSE(trial->GetActiveGroup(&active_group));
    285 
    286   // Create a single winning group.
    287   std::string one_winner("One Winner");
    288   trial = CreateFieldTrial(one_winner, 10, "Default", NULL);
    289   std::string winner("Winner");
    290   trial->AppendGroup(winner, 10);
    291   EXPECT_FALSE(trial->GetActiveGroup(&active_group));
    292   // Finalize the group selection by accessing the selected group.
    293   trial->group();
    294   EXPECT_TRUE(trial->GetActiveGroup(&active_group));
    295   EXPECT_EQ(one_winner, active_group.trial_name);
    296   EXPECT_EQ(winner, active_group.group_name);
    297 
    298   std::string multi_group("MultiGroup");
    299   scoped_refptr<FieldTrial> multi_group_trial =
    300       CreateFieldTrial(multi_group, 9, "Default", NULL);
    301 
    302   multi_group_trial->AppendGroup("Me", 3);
    303   multi_group_trial->AppendGroup("You", 3);
    304   multi_group_trial->AppendGroup("Them", 3);
    305   EXPECT_FALSE(multi_group_trial->GetActiveGroup(&active_group));
    306   // Finalize the group selection by accessing the selected group.
    307   multi_group_trial->group();
    308   EXPECT_TRUE(multi_group_trial->GetActiveGroup(&active_group));
    309   EXPECT_EQ(multi_group, active_group.trial_name);
    310   EXPECT_EQ(multi_group_trial->group_name(), active_group.group_name);
    311 
    312   // Now check if the list is built properly...
    313   FieldTrial::ActiveGroups active_groups;
    314   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    315   EXPECT_EQ(2U, active_groups.size());
    316   for (size_t i = 0; i < active_groups.size(); ++i) {
    317     // Order is not guaranteed, so check all values.
    318     EXPECT_NE(no_group, active_groups[i].trial_name);
    319     EXPECT_TRUE(one_winner != active_groups[i].trial_name ||
    320                 winner == active_groups[i].group_name);
    321     EXPECT_TRUE(multi_group != active_groups[i].trial_name ||
    322                 multi_group_trial->group_name() == active_groups[i].group_name);
    323   }
    324 }
    325 
    326 TEST_F(FieldTrialTest, GetActiveFieldTrialGroupsFromString) {
    327   FieldTrial::ActiveGroups active_groups;
    328   FieldTrialList::GetActiveFieldTrialGroupsFromString("*A/X/B/Y/*C/Z",
    329                                                       &active_groups);
    330   ASSERT_EQ(2U, active_groups.size());
    331   EXPECT_EQ("A", active_groups[0].trial_name);
    332   EXPECT_EQ("X", active_groups[0].group_name);
    333   EXPECT_EQ("C", active_groups[1].trial_name);
    334   EXPECT_EQ("Z", active_groups[1].group_name);
    335 }
    336 
    337 TEST_F(FieldTrialTest, AllGroups) {
    338   FieldTrial::State field_trial_state;
    339   std::string one_winner("One Winner");
    340   scoped_refptr<FieldTrial> trial =
    341       CreateFieldTrial(one_winner, 10, "Default", NULL);
    342   std::string winner("Winner");
    343   trial->AppendGroup(winner, 10);
    344   EXPECT_TRUE(trial->GetState(&field_trial_state));
    345   EXPECT_EQ(one_winner, *field_trial_state.trial_name);
    346   EXPECT_EQ(winner, *field_trial_state.group_name);
    347   trial->group();
    348   EXPECT_TRUE(trial->GetState(&field_trial_state));
    349   EXPECT_EQ(one_winner, *field_trial_state.trial_name);
    350   EXPECT_EQ(winner, *field_trial_state.group_name);
    351 
    352   std::string multi_group("MultiGroup");
    353   scoped_refptr<FieldTrial> multi_group_trial =
    354       CreateFieldTrial(multi_group, 9, "Default", NULL);
    355 
    356   multi_group_trial->AppendGroup("Me", 3);
    357   multi_group_trial->AppendGroup("You", 3);
    358   multi_group_trial->AppendGroup("Them", 3);
    359   EXPECT_TRUE(multi_group_trial->GetState(&field_trial_state));
    360   // Finalize the group selection by accessing the selected group.
    361   multi_group_trial->group();
    362   EXPECT_TRUE(multi_group_trial->GetState(&field_trial_state));
    363   EXPECT_EQ(multi_group, *field_trial_state.trial_name);
    364   EXPECT_EQ(multi_group_trial->group_name(), *field_trial_state.group_name);
    365 }
    366 
    367 TEST_F(FieldTrialTest, ActiveGroupsNotFinalized) {
    368   const char kTrialName[] = "TestTrial";
    369   const char kSecondaryGroupName[] = "SecondaryGroup";
    370 
    371   int default_group = -1;
    372   scoped_refptr<FieldTrial> trial =
    373       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    374   const int secondary_group = trial->AppendGroup(kSecondaryGroupName, 50);
    375 
    376   // Before |group()| is called, |GetActiveGroup()| should return false.
    377   FieldTrial::ActiveGroup active_group;
    378   EXPECT_FALSE(trial->GetActiveGroup(&active_group));
    379 
    380   // |GetActiveFieldTrialGroups()| should also not include the trial.
    381   FieldTrial::ActiveGroups active_groups;
    382   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    383   EXPECT_TRUE(active_groups.empty());
    384 
    385   // After |group()| has been called, both APIs should succeed.
    386   const int chosen_group = trial->group();
    387   EXPECT_TRUE(chosen_group == default_group || chosen_group == secondary_group);
    388 
    389   EXPECT_TRUE(trial->GetActiveGroup(&active_group));
    390   EXPECT_EQ(kTrialName, active_group.trial_name);
    391   if (chosen_group == default_group)
    392     EXPECT_EQ(kDefaultGroupName, active_group.group_name);
    393   else
    394     EXPECT_EQ(kSecondaryGroupName, active_group.group_name);
    395 
    396   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    397   ASSERT_EQ(1U, active_groups.size());
    398   EXPECT_EQ(kTrialName, active_groups[0].trial_name);
    399   EXPECT_EQ(active_group.group_name, active_groups[0].group_name);
    400 }
    401 
    402 TEST_F(FieldTrialTest, GetGroupNameWithoutActivation) {
    403   const char kTrialName[] = "TestTrial";
    404   const char kSecondaryGroupName[] = "SecondaryGroup";
    405 
    406   int default_group = -1;
    407   scoped_refptr<FieldTrial> trial =
    408       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    409   trial->AppendGroup(kSecondaryGroupName, 50);
    410 
    411   // The trial should start inactive.
    412   EXPECT_FALSE(FieldTrialList::IsTrialActive(kTrialName));
    413 
    414   // Calling |GetGroupNameWithoutActivation()| should not activate the trial.
    415   std::string group_name = trial->GetGroupNameWithoutActivation();
    416   EXPECT_FALSE(group_name.empty());
    417   EXPECT_FALSE(FieldTrialList::IsTrialActive(kTrialName));
    418 
    419   // Calling |group_name()| should activate it and return the same group name.
    420   EXPECT_EQ(group_name, trial->group_name());
    421   EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
    422 }
    423 
    424 TEST_F(FieldTrialTest, Save) {
    425   std::string save_string;
    426 
    427   scoped_refptr<FieldTrial> trial =
    428       CreateFieldTrial("Some name", 10, "Default some name", NULL);
    429   // There is no winner yet, so no textual group name is associated with trial.
    430   // In this case, the trial should not be included.
    431   EXPECT_EQ("", trial->group_name_internal());
    432   FieldTrialList::StatesToString(&save_string);
    433   EXPECT_EQ("", save_string);
    434   save_string.clear();
    435 
    436   // Create a winning group.
    437   trial->AppendGroup("Winner", 10);
    438   // Finalize the group selection by accessing the selected group.
    439   trial->group();
    440   FieldTrialList::StatesToString(&save_string);
    441   EXPECT_EQ("Some name/Winner/", save_string);
    442   save_string.clear();
    443 
    444   // Create a second trial and winning group.
    445   scoped_refptr<FieldTrial> trial2 =
    446       CreateFieldTrial("xxx", 10, "Default xxx", NULL);
    447   trial2->AppendGroup("yyyy", 10);
    448   // Finalize the group selection by accessing the selected group.
    449   trial2->group();
    450 
    451   FieldTrialList::StatesToString(&save_string);
    452   // We assume names are alphabetized... though this is not critical.
    453   EXPECT_EQ("Some name/Winner/xxx/yyyy/", save_string);
    454   save_string.clear();
    455 
    456   // Create a third trial with only the default group.
    457   scoped_refptr<FieldTrial> trial3 =
    458       CreateFieldTrial("zzz", 10, "default", NULL);
    459   // Finalize the group selection by accessing the selected group.
    460   trial3->group();
    461 
    462   FieldTrialList::StatesToString(&save_string);
    463   EXPECT_EQ("Some name/Winner/xxx/yyyy/zzz/default/", save_string);
    464 }
    465 
    466 TEST_F(FieldTrialTest, SaveAll) {
    467   std::string save_string;
    468 
    469   scoped_refptr<FieldTrial> trial =
    470       CreateFieldTrial("Some name", 10, "Default some name", nullptr);
    471   EXPECT_EQ("", trial->group_name_internal());
    472   FieldTrialList::AllStatesToString(&save_string);
    473   EXPECT_EQ("Some name/Default some name/", save_string);
    474   // Getting all states should have finalized the trial.
    475   EXPECT_EQ("Default some name", trial->group_name_internal());
    476   save_string.clear();
    477 
    478   // Create a winning group.
    479   trial = CreateFieldTrial("trial2", 10, "Default some name", nullptr);
    480   trial->AppendGroup("Winner", 10);
    481   // Finalize the group selection by accessing the selected group.
    482   trial->group();
    483   FieldTrialList::AllStatesToString(&save_string);
    484   EXPECT_EQ("Some name/Default some name/*trial2/Winner/", save_string);
    485   save_string.clear();
    486 
    487   // Create a second trial and winning group.
    488   scoped_refptr<FieldTrial> trial2 =
    489       CreateFieldTrial("xxx", 10, "Default xxx", nullptr);
    490   trial2->AppendGroup("yyyy", 10);
    491   // Finalize the group selection by accessing the selected group.
    492   trial2->group();
    493 
    494   FieldTrialList::AllStatesToString(&save_string);
    495   // We assume names are alphabetized... though this is not critical.
    496   EXPECT_EQ("Some name/Default some name/*trial2/Winner/*xxx/yyyy/",
    497             save_string);
    498   save_string.clear();
    499 
    500   // Create a third trial with only the default group.
    501   scoped_refptr<FieldTrial> trial3 =
    502       CreateFieldTrial("zzz", 10, "default", NULL);
    503 
    504   FieldTrialList::AllStatesToString(&save_string);
    505   EXPECT_EQ("Some name/Default some name/*trial2/Winner/*xxx/yyyy/zzz/default/",
    506             save_string);
    507 }
    508 
    509 TEST_F(FieldTrialTest, Restore) {
    510   ASSERT_FALSE(FieldTrialList::TrialExists("Some_name"));
    511   ASSERT_FALSE(FieldTrialList::TrialExists("xxx"));
    512 
    513   FieldTrialList::CreateTrialsFromString("Some_name/Winner/xxx/yyyy/",
    514                                          std::set<std::string>());
    515 
    516   FieldTrial* trial = FieldTrialList::Find("Some_name");
    517   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    518   EXPECT_EQ("Winner", trial->group_name());
    519   EXPECT_EQ("Some_name", trial->trial_name());
    520 
    521   trial = FieldTrialList::Find("xxx");
    522   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    523   EXPECT_EQ("yyyy", trial->group_name());
    524   EXPECT_EQ("xxx", trial->trial_name());
    525 }
    526 
    527 TEST_F(FieldTrialTest, RestoreNotEndingWithSlash) {
    528   EXPECT_TRUE(FieldTrialList::CreateTrialsFromString("tname/gname",
    529                                                      std::set<std::string>()));
    530 
    531   FieldTrial* trial = FieldTrialList::Find("tname");
    532   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    533   EXPECT_EQ("gname", trial->group_name());
    534   EXPECT_EQ("tname", trial->trial_name());
    535 }
    536 
    537 TEST_F(FieldTrialTest, BogusRestore) {
    538   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString("MissingSlash",
    539                                                       std::set<std::string>()));
    540   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString("MissingGroupName/",
    541                                                       std::set<std::string>()));
    542   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString("noname, only group/",
    543                                                       std::set<std::string>()));
    544   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString("/emptyname",
    545                                                       std::set<std::string>()));
    546   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString("*/emptyname",
    547                                                       std::set<std::string>()));
    548 }
    549 
    550 TEST_F(FieldTrialTest, DuplicateRestore) {
    551   scoped_refptr<FieldTrial> trial =
    552       CreateFieldTrial("Some name", 10, "Default", NULL);
    553   trial->AppendGroup("Winner", 10);
    554   // Finalize the group selection by accessing the selected group.
    555   trial->group();
    556   std::string save_string;
    557   FieldTrialList::StatesToString(&save_string);
    558   EXPECT_EQ("Some name/Winner/", save_string);
    559 
    560   // It is OK if we redundantly specify a winner.
    561   EXPECT_TRUE(FieldTrialList::CreateTrialsFromString(save_string,
    562                                                      std::set<std::string>()));
    563 
    564   // But it is an error to try to change to a different winner.
    565   EXPECT_FALSE(FieldTrialList::CreateTrialsFromString("Some name/Loser/",
    566                                                       std::set<std::string>()));
    567 }
    568 
    569 TEST_F(FieldTrialTest, CreateTrialsFromStringNotActive) {
    570   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    571   ASSERT_FALSE(FieldTrialList::TrialExists("Xyz"));
    572   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString("Abc/def/Xyz/zyx/",
    573                                                      std::set<std::string>()));
    574 
    575   FieldTrial::ActiveGroups active_groups;
    576   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    577   ASSERT_TRUE(active_groups.empty());
    578 
    579   // Check that the values still get returned and querying them activates them.
    580   EXPECT_EQ("def", FieldTrialList::FindFullName("Abc"));
    581   EXPECT_EQ("zyx", FieldTrialList::FindFullName("Xyz"));
    582 
    583   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    584   ASSERT_EQ(2U, active_groups.size());
    585   EXPECT_EQ("Abc", active_groups[0].trial_name);
    586   EXPECT_EQ("def", active_groups[0].group_name);
    587   EXPECT_EQ("Xyz", active_groups[1].trial_name);
    588   EXPECT_EQ("zyx", active_groups[1].group_name);
    589 }
    590 
    591 TEST_F(FieldTrialTest, CreateTrialsFromStringForceActivation) {
    592   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    593   ASSERT_FALSE(FieldTrialList::TrialExists("def"));
    594   ASSERT_FALSE(FieldTrialList::TrialExists("Xyz"));
    595   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString(
    596       "*Abc/cba/def/fed/*Xyz/zyx/", std::set<std::string>()));
    597 
    598   FieldTrial::ActiveGroups active_groups;
    599   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    600   ASSERT_EQ(2U, active_groups.size());
    601   EXPECT_EQ("Abc", active_groups[0].trial_name);
    602   EXPECT_EQ("cba", active_groups[0].group_name);
    603   EXPECT_EQ("Xyz", active_groups[1].trial_name);
    604   EXPECT_EQ("zyx", active_groups[1].group_name);
    605 }
    606 
    607 TEST_F(FieldTrialTest, CreateTrialsFromStringNotActiveObserver) {
    608   ASSERT_FALSE(FieldTrialList::TrialExists("Abc"));
    609 
    610   TestFieldTrialObserver observer;
    611   ASSERT_TRUE(FieldTrialList::CreateTrialsFromString("Abc/def/",
    612                                                      std::set<std::string>()));
    613   RunLoop().RunUntilIdle();
    614   // Observer shouldn't be notified.
    615   EXPECT_TRUE(observer.trial_name().empty());
    616 
    617   // Check that the values still get returned and querying them activates them.
    618   EXPECT_EQ("def", FieldTrialList::FindFullName("Abc"));
    619 
    620   RunLoop().RunUntilIdle();
    621   EXPECT_EQ("Abc", observer.trial_name());
    622   EXPECT_EQ("def", observer.group_name());
    623 }
    624 
    625 TEST_F(FieldTrialTest, CreateTrialsFromStringWithIgnoredFieldTrials) {
    626   ASSERT_FALSE(FieldTrialList::TrialExists("Unaccepted1"));
    627   ASSERT_FALSE(FieldTrialList::TrialExists("Foo"));
    628   ASSERT_FALSE(FieldTrialList::TrialExists("Unaccepted2"));
    629   ASSERT_FALSE(FieldTrialList::TrialExists("Bar"));
    630   ASSERT_FALSE(FieldTrialList::TrialExists("Unaccepted3"));
    631 
    632   std::set<std::string> ignored_trial_names;
    633   ignored_trial_names.insert("Unaccepted1");
    634   ignored_trial_names.insert("Unaccepted2");
    635   ignored_trial_names.insert("Unaccepted3");
    636 
    637   FieldTrialList::CreateTrialsFromString(
    638       "Unaccepted1/Unaccepted1_name/"
    639       "Foo/Foo_name/"
    640       "Unaccepted2/Unaccepted2_name/"
    641       "Bar/Bar_name/"
    642       "Unaccepted3/Unaccepted3_name/",
    643       ignored_trial_names);
    644 
    645   EXPECT_FALSE(FieldTrialList::TrialExists("Unaccepted1"));
    646   EXPECT_TRUE(FieldTrialList::TrialExists("Foo"));
    647   EXPECT_FALSE(FieldTrialList::TrialExists("Unaccepted2"));
    648   EXPECT_TRUE(FieldTrialList::TrialExists("Bar"));
    649   EXPECT_FALSE(FieldTrialList::TrialExists("Unaccepted3"));
    650 
    651   FieldTrial::ActiveGroups active_groups;
    652   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    653   EXPECT_TRUE(active_groups.empty());
    654 
    655   FieldTrial* trial = FieldTrialList::Find("Foo");
    656   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    657   EXPECT_EQ("Foo", trial->trial_name());
    658   EXPECT_EQ("Foo_name", trial->group_name());
    659 
    660   trial = FieldTrialList::Find("Bar");
    661   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    662   EXPECT_EQ("Bar", trial->trial_name());
    663   EXPECT_EQ("Bar_name", trial->group_name());
    664 }
    665 
    666 TEST_F(FieldTrialTest, CreateFieldTrial) {
    667   ASSERT_FALSE(FieldTrialList::TrialExists("Some_name"));
    668 
    669   FieldTrialList::CreateFieldTrial("Some_name", "Winner");
    670 
    671   FieldTrial* trial = FieldTrialList::Find("Some_name");
    672   ASSERT_NE(static_cast<FieldTrial*>(NULL), trial);
    673   EXPECT_EQ("Winner", trial->group_name());
    674   EXPECT_EQ("Some_name", trial->trial_name());
    675 }
    676 
    677 TEST_F(FieldTrialTest, CreateFieldTrialIsNotActive) {
    678   const char kTrialName[] = "CreateFieldTrialIsActiveTrial";
    679   const char kWinnerGroup[] = "Winner";
    680   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    681   FieldTrialList::CreateFieldTrial(kTrialName, kWinnerGroup);
    682 
    683   FieldTrial::ActiveGroups active_groups;
    684   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
    685   EXPECT_TRUE(active_groups.empty());
    686 }
    687 
    688 TEST_F(FieldTrialTest, DuplicateFieldTrial) {
    689   scoped_refptr<FieldTrial> trial =
    690       CreateFieldTrial("Some_name", 10, "Default", NULL);
    691   trial->AppendGroup("Winner", 10);
    692 
    693   // It is OK if we redundantly specify a winner.
    694   FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("Some_name", "Winner");
    695   EXPECT_TRUE(trial1 != NULL);
    696 
    697   // But it is an error to try to change to a different winner.
    698   FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("Some_name", "Loser");
    699   EXPECT_TRUE(trial2 == NULL);
    700 }
    701 
    702 TEST_F(FieldTrialTest, DisableImmediately) {
    703   int default_group_number = -1;
    704   scoped_refptr<FieldTrial> trial =
    705       CreateFieldTrial("trial", 100, "default", &default_group_number);
    706   trial->Disable();
    707   ASSERT_EQ("default", trial->group_name());
    708   ASSERT_EQ(default_group_number, trial->group());
    709 }
    710 
    711 TEST_F(FieldTrialTest, DisableAfterInitialization) {
    712   scoped_refptr<FieldTrial> trial =
    713       CreateFieldTrial("trial", 100, "default", NULL);
    714   trial->AppendGroup("non_default", 100);
    715   trial->Disable();
    716   ASSERT_EQ("default", trial->group_name());
    717 }
    718 
    719 TEST_F(FieldTrialTest, ForcedFieldTrials) {
    720   // Validate we keep the forced choice.
    721   FieldTrial* forced_trial = FieldTrialList::CreateFieldTrial("Use the",
    722                                                               "Force");
    723   EXPECT_STREQ("Force", forced_trial->group_name().c_str());
    724 
    725   int default_group_number = -1;
    726   scoped_refptr<FieldTrial> factory_trial =
    727       CreateFieldTrial("Use the", 1000, "default", &default_group_number);
    728   EXPECT_EQ(factory_trial.get(), forced_trial);
    729 
    730   int chosen_group = factory_trial->AppendGroup("Force", 100);
    731   EXPECT_EQ(chosen_group, factory_trial->group());
    732   int not_chosen_group = factory_trial->AppendGroup("Dark Side", 100);
    733   EXPECT_NE(chosen_group, not_chosen_group);
    734 
    735   // Since we didn't force the default group, we should not be returned the
    736   // chosen group as the default group.
    737   EXPECT_NE(default_group_number, chosen_group);
    738   int new_group = factory_trial->AppendGroup("Duck Tape", 800);
    739   EXPECT_NE(chosen_group, new_group);
    740   // The new group should not be the default group either.
    741   EXPECT_NE(default_group_number, new_group);
    742 }
    743 
    744 TEST_F(FieldTrialTest, ForcedFieldTrialsDefaultGroup) {
    745   // Forcing the default should use the proper group ID.
    746   FieldTrial* forced_trial = FieldTrialList::CreateFieldTrial("Trial Name",
    747                                                               "Default");
    748   int default_group_number = -1;
    749   scoped_refptr<FieldTrial> factory_trial =
    750       CreateFieldTrial("Trial Name", 1000, "Default", &default_group_number);
    751   EXPECT_EQ(forced_trial, factory_trial.get());
    752 
    753   int other_group = factory_trial->AppendGroup("Not Default", 100);
    754   EXPECT_STREQ("Default", factory_trial->group_name().c_str());
    755   EXPECT_EQ(default_group_number, factory_trial->group());
    756   EXPECT_NE(other_group, factory_trial->group());
    757 
    758   int new_other_group = factory_trial->AppendGroup("Not Default Either", 800);
    759   EXPECT_NE(new_other_group, factory_trial->group());
    760 }
    761 
    762 TEST_F(FieldTrialTest, SetForced) {
    763   // Start by setting a trial for which we ensure a winner...
    764   int default_group_number = -1;
    765   scoped_refptr<FieldTrial> forced_trial =
    766       CreateFieldTrial("Use the", 1, "default", &default_group_number);
    767   EXPECT_EQ(forced_trial, forced_trial);
    768 
    769   int forced_group = forced_trial->AppendGroup("Force", 1);
    770   EXPECT_EQ(forced_group, forced_trial->group());
    771 
    772   // Now force it.
    773   forced_trial->SetForced();
    774 
    775   // Now try to set it up differently as a hard coded registration would.
    776   scoped_refptr<FieldTrial> hard_coded_trial =
    777       CreateFieldTrial("Use the", 1, "default", &default_group_number);
    778   EXPECT_EQ(hard_coded_trial, forced_trial);
    779 
    780   int would_lose_group = hard_coded_trial->AppendGroup("Force", 0);
    781   EXPECT_EQ(forced_group, hard_coded_trial->group());
    782   EXPECT_EQ(forced_group, would_lose_group);
    783 
    784   // Same thing if we would have done it to win again.
    785   scoped_refptr<FieldTrial> other_hard_coded_trial =
    786       CreateFieldTrial("Use the", 1, "default", &default_group_number);
    787   EXPECT_EQ(other_hard_coded_trial, forced_trial);
    788 
    789   int would_win_group = other_hard_coded_trial->AppendGroup("Force", 1);
    790   EXPECT_EQ(forced_group, other_hard_coded_trial->group());
    791   EXPECT_EQ(forced_group, would_win_group);
    792 }
    793 
    794 TEST_F(FieldTrialTest, SetForcedDefaultOnly) {
    795   const char kTrialName[] = "SetForcedDefaultOnly";
    796   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    797 
    798   int default_group = -1;
    799   scoped_refptr<FieldTrial> trial =
    800       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    801   trial->SetForced();
    802 
    803   trial = CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    804   EXPECT_EQ(default_group, trial->group());
    805   EXPECT_EQ(kDefaultGroupName, trial->group_name());
    806 }
    807 
    808 TEST_F(FieldTrialTest, SetForcedDefaultWithExtraGroup) {
    809   const char kTrialName[] = "SetForcedDefaultWithExtraGroup";
    810   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    811 
    812   int default_group = -1;
    813   scoped_refptr<FieldTrial> trial =
    814       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    815   trial->SetForced();
    816 
    817   trial = CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    818   const int extra_group = trial->AppendGroup("Extra", 100);
    819   EXPECT_EQ(default_group, trial->group());
    820   EXPECT_NE(extra_group, trial->group());
    821   EXPECT_EQ(kDefaultGroupName, trial->group_name());
    822 }
    823 
    824 TEST_F(FieldTrialTest, SetForcedTurnFeatureOn) {
    825   const char kTrialName[] = "SetForcedTurnFeatureOn";
    826   const char kExtraGroupName[] = "Extra";
    827   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    828 
    829   // Simulate a server-side (forced) config that turns the feature on when the
    830   // original hard-coded config had it disabled.
    831   scoped_refptr<FieldTrial> forced_trial =
    832       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    833   forced_trial->AppendGroup(kExtraGroupName, 100);
    834   forced_trial->SetForced();
    835 
    836   int default_group = -1;
    837   scoped_refptr<FieldTrial> client_trial =
    838       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    839   const int extra_group = client_trial->AppendGroup(kExtraGroupName, 0);
    840   EXPECT_NE(default_group, extra_group);
    841 
    842   EXPECT_FALSE(client_trial->group_reported_);
    843   EXPECT_EQ(extra_group, client_trial->group());
    844   EXPECT_TRUE(client_trial->group_reported_);
    845   EXPECT_EQ(kExtraGroupName, client_trial->group_name());
    846 }
    847 
    848 TEST_F(FieldTrialTest, SetForcedTurnFeatureOff) {
    849   const char kTrialName[] = "SetForcedTurnFeatureOff";
    850   const char kExtraGroupName[] = "Extra";
    851   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    852 
    853   // Simulate a server-side (forced) config that turns the feature off when the
    854   // original hard-coded config had it enabled.
    855   scoped_refptr<FieldTrial> forced_trial =
    856       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    857   forced_trial->AppendGroup(kExtraGroupName, 0);
    858   forced_trial->SetForced();
    859 
    860   int default_group = -1;
    861   scoped_refptr<FieldTrial> client_trial =
    862       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    863   const int extra_group = client_trial->AppendGroup(kExtraGroupName, 100);
    864   EXPECT_NE(default_group, extra_group);
    865 
    866   EXPECT_FALSE(client_trial->group_reported_);
    867   EXPECT_EQ(default_group, client_trial->group());
    868   EXPECT_TRUE(client_trial->group_reported_);
    869   EXPECT_EQ(kDefaultGroupName, client_trial->group_name());
    870 }
    871 
    872 TEST_F(FieldTrialTest, SetForcedChangeDefault_Default) {
    873   const char kTrialName[] = "SetForcedDefaultGroupChange";
    874   const char kGroupAName[] = "A";
    875   const char kGroupBName[] = "B";
    876   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    877 
    878   // Simulate a server-side (forced) config that switches which group is default
    879   // and ensures that the non-forced code receives the correct group numbers.
    880   scoped_refptr<FieldTrial> forced_trial =
    881       CreateFieldTrial(kTrialName, 100, kGroupAName, NULL);
    882   forced_trial->AppendGroup(kGroupBName, 100);
    883   forced_trial->SetForced();
    884 
    885   int default_group = -1;
    886   scoped_refptr<FieldTrial> client_trial =
    887       CreateFieldTrial(kTrialName, 100, kGroupBName, &default_group);
    888   const int extra_group = client_trial->AppendGroup(kGroupAName, 50);
    889   EXPECT_NE(default_group, extra_group);
    890 
    891   EXPECT_FALSE(client_trial->group_reported_);
    892   EXPECT_EQ(default_group, client_trial->group());
    893   EXPECT_TRUE(client_trial->group_reported_);
    894   EXPECT_EQ(kGroupBName, client_trial->group_name());
    895 }
    896 
    897 TEST_F(FieldTrialTest, SetForcedChangeDefault_NonDefault) {
    898   const char kTrialName[] = "SetForcedDefaultGroupChange";
    899   const char kGroupAName[] = "A";
    900   const char kGroupBName[] = "B";
    901   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    902 
    903   // Simulate a server-side (forced) config that switches which group is default
    904   // and ensures that the non-forced code receives the correct group numbers.
    905   scoped_refptr<FieldTrial> forced_trial =
    906       CreateFieldTrial(kTrialName, 100, kGroupAName, NULL);
    907   forced_trial->AppendGroup(kGroupBName, 0);
    908   forced_trial->SetForced();
    909 
    910   int default_group = -1;
    911   scoped_refptr<FieldTrial> client_trial =
    912       CreateFieldTrial(kTrialName, 100, kGroupBName, &default_group);
    913   const int extra_group = client_trial->AppendGroup(kGroupAName, 50);
    914   EXPECT_NE(default_group, extra_group);
    915 
    916   EXPECT_FALSE(client_trial->group_reported_);
    917   EXPECT_EQ(extra_group, client_trial->group());
    918   EXPECT_TRUE(client_trial->group_reported_);
    919   EXPECT_EQ(kGroupAName, client_trial->group_name());
    920 }
    921 
    922 TEST_F(FieldTrialTest, Observe) {
    923   const char kTrialName[] = "TrialToObserve1";
    924   const char kSecondaryGroupName[] = "SecondaryGroup";
    925 
    926   TestFieldTrialObserver observer;
    927   int default_group = -1;
    928   scoped_refptr<FieldTrial> trial =
    929       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    930   const int secondary_group = trial->AppendGroup(kSecondaryGroupName, 50);
    931   const int chosen_group = trial->group();
    932   EXPECT_TRUE(chosen_group == default_group || chosen_group == secondary_group);
    933 
    934   RunLoop().RunUntilIdle();
    935   EXPECT_EQ(kTrialName, observer.trial_name());
    936   if (chosen_group == default_group)
    937     EXPECT_EQ(kDefaultGroupName, observer.group_name());
    938   else
    939     EXPECT_EQ(kSecondaryGroupName, observer.group_name());
    940 }
    941 
    942 TEST_F(FieldTrialTest, ObserveDisabled) {
    943   const char kTrialName[] = "TrialToObserve2";
    944 
    945   TestFieldTrialObserver observer;
    946   int default_group = -1;
    947   scoped_refptr<FieldTrial> trial =
    948       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    949   trial->AppendGroup("A", 25);
    950   trial->AppendGroup("B", 25);
    951   trial->AppendGroup("C", 25);
    952   trial->Disable();
    953 
    954   // Observer shouldn't be notified of a disabled trial.
    955   RunLoop().RunUntilIdle();
    956   EXPECT_TRUE(observer.trial_name().empty());
    957   EXPECT_TRUE(observer.group_name().empty());
    958 
    959   // Observer shouldn't be notified even after a |group()| call.
    960   EXPECT_EQ(default_group, trial->group());
    961   RunLoop().RunUntilIdle();
    962   EXPECT_TRUE(observer.trial_name().empty());
    963   EXPECT_TRUE(observer.group_name().empty());
    964 }
    965 
    966 TEST_F(FieldTrialTest, ObserveForcedDisabled) {
    967   const char kTrialName[] = "TrialToObserve3";
    968 
    969   TestFieldTrialObserver observer;
    970   int default_group = -1;
    971   scoped_refptr<FieldTrial> trial =
    972       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, &default_group);
    973   trial->AppendGroup("A", 25);
    974   trial->AppendGroup("B", 25);
    975   trial->AppendGroup("C", 25);
    976   trial->SetForced();
    977   trial->Disable();
    978 
    979   // Observer shouldn't be notified of a disabled trial, even when forced.
    980   RunLoop().RunUntilIdle();
    981   EXPECT_TRUE(observer.trial_name().empty());
    982   EXPECT_TRUE(observer.group_name().empty());
    983 
    984   // Observer shouldn't be notified even after a |group()| call.
    985   EXPECT_EQ(default_group, trial->group());
    986   RunLoop().RunUntilIdle();
    987   EXPECT_TRUE(observer.trial_name().empty());
    988   EXPECT_TRUE(observer.group_name().empty());
    989 }
    990 
    991 TEST_F(FieldTrialTest, DisabledTrialNotActive) {
    992   const char kTrialName[] = "DisabledTrial";
    993   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
    994 
    995   scoped_refptr<FieldTrial> trial =
    996       CreateFieldTrial(kTrialName, 100, kDefaultGroupName, NULL);
    997   trial->AppendGroup("X", 50);
    998   trial->Disable();
    999 
   1000   // Ensure the trial is not listed as active.
   1001   FieldTrial::ActiveGroups active_groups;
   1002   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
   1003   EXPECT_TRUE(active_groups.empty());
   1004 
   1005   // Ensure the trial is not listed in the |StatesToString()| result.
   1006   std::string states;
   1007   FieldTrialList::StatesToString(&states);
   1008   EXPECT_TRUE(states.empty());
   1009 }
   1010 
   1011 TEST_F(FieldTrialTest, ExpirationYearNotExpired) {
   1012   const char kTrialName[] = "NotExpired";
   1013   const char kGroupName[] = "Group2";
   1014   const int kProbability = 100;
   1015   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
   1016 
   1017   scoped_refptr<FieldTrial> trial =
   1018       CreateFieldTrial(kTrialName, kProbability, kDefaultGroupName, NULL);
   1019   trial->AppendGroup(kGroupName, kProbability);
   1020   EXPECT_EQ(kGroupName, trial->group_name());
   1021 }
   1022 
   1023 TEST_F(FieldTrialTest, FloatBoundariesGiveEqualGroupSizes) {
   1024   const int kBucketCount = 100;
   1025 
   1026   // Try each boundary value |i / 100.0| as the entropy value.
   1027   for (int i = 0; i < kBucketCount; ++i) {
   1028     const double entropy = i / static_cast<double>(kBucketCount);
   1029 
   1030     scoped_refptr<base::FieldTrial> trial(
   1031         new base::FieldTrial("test", kBucketCount, "default", entropy));
   1032     for (int j = 0; j < kBucketCount; ++j)
   1033       trial->AppendGroup(base::IntToString(j), 1);
   1034 
   1035     EXPECT_EQ(base::IntToString(i), trial->group_name());
   1036   }
   1037 }
   1038 
   1039 TEST_F(FieldTrialTest, DoesNotSurpassTotalProbability) {
   1040   const double kEntropyValue = 1.0 - 1e-9;
   1041   ASSERT_LT(kEntropyValue, 1.0);
   1042 
   1043   scoped_refptr<base::FieldTrial> trial(
   1044       new base::FieldTrial("test", 2, "default", kEntropyValue));
   1045   trial->AppendGroup("1", 1);
   1046   trial->AppendGroup("2", 1);
   1047 
   1048   EXPECT_EQ("2", trial->group_name());
   1049 }
   1050 
   1051 TEST_F(FieldTrialTest, CreateSimulatedFieldTrial) {
   1052   const char kTrialName[] = "CreateSimulatedFieldTrial";
   1053   ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName));
   1054 
   1055   // Different cases to test, e.g. default vs. non default group being chosen.
   1056   struct {
   1057     double entropy_value;
   1058     const char* expected_group;
   1059   } test_cases[] = {
   1060     { 0.4, "A" },
   1061     { 0.85, "B" },
   1062     { 0.95, kDefaultGroupName },
   1063   };
   1064 
   1065   for (size_t i = 0; i < arraysize(test_cases); ++i) {
   1066     TestFieldTrialObserver observer;
   1067     scoped_refptr<FieldTrial> trial(
   1068        FieldTrial::CreateSimulatedFieldTrial(kTrialName, 100, kDefaultGroupName,
   1069                                              test_cases[i].entropy_value));
   1070     trial->AppendGroup("A", 80);
   1071     trial->AppendGroup("B", 10);
   1072     EXPECT_EQ(test_cases[i].expected_group, trial->group_name());
   1073 
   1074     // Field trial shouldn't have been registered with the list.
   1075     EXPECT_FALSE(FieldTrialList::TrialExists(kTrialName));
   1076     EXPECT_EQ(0u, FieldTrialList::GetFieldTrialCount());
   1077 
   1078     // Observer shouldn't have been notified.
   1079     RunLoop().RunUntilIdle();
   1080     EXPECT_TRUE(observer.trial_name().empty());
   1081 
   1082     // The trial shouldn't be in the active set of trials.
   1083     FieldTrial::ActiveGroups active_groups;
   1084     FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
   1085     EXPECT_TRUE(active_groups.empty());
   1086 
   1087     // The trial shouldn't be listed in the |StatesToString()| result.
   1088     std::string states;
   1089     FieldTrialList::StatesToString(&states);
   1090     EXPECT_TRUE(states.empty());
   1091   }
   1092 }
   1093 
   1094 TEST(FieldTrialTestWithoutList, StatesStringFormat) {
   1095   std::string save_string;
   1096 
   1097   // Scoping the first FieldTrialList, as we need another one to test the
   1098   // importing function.
   1099   {
   1100     FieldTrialList field_trial_list(NULL);
   1101     scoped_refptr<FieldTrial> trial =
   1102         CreateFieldTrial("Abc", 10, "Default some name", NULL);
   1103     trial->AppendGroup("cba", 10);
   1104     trial->group();
   1105     scoped_refptr<FieldTrial> trial2 =
   1106         CreateFieldTrial("Xyz", 10, "Default xxx", NULL);
   1107     trial2->AppendGroup("zyx", 10);
   1108     trial2->group();
   1109     scoped_refptr<FieldTrial> trial3 =
   1110         CreateFieldTrial("zzz", 10, "default", NULL);
   1111 
   1112     FieldTrialList::AllStatesToString(&save_string);
   1113   }
   1114 
   1115   // Starting with a new blank FieldTrialList.
   1116   FieldTrialList field_trial_list(NULL);
   1117   ASSERT_TRUE(field_trial_list.CreateTrialsFromString(save_string,
   1118                                                       std::set<std::string>()));
   1119 
   1120   FieldTrial::ActiveGroups active_groups;
   1121   field_trial_list.GetActiveFieldTrialGroups(&active_groups);
   1122   ASSERT_EQ(2U, active_groups.size());
   1123   EXPECT_EQ("Abc", active_groups[0].trial_name);
   1124   EXPECT_EQ("cba", active_groups[0].group_name);
   1125   EXPECT_EQ("Xyz", active_groups[1].trial_name);
   1126   EXPECT_EQ("zyx", active_groups[1].group_name);
   1127   EXPECT_TRUE(field_trial_list.TrialExists("zzz"));
   1128 }
   1129 
   1130 TEST(FieldTrialDeathTest, OneTimeRandomizedTrialWithoutFieldTrialList) {
   1131   // Trying to instantiate a one-time randomized field trial before the
   1132   // FieldTrialList is created should crash.
   1133   EXPECT_DEATH_IF_SUPPORTED(
   1134       FieldTrialList::FactoryGetFieldTrial(
   1135           "OneTimeRandomizedTrialWithoutFieldTrialList", 100, kDefaultGroupName,
   1136           base::FieldTrialList::kNoExpirationYear, 1, 1,
   1137           base::FieldTrial::ONE_TIME_RANDOMIZED, NULL),
   1138       "");
   1139 }
   1140 
   1141 #if defined(OS_WIN)
   1142 TEST(FieldTrialListTest, TestCopyFieldTrialStateToFlags) {
   1143   base::FieldTrialList field_trial_list(
   1144       base::MakeUnique<base::MockEntropyProvider>());
   1145   base::FieldTrialList::CreateFieldTrial("Trial1", "Group1");
   1146   base::FilePath test_file_path = base::FilePath(FILE_PATH_LITERAL("Program"));
   1147   base::CommandLine cmd_line = base::CommandLine(test_file_path);
   1148   const char field_trial_handle[] = "test-field-trial-handle";
   1149   const char enable_features_switch[] = "test-enable-features";
   1150   const char disable_features_switch[] = "test-disable-features";
   1151 
   1152   base::FieldTrialList::CopyFieldTrialStateToFlags(
   1153       field_trial_handle, enable_features_switch, disable_features_switch,
   1154       &cmd_line);
   1155   EXPECT_TRUE(cmd_line.HasSwitch(field_trial_handle) ||
   1156               cmd_line.HasSwitch(switches::kForceFieldTrials));
   1157 }
   1158 #endif
   1159 
   1160 TEST(FieldTrialListTest, InstantiateAllocator) {
   1161   test::ScopedFeatureList scoped_feature_list;
   1162   scoped_feature_list.Init();
   1163 
   1164   FieldTrialList field_trial_list(nullptr);
   1165   FieldTrialList::CreateFieldTrial("Trial1", "Group1");
   1166 
   1167   FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
   1168   void* memory = field_trial_list.field_trial_allocator_->shared_memory();
   1169   size_t used = field_trial_list.field_trial_allocator_->used();
   1170 
   1171   // Ensure that the function is idempotent.
   1172   FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
   1173   void* new_memory = field_trial_list.field_trial_allocator_->shared_memory();
   1174   size_t new_used = field_trial_list.field_trial_allocator_->used();
   1175   EXPECT_EQ(memory, new_memory);
   1176   EXPECT_EQ(used, new_used);
   1177 }
   1178 
   1179 TEST(FieldTrialListTest, AddTrialsToAllocator) {
   1180   std::string save_string;
   1181   base::SharedMemoryHandle handle;
   1182 
   1183   // Scoping the first FieldTrialList, as we need another one to test that it
   1184   // matches.
   1185   {
   1186     test::ScopedFeatureList scoped_feature_list;
   1187     scoped_feature_list.Init();
   1188 
   1189     FieldTrialList field_trial_list(nullptr);
   1190     FieldTrialList::CreateFieldTrial("Trial1", "Group1");
   1191     FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
   1192     FieldTrialList::AllStatesToString(&save_string);
   1193     handle = base::SharedMemory::DuplicateHandle(
   1194         field_trial_list.field_trial_allocator_->shared_memory()->handle());
   1195   }
   1196 
   1197   FieldTrialList field_trial_list2(nullptr);
   1198   std::unique_ptr<base::SharedMemory> shm(new SharedMemory(handle, true));
   1199   // 4 KiB is enough to hold the trials only created for this test.
   1200   shm.get()->Map(4 << 10);
   1201   FieldTrialList::CreateTrialsFromSharedMemory(std::move(shm));
   1202   std::string check_string;
   1203   FieldTrialList::AllStatesToString(&check_string);
   1204   EXPECT_EQ(save_string, check_string);
   1205 }
   1206 
   1207 TEST(FieldTrialListTest, DoNotAddSimulatedFieldTrialsToAllocator) {
   1208   constexpr char kTrialName[] = "trial";
   1209   base::SharedMemoryHandle handle;
   1210   {
   1211     test::ScopedFeatureList scoped_feature_list;
   1212     scoped_feature_list.Init();
   1213 
   1214     // Create a simulated trial and a real trial and call group() on them, which
   1215     // should only add the real trial to the field trial allocator.
   1216     FieldTrialList field_trial_list(nullptr);
   1217     FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
   1218 
   1219     // This shouldn't add to the allocator.
   1220     scoped_refptr<FieldTrial> simulated_trial =
   1221         FieldTrial::CreateSimulatedFieldTrial(kTrialName, 100, "Simulated",
   1222                                               0.95);
   1223     simulated_trial->group();
   1224 
   1225     // This should add to the allocator.
   1226     FieldTrial* real_trial =
   1227         FieldTrialList::CreateFieldTrial(kTrialName, "Real");
   1228     real_trial->group();
   1229 
   1230     handle = base::SharedMemory::DuplicateHandle(
   1231         field_trial_list.field_trial_allocator_->shared_memory()->handle());
   1232   }
   1233 
   1234   // Check that there's only one entry in the allocator.
   1235   FieldTrialList field_trial_list2(nullptr);
   1236   std::unique_ptr<base::SharedMemory> shm(new SharedMemory(handle, true));
   1237   // 4 KiB is enough to hold the trials only created for this test.
   1238   shm.get()->Map(4 << 10);
   1239   FieldTrialList::CreateTrialsFromSharedMemory(std::move(shm));
   1240   std::string check_string;
   1241   FieldTrialList::AllStatesToString(&check_string);
   1242   ASSERT_EQ(check_string.find("Simulated"), std::string::npos);
   1243 }
   1244 
   1245 TEST(FieldTrialListTest, AssociateFieldTrialParams) {
   1246   test::ScopedFeatureList scoped_feature_list;
   1247   scoped_feature_list.Init();
   1248 
   1249   std::string trial_name("Trial1");
   1250   std::string group_name("Group1");
   1251 
   1252   // Create a field trial with some params.
   1253   FieldTrialList field_trial_list(nullptr);
   1254   FieldTrialList::CreateFieldTrial(trial_name, group_name);
   1255   std::map<std::string, std::string> params;
   1256   params["key1"] = "value1";
   1257   params["key2"] = "value2";
   1258   FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
   1259       trial_name, group_name, params);
   1260   FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
   1261 
   1262   // Clear all cached params from the associator.
   1263   FieldTrialParamAssociator::GetInstance()->ClearAllCachedParamsForTesting();
   1264   // Check that the params have been cleared from the cache.
   1265   std::map<std::string, std::string> cached_params;
   1266   FieldTrialParamAssociator::GetInstance()->GetFieldTrialParamsWithoutFallback(
   1267       trial_name, group_name, &cached_params);
   1268   EXPECT_EQ(0U, cached_params.size());
   1269 
   1270   // Check that we fetch the param from shared memory properly.
   1271   std::map<std::string, std::string> new_params;
   1272   FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams(trial_name,
   1273                                                                 &new_params);
   1274   EXPECT_EQ("value1", new_params["key1"]);
   1275   EXPECT_EQ("value2", new_params["key2"]);
   1276   EXPECT_EQ(2U, new_params.size());
   1277 }
   1278 
   1279 TEST(FieldTrialListTest, ClearParamsFromSharedMemory) {
   1280   std::string trial_name("Trial1");
   1281   std::string group_name("Group1");
   1282 
   1283   base::SharedMemoryHandle handle;
   1284   {
   1285     test::ScopedFeatureList scoped_feature_list;
   1286     scoped_feature_list.Init();
   1287 
   1288     // Create a field trial with some params.
   1289     FieldTrialList field_trial_list(nullptr);
   1290     FieldTrial* trial =
   1291         FieldTrialList::CreateFieldTrial(trial_name, group_name);
   1292     std::map<std::string, std::string> params;
   1293     params["key1"] = "value1";
   1294     params["key2"] = "value2";
   1295     FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
   1296         trial_name, group_name, params);
   1297     FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
   1298 
   1299     // Clear all params from the associator AND shared memory. The allocated
   1300     // segments should be different.
   1301     FieldTrial::FieldTrialRef old_ref = trial->ref_;
   1302     FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
   1303     FieldTrial::FieldTrialRef new_ref = trial->ref_;
   1304     EXPECT_NE(old_ref, new_ref);
   1305 
   1306     // Check that there are no params associated with the field trial anymore.
   1307     std::map<std::string, std::string> new_params;
   1308     FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams(trial_name,
   1309                                                                   &new_params);
   1310     EXPECT_EQ(0U, new_params.size());
   1311 
   1312     // Now duplicate the handle so we can easily check that the trial is still
   1313     // in shared memory via AllStatesToString.
   1314     handle = base::SharedMemory::DuplicateHandle(
   1315         field_trial_list.field_trial_allocator_->shared_memory()->handle());
   1316   }
   1317 
   1318   // Check that we have the trial.
   1319   FieldTrialList field_trial_list2(nullptr);
   1320   std::unique_ptr<base::SharedMemory> shm(new SharedMemory(handle, true));
   1321   // 4 KiB is enough to hold the trials only created for this test.
   1322   shm.get()->Map(4 << 10);
   1323   FieldTrialList::CreateTrialsFromSharedMemory(std::move(shm));
   1324   std::string check_string;
   1325   FieldTrialList::AllStatesToString(&check_string);
   1326   EXPECT_EQ("*Trial1/Group1/", check_string);
   1327 }
   1328 
   1329 TEST(FieldTrialListTest, DumpAndFetchFromSharedMemory) {
   1330   std::string trial_name("Trial1");
   1331   std::string group_name("Group1");
   1332 
   1333   // Create a field trial with some params.
   1334   FieldTrialList field_trial_list(nullptr);
   1335   FieldTrialList::CreateFieldTrial(trial_name, group_name);
   1336   std::map<std::string, std::string> params;
   1337   params["key1"] = "value1";
   1338   params["key2"] = "value2";
   1339   FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
   1340       trial_name, group_name, params);
   1341 
   1342   std::unique_ptr<base::SharedMemory> shm(new SharedMemory());
   1343   // 4 KiB is enough to hold the trials only created for this test.
   1344   shm.get()->CreateAndMapAnonymous(4 << 10);
   1345   // We _could_ use PersistentMemoryAllocator, this just has less params.
   1346   SharedPersistentMemoryAllocator allocator(std::move(shm), 1, "", false);
   1347 
   1348   // Dump and subsequently retrieve the field trial to |allocator|.
   1349   FieldTrialList::DumpAllFieldTrialsToPersistentAllocator(&allocator);
   1350   std::vector<const FieldTrial::FieldTrialEntry*> entries =
   1351       FieldTrialList::GetAllFieldTrialsFromPersistentAllocator(allocator);
   1352 
   1353   // Check that we have the entry we put in.
   1354   EXPECT_EQ(1u, entries.size());
   1355   const FieldTrial::FieldTrialEntry* entry = entries[0];
   1356 
   1357   // Check that the trial and group names match.
   1358   StringPiece shm_trial_name;
   1359   StringPiece shm_group_name;
   1360   entry->GetTrialAndGroupName(&shm_trial_name, &shm_group_name);
   1361   EXPECT_EQ(trial_name, shm_trial_name);
   1362   EXPECT_EQ(group_name, shm_group_name);
   1363 
   1364   // Check that the params match.
   1365   std::map<std::string, std::string> shm_params;
   1366   entry->GetParams(&shm_params);
   1367   EXPECT_EQ(2u, shm_params.size());
   1368   EXPECT_EQ("value1", shm_params["key1"]);
   1369   EXPECT_EQ("value2", shm_params["key2"]);
   1370 }
   1371 
   1372 }  // namespace base
   1373