Home | History | Annotate | Download | only in base
      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 
     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:
     45   FeatureListTest() : feature_list_(nullptr) {
     46     RegisterFeatureListInstance(WrapUnique(new FeatureList));
     47   }
     48   ~FeatureListTest() override { ClearFeatureListInstance(); }
     49 
     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   }
     55   void ClearFeatureListInstance() {
     56     FeatureList::ClearInstanceForTesting();
     57     feature_list_ = nullptr;
     58   }
     59 
     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 
     69 TEST_F(FeatureListTest, DefaultStates) {
     70   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
     71   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
     72 }
     73 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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