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