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