OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Test of FieldTrial class | 5 // Test of FieldTrial class |
6 | 6 |
7 #include "base/metrics/field_trial.h" | 7 #include "base/metrics/field_trial.h" |
8 | 8 |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 | 11 |
12 namespace base { | 12 namespace base { |
13 | 13 |
14 class FieldTrialTest : public testing::Test { | 14 class FieldTrialTest : public testing::Test { |
15 public: | 15 public: |
16 FieldTrialTest() : trial_list_() { } | 16 FieldTrialTest() : trial_list_() { } |
17 | 17 |
18 private: | 18 private: |
19 FieldTrialList trial_list_; | 19 FieldTrialList trial_list_; |
20 }; | 20 }; |
21 | 21 |
22 // Test registration, and also check that destructors are called for trials | 22 // Test registration, and also check that destructors are called for trials |
23 // (and that Purify doesn't catch us leaking). | 23 // (and that Purify doesn't catch us leaking). |
24 TEST_F(FieldTrialTest, Registration) { | 24 TEST_F(FieldTrialTest, Registration) { |
25 const char* name1 = "name 1 test"; | 25 const char* name1 = "name 1 test"; |
26 const char* name2 = "name 2 test"; | 26 const char* name2 = "name 2 test"; |
27 EXPECT_FALSE(FieldTrialList::Find(name1)); | 27 EXPECT_FALSE(FieldTrialList::Find(name1)); |
28 EXPECT_FALSE(FieldTrialList::Find(name2)); | 28 EXPECT_FALSE(FieldTrialList::Find(name2)); |
29 | 29 |
30 FieldTrial* trial1 = new FieldTrial(name1, 10); | 30 FieldTrial* trial1 = |
31 EXPECT_EQ(FieldTrial::kNotParticipating, trial1->group()); | 31 new FieldTrial(name1, 10, "default name 1 test", 2011, 12, 31); |
jar (doing other things)
2011/01/15 20:52:47
For these constants, I'd suggest writing a little
| |
32 EXPECT_EQ(FieldTrial::kNotFinalized, trial1->group_); | |
32 EXPECT_EQ(name1, trial1->name()); | 33 EXPECT_EQ(name1, trial1->name()); |
33 EXPECT_EQ("", trial1->group_name()); | 34 EXPECT_EQ("", trial1->group_name()); |
34 | 35 |
35 trial1->AppendGroup("", 7); | 36 trial1->AppendGroup("", 7); |
36 | 37 |
37 EXPECT_EQ(trial1, FieldTrialList::Find(name1)); | 38 EXPECT_EQ(trial1, FieldTrialList::Find(name1)); |
38 EXPECT_FALSE(FieldTrialList::Find(name2)); | 39 EXPECT_FALSE(FieldTrialList::Find(name2)); |
39 | 40 |
40 FieldTrial* trial2 = new FieldTrial(name2, 10); | 41 FieldTrial* trial2 = |
41 EXPECT_EQ(FieldTrial::kNotParticipating, trial2->group()); | 42 new FieldTrial(name2, 10, "default name 2 test", 2011, 12, 31); |
43 EXPECT_EQ(FieldTrial::kNotFinalized, trial2->group_); | |
42 EXPECT_EQ(name2, trial2->name()); | 44 EXPECT_EQ(name2, trial2->name()); |
43 EXPECT_EQ("", trial2->group_name()); | 45 EXPECT_EQ("", trial2->group_name()); |
44 | 46 |
45 trial2->AppendGroup("a first group", 7); | 47 trial2->AppendGroup("a first group", 7); |
46 | 48 |
47 EXPECT_EQ(trial1, FieldTrialList::Find(name1)); | 49 EXPECT_EQ(trial1, FieldTrialList::Find(name1)); |
48 EXPECT_EQ(trial2, FieldTrialList::Find(name2)); | 50 EXPECT_EQ(trial2, FieldTrialList::Find(name2)); |
49 // Note: FieldTrialList should delete the objects at shutdown. | 51 // Note: FieldTrialList should delete the objects at shutdown. |
50 } | 52 } |
51 | 53 |
52 TEST_F(FieldTrialTest, AbsoluteProbabilities) { | 54 TEST_F(FieldTrialTest, AbsoluteProbabilities) { |
53 char always_true[] = " always true"; | 55 char always_true[] = " always true"; |
56 char default_always_true[] = " default always true"; | |
54 char always_false[] = " always false"; | 57 char always_false[] = " always false"; |
58 char default_always_false[] = " default always false"; | |
55 for (int i = 1; i < 250; ++i) { | 59 for (int i = 1; i < 250; ++i) { |
56 // Try lots of names, by changing the first character of the name. | 60 // Try lots of names, by changing the first character of the name. |
57 always_true[0] = i; | 61 always_true[0] = i; |
62 default_always_true[0] = i; | |
58 always_false[0] = i; | 63 always_false[0] = i; |
64 default_always_false[0] = i; | |
59 | 65 |
60 FieldTrial* trial_true = new FieldTrial(always_true, 10); | 66 FieldTrial* trial_true = |
67 new FieldTrial(always_true, 10, default_always_true, 2011, 12, 31); | |
61 const std::string winner = "TheWinner"; | 68 const std::string winner = "TheWinner"; |
62 int winner_group = trial_true->AppendGroup(winner, 10); | 69 int winner_group = trial_true->AppendGroup(winner, 10); |
63 | 70 |
64 EXPECT_EQ(winner_group, trial_true->group()); | 71 EXPECT_EQ(winner_group, trial_true->group()); |
65 EXPECT_EQ(winner, trial_true->group_name()); | 72 EXPECT_EQ(winner, trial_true->group_name()); |
66 | 73 |
67 FieldTrial* trial_false = new FieldTrial(always_false, 10); | 74 FieldTrial* trial_false = |
75 new FieldTrial(always_false, 10, default_always_false, 2011, 12, 31); | |
68 int loser_group = trial_false->AppendGroup("ALoser", 0); | 76 int loser_group = trial_false->AppendGroup("ALoser", 0); |
69 | 77 |
70 EXPECT_NE(loser_group, trial_false->group()); | 78 EXPECT_NE(loser_group, trial_false->group()); |
71 } | 79 } |
72 } | 80 } |
73 | 81 |
74 TEST_F(FieldTrialTest, RemainingProbability) { | 82 TEST_F(FieldTrialTest, RemainingProbability) { |
75 // First create a test that hasn't had a winner yet. | 83 // First create a test that hasn't had a winner yet. |
76 const std::string winner = "Winner"; | 84 const std::string winner = "Winner"; |
77 const std::string loser = "Loser"; | 85 const std::string loser = "Loser"; |
78 scoped_refptr<FieldTrial> trial; | 86 scoped_refptr<FieldTrial> trial; |
79 int counter = 0; | 87 int counter = 0; |
80 do { | 88 do { |
81 std::string name = StringPrintf("trial%d", ++counter); | 89 std::string name = StringPrintf("trial%d", ++counter); |
82 trial = new FieldTrial(name, 10); | 90 trial = new FieldTrial(name, 10, winner, 2011, 12, 31); |
83 trial->AppendGroup(loser, 5); // 50% chance of not being chosen. | 91 trial->AppendGroup(loser, 5); // 50% chance of not being chosen. |
84 } while (trial->group() != FieldTrial::kNotParticipating); | 92 // If a group is not assigned, group_ will be kNotFinalized. |
93 } while (trial->group_ != FieldTrial::kNotFinalized); | |
85 | 94 |
86 // Now add a winner with all remaining probability. | 95 // And that 'default' group (winner) should always win. |
87 trial->AppendGroup(winner, FieldTrial::kAllRemainingProbability); | 96 EXPECT_EQ(FieldTrial::kDefaultGroupNumber, trial->group()); |
88 | 97 |
89 // And that winner should ALWAYS win. | 98 // And that winner should ALWAYS win. |
90 EXPECT_EQ(winner, trial->group_name()); | 99 EXPECT_EQ(winner, trial->group_name()); |
91 } | 100 } |
92 | 101 |
93 TEST_F(FieldTrialTest, FiftyFiftyProbability) { | 102 TEST_F(FieldTrialTest, FiftyFiftyProbability) { |
94 // Check that even with small divisors, we have the proper probabilities, and | 103 // Check that even with small divisors, we have the proper probabilities, and |
95 // all outcomes are possible. Since this is a 50-50 test, it should get both | 104 // all outcomes are possible. Since this is a 50-50 test, it should get both |
96 // outcomes in a few tries, but we'll try no more than 100 times (and be flaky | 105 // outcomes in a few tries, but we'll try no more than 100 times (and be flaky |
97 // with probability around 1 in 2^99). | 106 // with probability around 1 in 2^99). |
98 bool first_winner = false; | 107 bool first_winner = false; |
99 bool second_winner = false; | 108 bool second_winner = false; |
100 int counter = 0; | 109 int counter = 0; |
101 do { | 110 do { |
102 std::string name = base::StringPrintf("FiftyFifty%d", ++counter); | 111 std::string name = base::StringPrintf("FiftyFifty%d", ++counter); |
103 scoped_refptr<FieldTrial> trial(new FieldTrial(name, 2)); | 112 std::string default_group_name = base::StringPrintf("Default FiftyFifty%d", |
113 ++counter); | |
114 scoped_refptr<FieldTrial> trial( | |
115 new FieldTrial(name, 2, default_group_name, 2011, 12, 31)); | |
104 trial->AppendGroup("first", 1); // 50% chance of being chosen. | 116 trial->AppendGroup("first", 1); // 50% chance of being chosen. |
105 if (trial->group() != FieldTrial::kNotParticipating) { | 117 // If group_ is kNotFinalized, then a group assignement hasn't been done. |
118 if (trial->group_ != FieldTrial::kNotFinalized) { | |
106 first_winner = true; | 119 first_winner = true; |
107 continue; | 120 continue; |
108 } | 121 } |
109 trial->AppendGroup("second", 1); // Always chosen at this point. | 122 trial->AppendGroup("second", 1); // Always chosen at this point. |
110 EXPECT_NE(FieldTrial::kNotParticipating, trial->group()); | 123 EXPECT_NE(FieldTrial::kNotFinalized, trial->group()); |
111 second_winner = true; | 124 second_winner = true; |
112 } while ((!second_winner || !first_winner) && counter < 100); | 125 } while ((!second_winner || !first_winner) && counter < 100); |
113 EXPECT_TRUE(second_winner); | 126 EXPECT_TRUE(second_winner); |
114 EXPECT_TRUE(first_winner); | 127 EXPECT_TRUE(first_winner); |
115 } | 128 } |
116 | 129 |
117 TEST_F(FieldTrialTest, MiddleProbabilities) { | 130 TEST_F(FieldTrialTest, MiddleProbabilities) { |
118 char name[] = " same name"; | 131 char name[] = " same name"; |
132 char default_group_name[] = " default same name"; | |
119 bool false_event_seen = false; | 133 bool false_event_seen = false; |
120 bool true_event_seen = false; | 134 bool true_event_seen = false; |
121 for (int i = 1; i < 250; ++i) { | 135 for (int i = 1; i < 250; ++i) { |
122 name[0] = i; | 136 name[0] = i; |
123 FieldTrial* trial = new FieldTrial(name, 10); | 137 default_group_name[0] = i; |
138 FieldTrial* trial = | |
139 new FieldTrial(name, 10, default_group_name, 2011, 12, 31); | |
124 int might_win = trial->AppendGroup("MightWin", 5); | 140 int might_win = trial->AppendGroup("MightWin", 5); |
125 | 141 |
126 if (trial->group() == might_win) { | 142 if (trial->group() == might_win) { |
127 true_event_seen = true; | 143 true_event_seen = true; |
128 } else { | 144 } else { |
129 false_event_seen = true; | 145 false_event_seen = true; |
130 } | 146 } |
131 if (false_event_seen && true_event_seen) | 147 if (false_event_seen && true_event_seen) |
132 return; // Successful test!!! | 148 return; // Successful test!!! |
133 } | 149 } |
134 // Very surprising to get here. Probability should be around 1 in 2 ** 250. | 150 // Very surprising to get here. Probability should be around 1 in 2 ** 250. |
135 // One of the following will fail. | 151 // One of the following will fail. |
136 EXPECT_TRUE(false_event_seen); | 152 EXPECT_TRUE(false_event_seen); |
137 EXPECT_TRUE(true_event_seen); | 153 EXPECT_TRUE(true_event_seen); |
138 } | 154 } |
139 | 155 |
140 TEST_F(FieldTrialTest, OneWinner) { | 156 TEST_F(FieldTrialTest, OneWinner) { |
141 char name[] = "Some name"; | 157 char name[] = "Some name"; |
158 char default_group_name[] = "Default some name"; | |
142 int group_count(10); | 159 int group_count(10); |
143 | 160 |
144 FieldTrial* trial = new FieldTrial(name, group_count); | 161 FieldTrial* trial = |
162 new FieldTrial(name, group_count, default_group_name, 2011, 12, 31); | |
145 int winner_index(-2); | 163 int winner_index(-2); |
146 std::string winner_name; | 164 std::string winner_name; |
147 | 165 |
148 for (int i = 1; i <= group_count; ++i) { | 166 for (int i = 1; i <= group_count; ++i) { |
149 int might_win = trial->AppendGroup("", 1); | 167 int might_win = trial->AppendGroup("", 1); |
150 | 168 |
151 if (trial->group() == might_win) { | 169 // Because we keep appending groups, we want to see if the last group that |
170 // was added has been assigned or not. | |
171 if (trial->group_ == might_win) { | |
152 EXPECT_EQ(-2, winner_index); | 172 EXPECT_EQ(-2, winner_index); |
153 winner_index = might_win; | 173 winner_index = might_win; |
154 StringAppendF(&winner_name, "%d", might_win); | 174 StringAppendF(&winner_name, "%d", might_win); |
155 EXPECT_EQ(winner_name, trial->group_name()); | 175 EXPECT_EQ(winner_name, trial->group_name()); |
156 } | 176 } |
157 } | 177 } |
158 EXPECT_GE(winner_index, 0); | 178 EXPECT_GE(winner_index, 0); |
159 EXPECT_EQ(trial->group(), winner_index); | 179 EXPECT_EQ(trial->group(), winner_index); |
160 EXPECT_EQ(trial->group_name(), winner_name); | 180 EXPECT_EQ(trial->group_name(), winner_name); |
161 } | 181 } |
162 | 182 |
183 TEST_F(FieldTrialTest, DisableProbability) { | |
184 const std::string default_group_name = "Default group"; | |
185 const std::string loser = "Loser"; | |
186 const std::string name = "Trial"; | |
187 | |
188 // Create a field trail that has expired. | |
189 scoped_refptr<FieldTrial> trial; | |
190 trial = new FieldTrial(name, 1000000000, default_group_name, 2011, 1, 1); | |
191 trial->AppendGroup(loser, 999999999); // 99.9999999% chance of being chosen. | |
192 | |
193 // Because trial has expired, we should always be in the default group. | |
194 EXPECT_EQ(FieldTrial::kDefaultGroupNumber, trial->group()); | |
195 | |
196 // And that default_group_name should ALWAYS win. | |
197 EXPECT_EQ(default_group_name, trial->group_name()); | |
198 } | |
199 | |
163 TEST_F(FieldTrialTest, Save) { | 200 TEST_F(FieldTrialTest, Save) { |
164 std::string save_string; | 201 std::string save_string; |
165 | 202 |
166 FieldTrial* trial = new FieldTrial("Some name", 10); | 203 FieldTrial* trial = |
204 new FieldTrial("Some name", 10, "Default some name", 2011, 12, 31); | |
167 // There is no winner yet, so no textual group name is associated with trial. | 205 // There is no winner yet, so no textual group name is associated with trial. |
168 EXPECT_EQ("", trial->group_name()); | 206 EXPECT_EQ("", trial->group_name()); |
169 FieldTrialList::StatesToString(&save_string); | 207 FieldTrialList::StatesToString(&save_string); |
170 EXPECT_EQ("", save_string); | 208 EXPECT_EQ("", save_string); |
171 save_string.clear(); | 209 save_string.clear(); |
172 | 210 |
173 // Create a winning group. | 211 // Create a winning group. |
174 trial->AppendGroup("Winner", 10); | 212 trial->AppendGroup("Winner", 10); |
175 FieldTrialList::StatesToString(&save_string); | 213 FieldTrialList::StatesToString(&save_string); |
176 EXPECT_EQ("Some name/Winner/", save_string); | 214 EXPECT_EQ("Some name/Winner/", save_string); |
177 save_string.clear(); | 215 save_string.clear(); |
178 | 216 |
179 // Create a second trial and winning group. | 217 // Create a second trial and winning group. |
180 FieldTrial* trial2 = new FieldTrial("xxx", 10); | 218 FieldTrial* trial2 = |
219 new FieldTrial("xxx", 10, "Default xxx", 2011, 12, 31); | |
181 trial2->AppendGroup("yyyy", 10); | 220 trial2->AppendGroup("yyyy", 10); |
182 | 221 |
183 FieldTrialList::StatesToString(&save_string); | 222 FieldTrialList::StatesToString(&save_string); |
184 // We assume names are alphabetized... though this is not critical. | 223 // We assume names are alphabetized... though this is not critical. |
185 EXPECT_EQ("Some name/Winner/xxx/yyyy/", save_string); | 224 EXPECT_EQ("Some name/Winner/xxx/yyyy/", save_string); |
186 } | 225 } |
187 | 226 |
188 TEST_F(FieldTrialTest, Restore) { | 227 TEST_F(FieldTrialTest, Restore) { |
189 EXPECT_TRUE(FieldTrialList::Find("Some_name") == NULL); | 228 EXPECT_TRUE(FieldTrialList::Find("Some_name") == NULL); |
190 EXPECT_TRUE(FieldTrialList::Find("xxx") == NULL); | 229 EXPECT_TRUE(FieldTrialList::Find("xxx") == NULL); |
(...skipping 12 matching lines...) Expand all Loading... | |
203 } | 242 } |
204 | 243 |
205 TEST_F(FieldTrialTest, BogusRestore) { | 244 TEST_F(FieldTrialTest, BogusRestore) { |
206 EXPECT_FALSE(FieldTrialList::StringAugmentsState("MissingSlash")); | 245 EXPECT_FALSE(FieldTrialList::StringAugmentsState("MissingSlash")); |
207 EXPECT_FALSE(FieldTrialList::StringAugmentsState("MissingGroupName/")); | 246 EXPECT_FALSE(FieldTrialList::StringAugmentsState("MissingGroupName/")); |
208 EXPECT_FALSE(FieldTrialList::StringAugmentsState("MissingFinalSlash/gname")); | 247 EXPECT_FALSE(FieldTrialList::StringAugmentsState("MissingFinalSlash/gname")); |
209 EXPECT_FALSE(FieldTrialList::StringAugmentsState("/noname, only group/")); | 248 EXPECT_FALSE(FieldTrialList::StringAugmentsState("/noname, only group/")); |
210 } | 249 } |
211 | 250 |
212 TEST_F(FieldTrialTest, DuplicateRestore) { | 251 TEST_F(FieldTrialTest, DuplicateRestore) { |
213 FieldTrial* trial = new FieldTrial("Some name", 10); | 252 FieldTrial* trial = |
253 new FieldTrial("Some name", 10, "Default some name", 2011, 12, 31); | |
214 trial->AppendGroup("Winner", 10); | 254 trial->AppendGroup("Winner", 10); |
215 std::string save_string; | 255 std::string save_string; |
216 FieldTrialList::StatesToString(&save_string); | 256 FieldTrialList::StatesToString(&save_string); |
217 EXPECT_EQ("Some name/Winner/", save_string); | 257 EXPECT_EQ("Some name/Winner/", save_string); |
218 | 258 |
219 // It is OK if we redundantly specify a winner. | 259 // It is OK if we redundantly specify a winner. |
220 EXPECT_TRUE(FieldTrialList::StringAugmentsState(save_string)); | 260 EXPECT_TRUE(FieldTrialList::StringAugmentsState(save_string)); |
221 | 261 |
222 // But it is an error to try to change to a different winner. | 262 // But it is an error to try to change to a different winner. |
223 EXPECT_FALSE(FieldTrialList::StringAugmentsState("Some name/Loser/")); | 263 EXPECT_FALSE(FieldTrialList::StringAugmentsState("Some name/Loser/")); |
224 } | 264 } |
225 | 265 |
226 TEST_F(FieldTrialTest, MakeName) { | 266 TEST_F(FieldTrialTest, MakeName) { |
227 FieldTrial* trial = new FieldTrial("Field Trial", 10); | 267 FieldTrial* trial = |
228 trial->AppendGroup("Winner", 10); | 268 new FieldTrial("Field Trial", 10, "Winner", 2011, 12, 31); |
269 trial->group(); | |
229 EXPECT_EQ("Histogram_Winner", | 270 EXPECT_EQ("Histogram_Winner", |
230 FieldTrial::MakeName("Histogram", "Field Trial")); | 271 FieldTrial::MakeName("Histogram", "Field Trial")); |
231 } | 272 } |
232 | 273 |
233 } // namespace base | 274 } // namespace base |
OLD | NEW |