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   FeatureList::GetInstance()->GetCommandLineFeatureOverrides(&enable_features,
    378                                                              &disable_features);
    379   EXPECT_EQ("A,X", SortFeatureListString(enable_features));
    380   EXPECT_EQ("D", SortFeatureListString(disable_features));
    381 }
    382 
    383 TEST_F(FeatureListTest, GetFeatureOverrides_UseDefault) {
    384   ClearFeatureListInstance();
    385   FieldTrialList field_trial_list(nullptr);
    386   std::unique_ptr<FeatureList> feature_list(new FeatureList);
    387   feature_list->InitializeFromCommandLine("A,X", "D");
    388 
    389   FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
    390   feature_list->RegisterFieldTrialOverride(
    391       kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
    392 
    393   RegisterFeatureListInstance(std::move(feature_list));
    394 
    395   std::string enable_features;
    396   std::string disable_features;
    397   FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
    398                                                   &disable_features);
    399   EXPECT_EQ("*OffByDefault<Trial,A,X", SortFeatureListString(enable_features));
    400   EXPECT_EQ("D", SortFeatureListString(disable_features));
    401 }
    402 
    403 TEST_F(FeatureListTest, GetFieldTrial) {
    404   ClearFeatureListInstance();
    405   FieldTrialList field_trial_list(nullptr);
    406   FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
    407   std::unique_ptr<FeatureList> feature_list(new FeatureList);
    408   feature_list->RegisterFieldTrialOverride(
    409       kFeatureOnByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
    410   RegisterFeatureListInstance(std::move(feature_list));
    411 
    412   EXPECT_EQ(trial, FeatureList::GetFieldTrial(kFeatureOnByDefault));
    413   EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kFeatureOffByDefault));
    414 }
    415 
    416 TEST_F(FeatureListTest, InitializeFromCommandLine_WithFieldTrials) {
    417   ClearFeatureListInstance();
    418   FieldTrialList field_trial_list(nullptr);
    419   FieldTrialList::CreateFieldTrial("Trial", "Group");
    420   std::unique_ptr<FeatureList> feature_list(new FeatureList);
    421   feature_list->InitializeFromCommandLine("A,OffByDefault<Trial,X", "D");
    422   RegisterFeatureListInstance(std::move(feature_list));
    423 
    424   EXPECT_FALSE(FieldTrialList::IsTrialActive("Trial"));
    425   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
    426   EXPECT_TRUE(FieldTrialList::IsTrialActive("Trial"));
    427 }
    428 
    429 TEST_F(FeatureListTest, InitializeFromCommandLine_UseDefault) {
    430   ClearFeatureListInstance();
    431   FieldTrialList field_trial_list(nullptr);
    432   FieldTrialList::CreateFieldTrial("T1", "Group");
    433   FieldTrialList::CreateFieldTrial("T2", "Group");
    434   std::unique_ptr<FeatureList> feature_list(new FeatureList);
    435   feature_list->InitializeFromCommandLine(
    436       "A,*OffByDefault<T1,*OnByDefault<T2,X", "D");
    437   RegisterFeatureListInstance(std::move(feature_list));
    438 
    439   EXPECT_FALSE(FieldTrialList::IsTrialActive("T1"));
    440   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
    441   EXPECT_TRUE(FieldTrialList::IsTrialActive("T1"));
    442 
    443   EXPECT_FALSE(FieldTrialList::IsTrialActive("T2"));
    444   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
    445   EXPECT_TRUE(FieldTrialList::IsTrialActive("T2"));
    446 }
    447 
    448 TEST_F(FeatureListTest, InitializeInstance) {
    449   ClearFeatureListInstance();
    450 
    451   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
    452   FeatureList::SetInstance(std::move(feature_list));
    453   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
    454   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
    455 
    456   // Initialize from command line if we haven't yet.
    457   FeatureList::InitializeInstance("", kFeatureOnByDefaultName);
    458   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
    459   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
    460 
    461   // Do not initialize from commandline if we have already.
    462   FeatureList::InitializeInstance(kFeatureOffByDefaultName, "");
    463   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
    464   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
    465 }
    466 
    467 TEST_F(FeatureListTest, UninitializedInstance_IsEnabledReturnsFalse) {
    468   ClearFeatureListInstance();
    469   // This test case simulates the calling pattern found in code which does not
    470   // explicitly initialize the features list.
    471   // All IsEnabled() calls should return the default value in this scenario.
    472   EXPECT_EQ(nullptr, FeatureList::GetInstance());
    473   EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
    474   EXPECT_EQ(nullptr, FeatureList::GetInstance());
    475   EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
    476 }
    477 
    478 TEST_F(FeatureListTest, StoreAndRetrieveFeaturesFromSharedMemory) {
    479   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
    480 
    481   // Create some overrides.
    482   feature_list->RegisterOverride(kFeatureOffByDefaultName,
    483                                  FeatureList::OVERRIDE_ENABLE_FEATURE, nullptr);
    484   feature_list->RegisterOverride(
    485       kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE, nullptr);
    486   feature_list->FinalizeInitialization();
    487 
    488   // Create an allocator and store the overrides.
    489   std::unique_ptr<SharedMemory> shm(new SharedMemory());
    490   shm->CreateAndMapAnonymous(4 << 10);
    491   SharedPersistentMemoryAllocator allocator(std::move(shm), 1, "", false);
    492   feature_list->AddFeaturesToAllocator(&allocator);
    493 
    494   std::unique_ptr<base::FeatureList> feature_list2(new base::FeatureList);
    495 
    496   // Check that the new feature list is empty.
    497   EXPECT_FALSE(feature_list2->IsFeatureOverriddenFromCommandLine(
    498       kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
    499   EXPECT_FALSE(feature_list2->IsFeatureOverriddenFromCommandLine(
    500       kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
    501 
    502   feature_list2->InitializeFromSharedMemory(&allocator);
    503   // Check that the new feature list now has 2 overrides.
    504   EXPECT_TRUE(feature_list2->IsFeatureOverriddenFromCommandLine(
    505       kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
    506   EXPECT_TRUE(feature_list2->IsFeatureOverriddenFromCommandLine(
    507       kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
    508 }
    509 
    510 TEST_F(FeatureListTest, StoreAndRetrieveAssociatedFeaturesFromSharedMemory) {
    511   FieldTrialList field_trial_list(nullptr);
    512   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
    513 
    514   // Create some overrides.
    515   FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("TrialExample1", "A");
    516   FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("TrialExample2", "B");
    517   feature_list->RegisterFieldTrialOverride(
    518       kFeatureOnByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial1);
    519   feature_list->RegisterFieldTrialOverride(
    520       kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial2);
    521   feature_list->FinalizeInitialization();
    522 
    523   // Create an allocator and store the overrides.
    524   std::unique_ptr<SharedMemory> shm(new SharedMemory());
    525   shm->CreateAndMapAnonymous(4 << 10);
    526   SharedPersistentMemoryAllocator allocator(std::move(shm), 1, "", false);
    527   feature_list->AddFeaturesToAllocator(&allocator);
    528 
    529   std::unique_ptr<base::FeatureList> feature_list2(new base::FeatureList);
    530   feature_list2->InitializeFromSharedMemory(&allocator);
    531   feature_list2->FinalizeInitialization();
    532 
    533   // Check that the field trials are still associated.
    534   FieldTrial* associated_trial1 =
    535       feature_list2->GetAssociatedFieldTrial(kFeatureOnByDefault);
    536   FieldTrial* associated_trial2 =
    537       feature_list2->GetAssociatedFieldTrial(kFeatureOffByDefault);
    538   EXPECT_EQ(associated_trial1, trial1);
    539   EXPECT_EQ(associated_trial2, trial2);
    540 }
    541 
    542 }  // namespace base
    543