• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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/feature_list.h"
6 
7 #include <stddef.h>
8 
9 #include <algorithm>
10 #include <utility>
11 
12 #include "base/format_macros.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/metrics/field_trial.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 
20 namespace base {
21 
22 namespace {
23 
24 const char kFeatureOnByDefaultName[] = "OnByDefault";
25 struct Feature kFeatureOnByDefault {
26   kFeatureOnByDefaultName, FEATURE_ENABLED_BY_DEFAULT
27 };
28 
29 const char kFeatureOffByDefaultName[] = "OffByDefault";
30 struct Feature kFeatureOffByDefault {
31   kFeatureOffByDefaultName, FEATURE_DISABLED_BY_DEFAULT
32 };
33 
SortFeatureListString(const std::string & feature_list)34 std::string SortFeatureListString(const std::string& feature_list) {
35   std::vector<std::string> features =
36       FeatureList::SplitFeatureListString(feature_list);
37   std::sort(features.begin(), features.end());
38   return JoinString(features, ",");
39 }
40 
41 }  // namespace
42 
43 class FeatureListTest : public testing::Test {
44  public:
FeatureListTest()45   FeatureListTest() : feature_list_(nullptr) {
46     RegisterFeatureListInstance(WrapUnique(new FeatureList));
47   }
~FeatureListTest()48   ~FeatureListTest() override { ClearFeatureListInstance(); }
49 
RegisterFeatureListInstance(std::unique_ptr<FeatureList> feature_list)50   void RegisterFeatureListInstance(std::unique_ptr<FeatureList> feature_list) {
51     FeatureList::ClearInstanceForTesting();
52     feature_list_ = feature_list.get();
53     FeatureList::SetInstance(std::move(feature_list));
54   }
ClearFeatureListInstance()55   void ClearFeatureListInstance() {
56     FeatureList::ClearInstanceForTesting();
57     feature_list_ = nullptr;
58   }
59 
feature_list()60   FeatureList* feature_list() { return feature_list_; }
61 
62  private:
63   // Weak. Owned by the FeatureList::SetInstance().
64   FeatureList* feature_list_;
65 
66   DISALLOW_COPY_AND_ASSIGN(FeatureListTest);
67 };
68 
TEST_F(FeatureListTest,DefaultStates)69 TEST_F(FeatureListTest, DefaultStates) {
70   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
71   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
72 }
73 
TEST_F(FeatureListTest,InitializeFromCommandLine)74 TEST_F(FeatureListTest, InitializeFromCommandLine) {
75   struct {
76     const char* enable_features;
77     const char* disable_features;
78     bool expected_feature_on_state;
79     bool expected_feature_off_state;
80   } test_cases[] = {
81       {"", "", true, false},
82       {"OffByDefault", "", true, true},
83       {"OffByDefault", "OnByDefault", false, true},
84       {"OnByDefault,OffByDefault", "", true, true},
85       {"", "OnByDefault,OffByDefault", false, false},
86       // In the case an entry is both, disable takes precedence.
87       {"OnByDefault", "OnByDefault,OffByDefault", false, false},
88   };
89 
90   for (size_t i = 0; i < arraysize(test_cases); ++i) {
91     const auto& test_case = test_cases[i];
92     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: [%s] [%s]", i,
93                                     test_case.enable_features,
94                                     test_case.disable_features));
95 
96     ClearFeatureListInstance();
97     std::unique_ptr<FeatureList> feature_list(new FeatureList);
98     feature_list->InitializeFromCommandLine(test_case.enable_features,
99                                             test_case.disable_features);
100     RegisterFeatureListInstance(std::move(feature_list));
101 
102     EXPECT_EQ(test_case.expected_feature_on_state,
103               FeatureList::IsEnabled(kFeatureOnByDefault))
104         << i;
105     EXPECT_EQ(test_case.expected_feature_off_state,
106               FeatureList::IsEnabled(kFeatureOffByDefault))
107         << i;
108   }
109 }
110 
TEST_F(FeatureListTest,CheckFeatureIdentity)111 TEST_F(FeatureListTest, CheckFeatureIdentity) {
112   // Tests that CheckFeatureIdentity() correctly detects when two different
113   // structs with the same feature name are passed to it.
114 
115   // Call it twice for each feature at the top of the file, since the first call
116   // makes it remember the entry and the second call will verify it.
117   EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOnByDefault));
118   EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOnByDefault));
119   EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOffByDefault));
120   EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOffByDefault));
121 
122   // Now, call it with a distinct struct for |kFeatureOnByDefaultName|, which
123   // should return false.
124   struct Feature kFeatureOnByDefault2 {
125     kFeatureOnByDefaultName, FEATURE_ENABLED_BY_DEFAULT
126   };
127   EXPECT_FALSE(feature_list()->CheckFeatureIdentity(kFeatureOnByDefault2));
128 }
129 
TEST_F(FeatureListTest,FieldTrialOverrides)130 TEST_F(FeatureListTest, FieldTrialOverrides) {
131   struct {
132     FeatureList::OverrideState trial1_state;
133     FeatureList::OverrideState trial2_state;
134   } test_cases[] = {
135       {FeatureList::OVERRIDE_DISABLE_FEATURE,
136        FeatureList::OVERRIDE_DISABLE_FEATURE},
137       {FeatureList::OVERRIDE_DISABLE_FEATURE,
138        FeatureList::OVERRIDE_ENABLE_FEATURE},
139       {FeatureList::OVERRIDE_ENABLE_FEATURE,
140        FeatureList::OVERRIDE_DISABLE_FEATURE},
141       {FeatureList::OVERRIDE_ENABLE_FEATURE,
142        FeatureList::OVERRIDE_ENABLE_FEATURE},
143   };
144 
145   FieldTrial::ActiveGroup active_group;
146   for (size_t i = 0; i < arraysize(test_cases); ++i) {
147     const auto& test_case = test_cases[i];
148     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i));
149 
150     ClearFeatureListInstance();
151 
152     FieldTrialList field_trial_list(nullptr);
153     std::unique_ptr<FeatureList> feature_list(new FeatureList);
154 
155     FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("TrialExample1", "A");
156     FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("TrialExample2", "B");
157     feature_list->RegisterFieldTrialOverride(kFeatureOnByDefaultName,
158                                              test_case.trial1_state, trial1);
159     feature_list->RegisterFieldTrialOverride(kFeatureOffByDefaultName,
160                                              test_case.trial2_state, trial2);
161     RegisterFeatureListInstance(std::move(feature_list));
162 
163     // Initially, neither trial should be active.
164     EXPECT_FALSE(FieldTrialList::IsTrialActive(trial1->trial_name()));
165     EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
166 
167     const bool expected_enabled_1 =
168         (test_case.trial1_state == FeatureList::OVERRIDE_ENABLE_FEATURE);
169     EXPECT_EQ(expected_enabled_1, FeatureList::IsEnabled(kFeatureOnByDefault));
170     // The above should have activated |trial1|.
171     EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
172     EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
173 
174     const bool expected_enabled_2 =
175         (test_case.trial2_state == FeatureList::OVERRIDE_ENABLE_FEATURE);
176     EXPECT_EQ(expected_enabled_2, FeatureList::IsEnabled(kFeatureOffByDefault));
177     // The above should have activated |trial2|.
178     EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
179     EXPECT_TRUE(FieldTrialList::IsTrialActive(trial2->trial_name()));
180   }
181 }
182 
TEST_F(FeatureListTest,FieldTrialAssociateUseDefault)183 TEST_F(FeatureListTest, FieldTrialAssociateUseDefault) {
184   FieldTrialList field_trial_list(nullptr);
185   std::unique_ptr<FeatureList> feature_list(new FeatureList);
186 
187   FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("TrialExample1", "A");
188   FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("TrialExample2", "B");
189   feature_list->RegisterFieldTrialOverride(
190       kFeatureOnByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial1);
191   feature_list->RegisterFieldTrialOverride(
192       kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial2);
193   RegisterFeatureListInstance(std::move(feature_list));
194 
195   // Initially, neither trial should be active.
196   EXPECT_FALSE(FieldTrialList::IsTrialActive(trial1->trial_name()));
197   EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
198 
199   // Check the feature enabled state is its default.
200   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
201   // The above should have activated |trial1|.
202   EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
203   EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
204 
205   // Check the feature enabled state is its default.
206   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
207   // The above should have activated |trial2|.
208   EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
209   EXPECT_TRUE(FieldTrialList::IsTrialActive(trial2->trial_name()));
210 }
211 
TEST_F(FeatureListTest,CommandLineTakesPrecedenceOverFieldTrial)212 TEST_F(FeatureListTest, CommandLineTakesPrecedenceOverFieldTrial) {
213   ClearFeatureListInstance();
214 
215   FieldTrialList field_trial_list(nullptr);
216   std::unique_ptr<FeatureList> feature_list(new FeatureList);
217 
218   // The feature is explicitly enabled on the command-line.
219   feature_list->InitializeFromCommandLine(kFeatureOffByDefaultName, "");
220 
221   // But the FieldTrial would set the feature to disabled.
222   FieldTrial* trial = FieldTrialList::CreateFieldTrial("TrialExample2", "A");
223   feature_list->RegisterFieldTrialOverride(
224       kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
225   RegisterFeatureListInstance(std::move(feature_list));
226 
227   EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
228   // Command-line should take precedence.
229   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
230   // Since the feature is on due to the command-line, and not as a result of the
231   // field trial, the field trial should not be activated (since the Associate*
232   // API wasn't used.)
233   EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
234 }
235 
TEST_F(FeatureListTest,IsFeatureOverriddenFromCommandLine)236 TEST_F(FeatureListTest, IsFeatureOverriddenFromCommandLine) {
237   ClearFeatureListInstance();
238 
239   FieldTrialList field_trial_list(nullptr);
240   std::unique_ptr<FeatureList> feature_list(new FeatureList);
241 
242   // No features are overridden from the command line yet
243   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
244       kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
245   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
246       kFeatureOnByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
247   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
248       kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
249   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
250       kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
251 
252   // Now, enable |kFeatureOffByDefaultName| via the command-line.
253   feature_list->InitializeFromCommandLine(kFeatureOffByDefaultName, "");
254 
255   // It should now be overridden for the enabled group.
256   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
257       kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
258   EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
259       kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
260 
261   // Register a field trial to associate with the feature and ensure that the
262   // results are still the same.
263   feature_list->AssociateReportingFieldTrial(
264       kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE,
265       FieldTrialList::CreateFieldTrial("Trial1", "A"));
266   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
267       kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
268   EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
269       kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
270 
271   // Now, register a field trial to override |kFeatureOnByDefaultName| state
272   // and check that the function still returns false for that feature.
273   feature_list->RegisterFieldTrialOverride(
274       kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE,
275       FieldTrialList::CreateFieldTrial("Trial2", "A"));
276   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
277       kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
278   EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
279       kFeatureOnByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
280   RegisterFeatureListInstance(std::move(feature_list));
281 
282   // Check the expected feature states for good measure.
283   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
284   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
285 }
286 
TEST_F(FeatureListTest,AssociateReportingFieldTrial)287 TEST_F(FeatureListTest, AssociateReportingFieldTrial) {
288   struct {
289     const char* enable_features;
290     const char* disable_features;
291     bool expected_enable_trial_created;
292     bool expected_disable_trial_created;
293   } test_cases[] = {
294       // If no enable/disable flags are specified, no trials should be created.
295       {"", "", false, false},
296       // Enabling the feature should result in the enable trial created.
297       {kFeatureOffByDefaultName, "", true, false},
298       // Disabling the feature should result in the disable trial created.
299       {"", kFeatureOffByDefaultName, false, true},
300   };
301 
302   const char kTrialName[] = "ForcingTrial";
303   const char kForcedOnGroupName[] = "ForcedOn";
304   const char kForcedOffGroupName[] = "ForcedOff";
305 
306   for (size_t i = 0; i < arraysize(test_cases); ++i) {
307     const auto& test_case = test_cases[i];
308     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: [%s] [%s]", i,
309                                     test_case.enable_features,
310                                     test_case.disable_features));
311 
312     ClearFeatureListInstance();
313 
314     FieldTrialList field_trial_list(nullptr);
315     std::unique_ptr<FeatureList> feature_list(new FeatureList);
316     feature_list->InitializeFromCommandLine(test_case.enable_features,
317                                             test_case.disable_features);
318 
319     FieldTrial* enable_trial = nullptr;
320     if (feature_list->IsFeatureOverriddenFromCommandLine(
321             kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE)) {
322       enable_trial = base::FieldTrialList::CreateFieldTrial(kTrialName,
323                                                             kForcedOnGroupName);
324       feature_list->AssociateReportingFieldTrial(
325           kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE,
326           enable_trial);
327     }
328     FieldTrial* disable_trial = nullptr;
329     if (feature_list->IsFeatureOverriddenFromCommandLine(
330             kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE)) {
331       disable_trial = base::FieldTrialList::CreateFieldTrial(
332           kTrialName, kForcedOffGroupName);
333       feature_list->AssociateReportingFieldTrial(
334           kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE,
335           disable_trial);
336     }
337     EXPECT_EQ(test_case.expected_enable_trial_created, enable_trial != nullptr);
338     EXPECT_EQ(test_case.expected_disable_trial_created,
339               disable_trial != nullptr);
340     RegisterFeatureListInstance(std::move(feature_list));
341 
342     EXPECT_FALSE(FieldTrialList::IsTrialActive(kTrialName));
343     if (disable_trial) {
344       EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
345       EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
346       EXPECT_EQ(kForcedOffGroupName, disable_trial->group_name());
347     } else if (enable_trial) {
348       EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
349       EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
350       EXPECT_EQ(kForcedOnGroupName, enable_trial->group_name());
351     }
352   }
353 }
354 
TEST_F(FeatureListTest,GetFeatureOverrides)355 TEST_F(FeatureListTest, GetFeatureOverrides) {
356   ClearFeatureListInstance();
357   FieldTrialList field_trial_list(nullptr);
358   std::unique_ptr<FeatureList> feature_list(new FeatureList);
359   feature_list->InitializeFromCommandLine("A,X", "D");
360 
361   FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
362   feature_list->RegisterFieldTrialOverride(kFeatureOffByDefaultName,
363                                            FeatureList::OVERRIDE_ENABLE_FEATURE,
364                                            trial);
365 
366   RegisterFeatureListInstance(std::move(feature_list));
367 
368   std::string enable_features;
369   std::string disable_features;
370   FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
371                                                   &disable_features);
372   EXPECT_EQ("A,OffByDefault<Trial,X", SortFeatureListString(enable_features));
373   EXPECT_EQ("D", SortFeatureListString(disable_features));
374 }
375 
TEST_F(FeatureListTest,GetFeatureOverrides_UseDefault)376 TEST_F(FeatureListTest, GetFeatureOverrides_UseDefault) {
377   ClearFeatureListInstance();
378   FieldTrialList field_trial_list(nullptr);
379   std::unique_ptr<FeatureList> feature_list(new FeatureList);
380   feature_list->InitializeFromCommandLine("A,X", "D");
381 
382   FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
383   feature_list->RegisterFieldTrialOverride(
384       kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
385 
386   RegisterFeatureListInstance(std::move(feature_list));
387 
388   std::string enable_features;
389   std::string disable_features;
390   FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
391                                                   &disable_features);
392   EXPECT_EQ("*OffByDefault<Trial,A,X", SortFeatureListString(enable_features));
393   EXPECT_EQ("D", SortFeatureListString(disable_features));
394 }
395 
TEST_F(FeatureListTest,GetFieldTrial)396 TEST_F(FeatureListTest, GetFieldTrial) {
397   ClearFeatureListInstance();
398   FieldTrialList field_trial_list(nullptr);
399   FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
400   std::unique_ptr<FeatureList> feature_list(new FeatureList);
401   feature_list->RegisterFieldTrialOverride(
402       kFeatureOnByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
403   RegisterFeatureListInstance(std::move(feature_list));
404 
405   EXPECT_EQ(trial, FeatureList::GetFieldTrial(kFeatureOnByDefault));
406   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kFeatureOffByDefault));
407 }
408 
TEST_F(FeatureListTest,InitializeFromCommandLine_WithFieldTrials)409 TEST_F(FeatureListTest, InitializeFromCommandLine_WithFieldTrials) {
410   ClearFeatureListInstance();
411   FieldTrialList field_trial_list(nullptr);
412   FieldTrialList::CreateFieldTrial("Trial", "Group");
413   std::unique_ptr<FeatureList> feature_list(new FeatureList);
414   feature_list->InitializeFromCommandLine("A,OffByDefault<Trial,X", "D");
415   RegisterFeatureListInstance(std::move(feature_list));
416 
417   EXPECT_FALSE(FieldTrialList::IsTrialActive("Trial"));
418   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
419   EXPECT_TRUE(FieldTrialList::IsTrialActive("Trial"));
420 }
421 
TEST_F(FeatureListTest,InitializeFromCommandLine_UseDefault)422 TEST_F(FeatureListTest, InitializeFromCommandLine_UseDefault) {
423   ClearFeatureListInstance();
424   FieldTrialList field_trial_list(nullptr);
425   FieldTrialList::CreateFieldTrial("T1", "Group");
426   FieldTrialList::CreateFieldTrial("T2", "Group");
427   std::unique_ptr<FeatureList> feature_list(new FeatureList);
428   feature_list->InitializeFromCommandLine(
429       "A,*OffByDefault<T1,*OnByDefault<T2,X", "D");
430   RegisterFeatureListInstance(std::move(feature_list));
431 
432   EXPECT_FALSE(FieldTrialList::IsTrialActive("T1"));
433   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
434   EXPECT_TRUE(FieldTrialList::IsTrialActive("T1"));
435 
436   EXPECT_FALSE(FieldTrialList::IsTrialActive("T2"));
437   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
438   EXPECT_TRUE(FieldTrialList::IsTrialActive("T2"));
439 }
440 
TEST_F(FeatureListTest,InitializeInstance)441 TEST_F(FeatureListTest, InitializeInstance) {
442   ClearFeatureListInstance();
443 
444   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
445   FeatureList::SetInstance(std::move(feature_list));
446   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
447   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
448 
449   // Initialize from command line if we haven't yet.
450   FeatureList::InitializeInstance("", kFeatureOnByDefaultName);
451   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
452   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
453 
454   // Do not initialize from commandline if we have already.
455   FeatureList::InitializeInstance(kFeatureOffByDefaultName, "");
456   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
457   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
458 }
459 
TEST_F(FeatureListTest,UninitializedInstance_IsEnabledReturnsFalse)460 TEST_F(FeatureListTest, UninitializedInstance_IsEnabledReturnsFalse) {
461   ClearFeatureListInstance();
462   // This test case simulates the calling pattern found in code which does not
463   // explicitly initialize the features list.
464   // All IsEnabled() calls should return the default value in this scenario.
465   EXPECT_EQ(nullptr, FeatureList::GetInstance());
466   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
467   EXPECT_EQ(nullptr, FeatureList::GetInstance());
468   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
469 }
470 
471 }  // namespace base
472