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