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