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