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