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