• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
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/test/scoped_feature_list.h"
6 
7 #include <map>
8 #include <string>
9 #include <utility>
10 
11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/field_trial_params.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace base {
16 namespace test {
17 
18 namespace {
19 
20 BASE_FEATURE(kTestFeature1, "TestFeature1", FEATURE_DISABLED_BY_DEFAULT);
21 BASE_FEATURE(kTestFeature2, "TestFeature2", FEATURE_DISABLED_BY_DEFAULT);
22 
ExpectFeatures(const std::string & enabled_features,const std::string & disabled_features)23 void ExpectFeatures(const std::string& enabled_features,
24                     const std::string& disabled_features) {
25   FeatureList* list = FeatureList::GetInstance();
26   std::string actual_enabled_features;
27   std::string actual_disabled_features;
28 
29   list->GetFeatureOverrides(&actual_enabled_features,
30                             &actual_disabled_features);
31 
32   EXPECT_EQ(enabled_features, actual_enabled_features);
33   EXPECT_EQ(disabled_features, actual_disabled_features);
34 }
35 
GetActiveFieldTrialGroupName(const std::string trial_name)36 std::string GetActiveFieldTrialGroupName(const std::string trial_name) {
37   FieldTrial::ActiveGroups groups;
38   FieldTrialList::GetActiveFieldTrialGroups(&groups);
39   for (const auto& group : groups) {
40     if (group.trial_name == trial_name)
41       return group.group_name;
42   }
43   return std::string();
44 }
45 
46 }  // namespace
47 
48 class ScopedFeatureListTest : public testing::Test {
49  public:
ScopedFeatureListTest()50   ScopedFeatureListTest() {
51     // Clear default feature list.
52     std::unique_ptr<FeatureList> feature_list(new FeatureList);
53     feature_list->InitializeFromCommandLine(std::string(), std::string());
54     original_feature_list_ = FeatureList::ClearInstanceForTesting();
55     FeatureList::SetInstance(std::move(feature_list));
56   }
57 
58   ScopedFeatureListTest(const ScopedFeatureListTest&) = delete;
59   ScopedFeatureListTest& operator=(const ScopedFeatureListTest&) = delete;
60 
~ScopedFeatureListTest()61   ~ScopedFeatureListTest() override {
62     // Restore feature list.
63     if (original_feature_list_) {
64       FeatureList::ClearInstanceForTesting();
65       FeatureList::RestoreInstanceForTesting(std::move(original_feature_list_));
66     }
67   }
68 
69  private:
70   // Save the present FeatureList and restore it after test finish.
71   std::unique_ptr<FeatureList> original_feature_list_;
72 };
73 
TEST_F(ScopedFeatureListTest,BasicScoped)74 TEST_F(ScopedFeatureListTest, BasicScoped) {
75   ExpectFeatures(std::string(), std::string());
76   EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature1));
77   {
78     test::ScopedFeatureList feature_list1;
79     feature_list1.InitFromCommandLine("TestFeature1", std::string());
80     ExpectFeatures("TestFeature1", std::string());
81     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
82   }
83   ExpectFeatures(std::string(), std::string());
84   EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature1));
85 }
86 
TEST_F(ScopedFeatureListTest,InitFromCommandLineWithFeatureParams)87 TEST_F(ScopedFeatureListTest, InitFromCommandLineWithFeatureParams) {
88   const std::map<std::string, std::string> feature_params1 = {{"x", "uma"},
89                                                               {"y", "ukm"}};
90   const std::map<std::string, std::string> feature_params2 = {{"x", "ukm"},
91                                                               {"y", "uma"}};
92 
93   test::ScopedFeatureList feature_list1;
94   feature_list1.InitFromCommandLine("TestFeature1<foo.bar:x/uma/y/ukm", "");
95 
96   // Check initial state. Field trial and parameters should be set correctly.
97   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
98   FieldTrial::ActiveGroups active_groups;
99   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
100   EXPECT_EQ(1u, active_groups.size());
101   FieldTrial* original_field_trial =
102       FieldTrialList::Find(active_groups[0].trial_name);
103   std::map<std::string, std::string> actualParams;
104   EXPECT_TRUE(GetFieldTrialParamsByFeature(kTestFeature1, &actualParams));
105   EXPECT_EQ(feature_params1, actualParams);
106 
107   {
108     // Override feature with existing field trial.
109     test::ScopedFeatureList feature_list2;
110 
111     feature_list2.InitAndEnableFeatureWithParameters(kTestFeature1,
112                                                      feature_params2);
113     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
114     EXPECT_NE(original_field_trial, FeatureList::GetFieldTrial(kTestFeature1));
115     actualParams.clear();
116     EXPECT_TRUE(GetFieldTrialParamsByFeature(kTestFeature1, &actualParams));
117     EXPECT_EQ(feature_params2, actualParams);
118     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
119   }
120 
121   // Check that initial state is restored.
122   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
123   active_groups.clear();
124   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
125   EXPECT_EQ(1u, active_groups.size());
126   EXPECT_EQ(original_field_trial, FeatureList::GetFieldTrial(kTestFeature1));
127   actualParams.clear();
128   EXPECT_TRUE(GetFieldTrialParamsByFeature(kTestFeature1, &actualParams));
129   EXPECT_EQ(feature_params1, actualParams);
130 }
131 
TEST_F(ScopedFeatureListTest,EnableWithFeatureParameters)132 TEST_F(ScopedFeatureListTest, EnableWithFeatureParameters) {
133   const char kParam1[] = "param_1";
134   const char kParam2[] = "param_2";
135   const char kValue1[] = "value_1";
136   const char kValue2[] = "value_2";
137   std::map<std::string, std::string> parameters;
138   parameters[kParam1] = kValue1;
139   parameters[kParam2] = kValue2;
140 
141   ExpectFeatures(std::string(), std::string());
142   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
143   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
144   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
145   FieldTrial::ActiveGroups active_groups;
146   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
147   EXPECT_EQ(0u, active_groups.size());
148 
149   {
150     test::ScopedFeatureList feature_list;
151 
152     feature_list.InitAndEnableFeatureWithParameters(kTestFeature1, parameters);
153     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
154     EXPECT_EQ(kValue1,
155               GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
156     EXPECT_EQ(kValue2,
157               GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
158     active_groups.clear();
159     FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
160     EXPECT_EQ(1u, active_groups.size());
161   }
162 
163   ExpectFeatures(std::string(), std::string());
164   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
165   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
166   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
167   active_groups.clear();
168   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
169   EXPECT_EQ(0u, active_groups.size());
170 }
171 
TEST_F(ScopedFeatureListTest,OverrideWithFeatureParameters)172 TEST_F(ScopedFeatureListTest, OverrideWithFeatureParameters) {
173   scoped_refptr<FieldTrial> trial =
174       FieldTrialList::CreateFieldTrial("foo", "bar");
175   const char kParam[] = "param_1";
176   const char kValue[] = "value_1";
177   const char kValue0[] = "value_0";
178   std::map<std::string, std::string> parameters;
179   parameters[kParam] = kValue;
180 
181   test::ScopedFeatureList feature_list1;
182   feature_list1.InitFromCommandLine(
183       "TestFeature1<foo.bar:param_1/value_0,TestFeature2", std::string());
184 
185   // Check initial state.
186   ExpectFeatures("TestFeature1<foo,TestFeature2", std::string());
187   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
188   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
189   // ScopedFeatureList always scope features, field trials and their associated
190   // parameters. So ScopedFeatureList::InitFromCommandLine() creates another
191   // FieldTrial instance whose trial name, group name and associated parameters
192   // are the same as |trial|, and changes |kTestFeature1|'s field trial to
193   // be the newly created one.
194   EXPECT_NE(trial.get(), FeatureList::GetFieldTrial(kTestFeature1));
195   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
196   EXPECT_EQ(kValue0, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
197   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
198   EXPECT_EQ("bar", GetActiveFieldTrialGroupName("foo"));
199 
200   FieldTrial* trial_for_test_feature1 =
201       FeatureList::GetFieldTrial(kTestFeature1);
202   EXPECT_EQ("foo", trial_for_test_feature1->trial_name());
203   EXPECT_EQ("bar", trial_for_test_feature1->group_name());
204 
205   {
206     // Override feature with existing field trial.
207     test::ScopedFeatureList feature_list2;
208 
209     feature_list2.InitAndEnableFeatureWithParameters(kTestFeature1, parameters);
210     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
211     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
212     EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
213     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
214     EXPECT_NE(trial.get(), FeatureList::GetFieldTrial(kTestFeature1));
215     EXPECT_NE(trial_for_test_feature1,
216               FeatureList::GetFieldTrial(kTestFeature1));
217     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
218     EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
219   }
220 
221   {
222     // Override feature with existing field trial.
223     test::ScopedFeatureList feature_list2;
224 
225     feature_list2.InitFromCommandLine("TestFeature1<foo.bar2:param_1/value_1",
226                                       std::string());
227     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
228     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
229     EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
230     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
231     EXPECT_NE(trial.get(), FeatureList::GetFieldTrial(kTestFeature1));
232     EXPECT_NE(trial_for_test_feature1,
233               FeatureList::GetFieldTrial(kTestFeature1));
234     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
235     EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
236 
237     // foo's active group is now bar2, not bar.
238     EXPECT_TRUE(FieldTrialList::IsTrialActive("foo"));
239     EXPECT_EQ("bar2", GetActiveFieldTrialGroupName("foo"));
240   }
241 
242   // Check that initial state is restored.
243   ExpectFeatures("TestFeature1<foo,TestFeature2", std::string());
244   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
245   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
246   EXPECT_EQ(trial_for_test_feature1, FeatureList::GetFieldTrial(kTestFeature1));
247   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
248   EXPECT_EQ(kValue0, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
249   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
250   // foo's active group is bar, because initial state is restored.
251   EXPECT_EQ("bar", GetActiveFieldTrialGroupName("foo"));
252 
253   {
254     // Override feature with no existing field trial.
255     test::ScopedFeatureList feature_list2;
256 
257     feature_list2.InitAndEnableFeatureWithParameters(kTestFeature2, parameters);
258     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
259     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
260     EXPECT_EQ(kValue0, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
261     EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
262     EXPECT_EQ(trial_for_test_feature1->trial_name(),
263               FeatureList::GetFieldTrial(kTestFeature1)->trial_name());
264     EXPECT_EQ(trial_for_test_feature1->group_name(),
265               FeatureList::GetFieldTrial(kTestFeature1)->group_name());
266     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
267   }
268 
269   // Check that initial state is restored.
270   ExpectFeatures("TestFeature1<foo,TestFeature2", std::string());
271   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
272   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
273   EXPECT_EQ(trial_for_test_feature1, FeatureList::GetFieldTrial(kTestFeature1));
274   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
275   EXPECT_EQ(kValue0, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
276   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
277 }
278 
TEST_F(ScopedFeatureListTest,OverrideWithFeatureMultipleParameters)279 TEST_F(ScopedFeatureListTest, OverrideWithFeatureMultipleParameters) {
280   const char kParam1[] = "param_1";
281   const char kValue1[] = "value_1";
282   const char kParam2[] = "param_2";
283   const char kValue2[] = "value_2";
284   const char kValue3[] = "value_3";
285   std::map<std::string, std::string> parameters;
286   parameters[kParam1] = kValue3;
287 
288   test::ScopedFeatureList feature_list1;
289   feature_list1.InitFromCommandLine(
290       "TestFeature1<foo.bar:param_1/value_1/param_2/"
291       "value_2,TestFeature2:param_1/value_2",
292       std::string());
293 
294   // Check initial state.
295   ExpectFeatures("TestFeature1<foo,TestFeature2<StudyTestFeature2",
296                  std::string());
297   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
298   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
299   EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
300   EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
301   EXPECT_EQ(kValue1, GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
302   EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
303   EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature2, kParam1));
304   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam2));
305 
306   FieldTrial* trial = FieldTrialList::Find("foo");
307   EXPECT_EQ("bar", trial->GetGroupNameWithoutActivation());
308   EXPECT_EQ("bar", GetActiveFieldTrialGroupName("foo"));
309 
310   FieldTrial* trial2 = FieldTrialList::Find("StudyTestFeature2");
311   EXPECT_EQ("GroupTestFeature2", trial2->GetGroupNameWithoutActivation());
312   EXPECT_EQ("GroupTestFeature2",
313             GetActiveFieldTrialGroupName("StudyTestFeature2"));
314 
315   {
316     // Override feature with existing field trial.
317     test::ScopedFeatureList feature_list2;
318 
319     feature_list2.InitAndEnableFeatureWithParameters(kTestFeature1, parameters);
320     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
321     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
322     EXPECT_EQ(kValue3,
323               GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
324     // param_2 is not set.
325     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
326     EXPECT_EQ(kValue2,
327               GetFieldTrialParamValueByFeature(kTestFeature2, kParam1));
328     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam2));
329     EXPECT_NE(trial, FeatureList::GetFieldTrial(kTestFeature1));
330     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
331     EXPECT_NE(trial2, FeatureList::GetFieldTrial(kTestFeature2));
332     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
333   }
334 
335   // Check that initial state is restored.
336   ExpectFeatures("TestFeature1<foo,TestFeature2<StudyTestFeature2",
337                  std::string());
338   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
339   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
340   EXPECT_EQ(trial, FeatureList::GetFieldTrial(kTestFeature1));
341   EXPECT_EQ(trial2, FeatureList::GetFieldTrial(kTestFeature2));
342   EXPECT_EQ(kValue1, GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
343   EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
344   EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature2, kParam1));
345   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam2));
346   // foo's active group is bar, because initial state is restored.
347   EXPECT_EQ("bar", GetActiveFieldTrialGroupName("foo"));
348   EXPECT_EQ("GroupTestFeature2",
349             GetActiveFieldTrialGroupName("StudyTestFeature2"));
350 
351   {
352     // Override feature with existing field trial.
353     test::ScopedFeatureList feature_list2;
354 
355     feature_list2.InitFromCommandLine("TestFeature1<foo.bar2:param_2/value_3",
356                                       std::string());
357     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
358     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
359     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
360     EXPECT_EQ(kValue3,
361               GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
362     EXPECT_EQ(kValue2,
363               GetFieldTrialParamValueByFeature(kTestFeature2, kParam1));
364     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam2));
365     EXPECT_NE(trial, FeatureList::GetFieldTrial(kTestFeature1));
366     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature1));
367     EXPECT_EQ("foo", FeatureList::GetFieldTrial(kTestFeature1)->trial_name());
368     EXPECT_EQ("bar2", FeatureList::GetFieldTrial(kTestFeature1)->group_name());
369     EXPECT_NE(trial2, FeatureList::GetFieldTrial(kTestFeature2));
370     EXPECT_NE(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
371 
372     // foo's active group is now bar2, not bar.
373     EXPECT_TRUE(FieldTrialList::IsTrialActive("foo"));
374     EXPECT_EQ("bar2", GetActiveFieldTrialGroupName("foo"));
375   }
376 
377   // Check that initial state is restored.
378   ExpectFeatures("TestFeature1<foo,TestFeature2<StudyTestFeature2",
379                  std::string());
380   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
381   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
382   EXPECT_EQ(trial, FeatureList::GetFieldTrial(kTestFeature1));
383   EXPECT_EQ(trial2, FeatureList::GetFieldTrial(kTestFeature2));
384   EXPECT_EQ(kValue1, GetFieldTrialParamValueByFeature(kTestFeature1, kParam1));
385   EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature1, kParam2));
386   EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature2, kParam1));
387   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam2));
388   EXPECT_EQ("bar", GetActiveFieldTrialGroupName("foo"));
389 }
390 
TEST_F(ScopedFeatureListTest,OverrideMultipleFeaturesWithParameters)391 TEST_F(ScopedFeatureListTest, OverrideMultipleFeaturesWithParameters) {
392   scoped_refptr<FieldTrial> trial1 =
393       FieldTrialList::CreateFieldTrial("foo1", "bar1");
394   const char kParam[] = "param_1";
395   const char kValue0[] = "value_0";
396   const char kValue1[] = "value_1";
397   const char kValue2[] = "value_2";
398   std::map<std::string, std::string> parameters1;
399   parameters1[kParam] = kValue1;
400   std::map<std::string, std::string> parameters2;
401   parameters2[kParam] = kValue2;
402 
403   test::ScopedFeatureList feature_list1;
404   feature_list1.InitFromCommandLine(
405       "TestFeature1<foo1:param_1/value_0,TestFeature2", std::string());
406 
407   // Check initial state.
408   ExpectFeatures("TestFeature1<foo1,TestFeature2", std::string());
409   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
410   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
411   EXPECT_EQ("foo1", FeatureList::GetFieldTrial(kTestFeature1)->trial_name());
412   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
413   EXPECT_EQ(kValue0, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
414   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
415 
416   // InitFromCommandLine() scopes field trials.
417   FieldTrial* trial = FieldTrialList::Find("foo1");
418   // --enable-features will create a group whose name is "Group" + feature
419   // name if no group name is specified. In this case, the feature name is
420   // "TestFeature1". So the group name is "GroupTestFeature1".
421   EXPECT_EQ("GroupTestFeature1", trial->GetGroupNameWithoutActivation());
422   EXPECT_NE(trial1.get(), trial);
423   // Because of "scoped", "bar1" disappears. Instead, "GroupTestFeature1"
424   // is created and activated.
425   EXPECT_NE("bar1", GetActiveFieldTrialGroupName("foo1"));
426   EXPECT_EQ("GroupTestFeature1", GetActiveFieldTrialGroupName("foo1"));
427 
428   {
429     // Override multiple features with parameters.
430     test::ScopedFeatureList feature_list2;
431     feature_list2.InitWithFeaturesAndParameters(
432         {{kTestFeature1, parameters1}, {kTestFeature2, parameters2}}, {});
433 
434     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
435     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
436     EXPECT_EQ(kValue1, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
437     EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
438   }
439 
440   {
441     // Override a feature with a parameter and disable another one.
442     test::ScopedFeatureList feature_list2;
443     feature_list2.InitWithFeaturesAndParameters({{kTestFeature1, parameters2}},
444                                                 {kTestFeature2});
445 
446     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
447     EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature2));
448     EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
449     EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
450   }
451 
452   // Check that initial state is restored.
453   ExpectFeatures("TestFeature1<foo1,TestFeature2", std::string());
454   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
455   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature2));
456   EXPECT_EQ(trial, FeatureList::GetFieldTrial(kTestFeature1));
457   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kTestFeature2));
458   EXPECT_EQ(kValue0, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
459   EXPECT_EQ("", GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
460 }
461 
TEST_F(ScopedFeatureListTest,ParamsWithSpecialCharsPreserved)462 TEST_F(ScopedFeatureListTest, ParamsWithSpecialCharsPreserved) {
463   // Check that special characters in param names and values are preserved.
464   const char kParam[] = ";_\\<:>/_!?";
465   const char kValue[] = ",;:/'!?";
466   FieldTrialParams params0 = {{kParam, kValue}};
467 
468   test::ScopedFeatureList feature_list0;
469   feature_list0.InitWithFeaturesAndParameters({{kTestFeature1, params0}}, {});
470   EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
471 
472   {
473     const char kValue1[] = "normal";
474     FieldTrialParams params1 = {{kParam, kValue1}};
475     test::ScopedFeatureList feature_list1;
476     feature_list1.InitWithFeaturesAndParameters({{kTestFeature1, params1}}, {});
477 
478     EXPECT_EQ(kValue1, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
479   }
480   EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
481 
482   {
483     const char kValue2[] = "[<(2)>]";
484     FieldTrialParams params2 = {{kParam, kValue2}};
485     test::ScopedFeatureList feature_list2;
486     feature_list2.InitWithFeaturesAndParameters({{kTestFeature2, params2}}, {});
487 
488     EXPECT_EQ(kValue2, GetFieldTrialParamValueByFeature(kTestFeature2, kParam));
489     EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
490   }
491   EXPECT_EQ(kValue, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
492 }
493 
TEST_F(ScopedFeatureListTest,ParamsWithEmptyValue)494 TEST_F(ScopedFeatureListTest, ParamsWithEmptyValue) {
495   const char kParam[] = "p";
496   const char kEmptyValue[] = "";
497   FieldTrialParams params = {{kParam, kEmptyValue}};
498 
499   test::ScopedFeatureList feature_list0;
500   feature_list0.InitWithFeaturesAndParameters({{kTestFeature1, params}}, {});
501   EXPECT_EQ(kEmptyValue,
502             GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
503   {
504     const char kValue1[] = "normal";
505     FieldTrialParams params1 = {{kParam, kValue1}};
506     test::ScopedFeatureList feature_list1;
507     feature_list1.InitWithFeaturesAndParameters({{kTestFeature1, params1}}, {});
508 
509     EXPECT_EQ(kValue1, GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
510   }
511   EXPECT_EQ(kEmptyValue,
512             GetFieldTrialParamValueByFeature(kTestFeature1, kParam));
513 }
514 
TEST_F(ScopedFeatureListTest,EnableFeatureOverrideDisable)515 TEST_F(ScopedFeatureListTest, EnableFeatureOverrideDisable) {
516   test::ScopedFeatureList feature_list1;
517   feature_list1.InitWithFeatures({}, {kTestFeature1});
518 
519   {
520     test::ScopedFeatureList feature_list2;
521     feature_list2.InitWithFeatures({kTestFeature1}, {});
522     ExpectFeatures("TestFeature1", std::string());
523   }
524 }
525 
TEST_F(ScopedFeatureListTest,FeatureOverrideNotMakeDuplicate)526 TEST_F(ScopedFeatureListTest, FeatureOverrideNotMakeDuplicate) {
527   test::ScopedFeatureList feature_list1;
528   feature_list1.InitWithFeatures({}, {kTestFeature1});
529 
530   {
531     test::ScopedFeatureList feature_list2;
532     feature_list2.InitWithFeatures({}, {kTestFeature1});
533     ExpectFeatures(std::string(), "TestFeature1");
534   }
535 }
536 
TEST_F(ScopedFeatureListTest,FeatureOverrideFeatureWithDefault)537 TEST_F(ScopedFeatureListTest, FeatureOverrideFeatureWithDefault) {
538   test::ScopedFeatureList feature_list1;
539   feature_list1.InitFromCommandLine("*TestFeature1", std::string());
540 
541   {
542     test::ScopedFeatureList feature_list2;
543     feature_list2.InitWithFeatures({kTestFeature1}, {});
544     ExpectFeatures("TestFeature1", std::string());
545   }
546 }
547 
TEST_F(ScopedFeatureListTest,FeatureOverrideFeatureWithDefault2)548 TEST_F(ScopedFeatureListTest, FeatureOverrideFeatureWithDefault2) {
549   test::ScopedFeatureList feature_list1;
550   feature_list1.InitFromCommandLine("*TestFeature1", std::string());
551 
552   {
553     test::ScopedFeatureList feature_list2;
554     feature_list2.InitWithFeatures({}, {kTestFeature1});
555     ExpectFeatures(std::string(), "TestFeature1");
556   }
557 }
558 
TEST_F(ScopedFeatureListTest,FeatureOverrideFeatureWithEnabledFieldTrial)559 TEST_F(ScopedFeatureListTest, FeatureOverrideFeatureWithEnabledFieldTrial) {
560   test::ScopedFeatureList feature_list1;
561 
562   std::unique_ptr<FeatureList> feature_list(new FeatureList);
563   FieldTrial* trial = FieldTrialList::CreateFieldTrial("TrialExample", "A");
564   feature_list->RegisterFieldTrialOverride(
565       kTestFeature1.name, FeatureList::OVERRIDE_ENABLE_FEATURE, trial);
566   feature_list1.InitWithFeatureList(std::move(feature_list));
567 
568   {
569     test::ScopedFeatureList feature_list2;
570     feature_list2.InitWithFeatures({kTestFeature1}, {});
571     ExpectFeatures("TestFeature1", std::string());
572   }
573 }
574 
TEST_F(ScopedFeatureListTest,FeatureOverrideFeatureWithDisabledFieldTrial)575 TEST_F(ScopedFeatureListTest, FeatureOverrideFeatureWithDisabledFieldTrial) {
576   test::ScopedFeatureList feature_list1;
577 
578   std::unique_ptr<FeatureList> feature_list(new FeatureList);
579   FieldTrial* trial = FieldTrialList::CreateFieldTrial("TrialExample", "A");
580   feature_list->RegisterFieldTrialOverride(
581       kTestFeature1.name, FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
582   feature_list1.InitWithFeatureList(std::move(feature_list));
583 
584   {
585     test::ScopedFeatureList feature_list2;
586     feature_list2.InitWithFeatures({kTestFeature1}, {});
587     ExpectFeatures("TestFeature1", std::string());
588   }
589 }
590 
TEST_F(ScopedFeatureListTest,FeatureOverrideKeepsOtherExistingFeature)591 TEST_F(ScopedFeatureListTest, FeatureOverrideKeepsOtherExistingFeature) {
592   test::ScopedFeatureList feature_list1;
593   feature_list1.InitWithFeatures({}, {kTestFeature1});
594 
595   {
596     test::ScopedFeatureList feature_list2;
597     feature_list2.InitWithFeatures({}, {kTestFeature2});
598     EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature1));
599     EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature2));
600   }
601 }
602 
TEST_F(ScopedFeatureListTest,FeatureOverrideKeepsOtherExistingFeature2)603 TEST_F(ScopedFeatureListTest, FeatureOverrideKeepsOtherExistingFeature2) {
604   test::ScopedFeatureList feature_list1;
605   feature_list1.InitWithFeatures({}, {kTestFeature1});
606 
607   {
608     test::ScopedFeatureList feature_list2;
609     feature_list2.InitWithFeatures({kTestFeature2}, {});
610     ExpectFeatures("TestFeature2", "TestFeature1");
611   }
612 }
613 
TEST_F(ScopedFeatureListTest,FeatureOverrideKeepsOtherExistingDefaultFeature)614 TEST_F(ScopedFeatureListTest, FeatureOverrideKeepsOtherExistingDefaultFeature) {
615   test::ScopedFeatureList feature_list1;
616   feature_list1.InitFromCommandLine("*TestFeature1", std::string());
617 
618   {
619     test::ScopedFeatureList feature_list2;
620     feature_list2.InitWithFeatures({}, {kTestFeature2});
621     ExpectFeatures("*TestFeature1", "TestFeature2");
622   }
623 }
624 
TEST_F(ScopedFeatureListTest,ScopedFeatureListIsNoopWhenNotInitialized)625 TEST_F(ScopedFeatureListTest, ScopedFeatureListIsNoopWhenNotInitialized) {
626   test::ScopedFeatureList feature_list1;
627   feature_list1.InitFromCommandLine("*TestFeature1", std::string());
628 
629   // A ScopedFeatureList on which Init() is not called should not reset things
630   // when going out of scope.
631   { test::ScopedFeatureList feature_list2; }
632 
633   ExpectFeatures("*TestFeature1", std::string());
634 }
635 
TEST_F(ScopedFeatureListTest,RestoreFieldTrialParamsCorrectlyWhenLeakedFieldTrialCreated)636 TEST_F(ScopedFeatureListTest,
637        RestoreFieldTrialParamsCorrectlyWhenLeakedFieldTrialCreated) {
638   test::ScopedFeatureList feature_list1;
639   feature_list1.InitFromCommandLine("TestFeature1:TestParam/TestValue1", "");
640   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
641   EXPECT_EQ("TestValue1",
642             GetFieldTrialParamValueByFeature(kTestFeature1, "TestParam"));
643 
644   // content::InitializeFieldTrialAndFeatureList() creates a leaked
645   // FieldTrialList. To emulate the leaked one, declare
646   // unique_ptr<FieldTriaList> here and initialize it inside the following
647   // child scope.
648   std::unique_ptr<FieldTrialList> leaked_field_trial_list;
649   {
650     test::ScopedFeatureList feature_list2;
651     feature_list2.InitWithNullFeatureAndFieldTrialLists();
652 
653     leaked_field_trial_list = std::make_unique<FieldTrialList>();
654     FeatureList::InitializeInstance("TestFeature1:TestParam/TestValue2", "",
655                                     {});
656     EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
657     EXPECT_EQ("TestValue2",
658               GetFieldTrialParamValueByFeature(kTestFeature1, "TestParam"));
659   }
660   EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1));
661   EXPECT_EQ("TestValue1",
662             GetFieldTrialParamValueByFeature(kTestFeature1, "TestParam"));
663 
664   {
665     FieldTrialList* backup_field_trial =
666         FieldTrialList::BackupInstanceForTesting();
667 
668     // To free leaked_field_trial_list, need RestoreInstanceForTesting()
669     // to pass DCHECK_EQ(this, global_) at ~FieldTrialList().
670     FieldTrialList::RestoreInstanceForTesting(leaked_field_trial_list.get());
671     leaked_field_trial_list.reset();
672     FieldTrialList::RestoreInstanceForTesting(backup_field_trial);
673   }
674 }
675 
TEST(ScopedFeatureListTestWithMemberList,ScopedFeatureListLocalOverride)676 TEST(ScopedFeatureListTestWithMemberList, ScopedFeatureListLocalOverride) {
677   test::ScopedFeatureList initial_feature_list;
678   initial_feature_list.InitAndDisableFeature(kTestFeature1);
679   {
680     base::test::ScopedFeatureList scoped_features;
681     scoped_features.InitAndEnableFeatureWithParameters(kTestFeature1,
682                                                        {{"mode", "nobugs"}});
683     ASSERT_TRUE(FeatureList::IsEnabled(kTestFeature1));
684   }
685 }
686 
687 }  // namespace test
688 }  // namespace base
689