Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /feature_list_unittest.cc
blob: b84e05642c81eb1a9ba4901e0e60963510f2d98e [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:06[diff] [blame]1// Copyright 2015 The Chromium Authors
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]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
avi9b6f42932015-12-26 22:15:14[diff] [blame]7#include<stddef.h>
8
Peter Kasting025a94252025-01-29 21:28:37[diff] [blame]9#include<algorithm>
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]10#include<array>
Kendrake Tsuid3895ec2024-01-22 22:08:39[diff] [blame]11#include<ostream>
12#include<set>
13#include<string>
Helmut Januschkabf1d5e52024-04-05 02:30:27[diff] [blame]14#include<string_view>
danakj0c8d4aa2015-11-25 05:29:58[diff] [blame]15#include<utility>
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]16#include<vector>
danakj0c8d4aa2015-11-25 05:29:58[diff] [blame]17
Miriam Zimmermanb4683c12021-12-01 15:44:33[diff] [blame]18#include"base/feature_list_buildflags.h"
Leszek Swirskif7f53b432024-09-30 10:12:10[diff] [blame]19#include"base/feature_visitor.h"
asvitkine8423d172015-09-28 23:23:44[diff] [blame]20#include"base/format_macros.h"
Alexandr Ilin027ca3d32019-02-12 18:37:33[diff] [blame]21#include"base/memory/read_only_shared_memory_region.h"
asvitkine8423d172015-09-28 23:23:44[diff] [blame]22#include"base/metrics/field_trial.h"
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]23#include"base/metrics/field_trial_param_associator.h"
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]24#include"base/metrics/persistent_memory_allocator.h"
Miriam Zimmermanb4683c12021-12-01 15:44:33[diff] [blame]25#include"base/strings/strcat.h"
asvitkine86340192015-12-01 00:45:29[diff] [blame]26#include"base/strings/string_util.h"
asvitkine8423d172015-09-28 23:23:44[diff] [blame]27#include"base/strings/stringprintf.h"
Wezce49a7d2019-10-08 21:47:41[diff] [blame]28#include"base/test/scoped_feature_list.h"
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]29#include"testing/gtest/include/gtest/gtest.h"
30
31namespace base{
32
33namespace{
34
brucedawson702ade72017-01-24 00:27:05[diff] [blame]35constexprchar kFeatureOnByDefaultName[]="OnByDefault";
Daniel Cheng2628f682024-05-03 16:18:45[diff] [blame]36BASE_FEATURE(kFeatureOnByDefault,
37 kFeatureOnByDefaultName,
38 FEATURE_ENABLED_BY_DEFAULT);
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]39
brucedawson702ade72017-01-24 00:27:05[diff] [blame]40constexprchar kFeatureOffByDefaultName[]="OffByDefault";
Daniel Cheng2628f682024-05-03 16:18:45[diff] [blame]41BASE_FEATURE(kFeatureOffByDefault,
42 kFeatureOffByDefaultName,
43 FEATURE_DISABLED_BY_DEFAULT);
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]44
asvitkine86340192015-12-01 00:45:29[diff] [blame]45std::stringSortFeatureListString(const std::string& feature_list){
Helmut Januschkabf1d5e52024-04-05 02:30:27[diff] [blame]46 std::vector<std::string_view> features=
asvitkine86340192015-12-01 00:45:29[diff] [blame]47FeatureList::SplitFeatureListString(feature_list);
Peter Kasting025a94252025-01-29 21:28:37[diff] [blame]48 std::ranges::sort(features);
asvitkine86340192015-12-01 00:45:29[diff] [blame]49returnJoinString(features,",");
50}
51
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]52}// namespace
53
54classFeatureListTest:public testing::Test{
55public:
Wezce49a7d2019-10-08 21:47:41[diff] [blame]56FeatureListTest(){
57// Provide an empty FeatureList to each test by default.
58 scoped_feature_list_.InitWithFeatureList(std::make_unique<FeatureList>());
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]59}
David Bienvenub4b441e2020-09-23 05:49:57[diff] [blame]60FeatureListTest(constFeatureListTest&)=delete;
61FeatureListTest&operator=(constFeatureListTest&)=delete;
Wezce49a7d2019-10-08 21:47:41[diff] [blame]62~FeatureListTest() override=default;
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]63
64private:
Wezce49a7d2019-10-08 21:47:41[diff] [blame]65 test::ScopedFeatureList scoped_feature_list_;
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]66};
67
68TEST_F(FeatureListTest,DefaultStates){
69 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
70 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
71}
72
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]73TEST_F(FeatureListTest,InitFromCommandLine){
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]74structTestCases{
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]75constchar* enable_features;
76constchar* disable_features;
77bool expected_feature_on_state;
78bool expected_feature_off_state;
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]79};
80auto test_cases= std::to_array<TestCases>({
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]81{"","",true,false},
82{"OffByDefault","",true,true},
83{"OffByDefault","OnByDefault",false,true},
84{"OnByDefault,OffByDefault","",true,true},
85{"","OnByDefault,OffByDefault",false,false},
86// In the case an entry is both, disable takes precedence.
87{"OnByDefault","OnByDefault,OffByDefault",false,false},
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]88});
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]89
Daniel Chengf45f47602022-02-28 22:38:32[diff] [blame]90for(size_t i=0; i< std::size(test_cases);++i){
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]91constauto& test_case= test_cases[i];
asvitkine8423d172015-09-28 23:23:44[diff] [blame]92 SCOPED_TRACE(base::StringPrintf("Test[%"PRIuS"]: [%s] [%s]", i,
93 test_case.enable_features,
94 test_case.disable_features));
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]95
Wezce49a7d2019-10-08 21:47:41[diff] [blame]96auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]97 feature_list->InitFromCommandLine(test_case.enable_features,
98 test_case.disable_features);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]99 test::ScopedFeatureList scoped_feature_list;
100 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]101
102 EXPECT_EQ(test_case.expected_feature_on_state,
103FeatureList::IsEnabled(kFeatureOnByDefault))
104<< i;
105 EXPECT_EQ(test_case.expected_feature_off_state,
106FeatureList::IsEnabled(kFeatureOffByDefault))
107<< i;
Anthony Vallee-Dubois3475f662022-08-30 14:24:28[diff] [blame]108
109// Reading the state of each feature again will pull it from their
110// respective caches instead of performing the full lookup, which should
111// yield the same result.
112 EXPECT_EQ(test_case.expected_feature_on_state,
113FeatureList::IsEnabled(kFeatureOnByDefault))
114<< i;
115 EXPECT_EQ(test_case.expected_feature_off_state,
116FeatureList::IsEnabled(kFeatureOffByDefault))
117<< i;
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]118}
119}
120
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]121TEST_F(FeatureListTest,InitFromCommandLineWithFeatureParams){
Weilun Shie81c6b92020-07-06 20:33:59[diff] [blame]122struct{
123const std::string enable_features;
124const std::string expected_field_trial_created;
125const std::map<std::string, std::string> expected_feature_params;
126} test_cases[]={
127{"Feature:x/100/y/test","StudyFeature",{{"x","100"},{"y","test"}}},
128{"Feature<Trial1:x/200/y/123","Trial1",{{"x","200"},{"y","123"}}},
129{"Feature<Trial2.Group2:x/test/y/uma/z/ukm",
130"Trial2",
131{{"x","test"},{"y","uma"},{"z","ukm"}}},
132};
133
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]134// Clear global state so that repeated runs of this test don't flake.
135// When https://crrev.com/c/3694674 is submitted, we should be able to remove
136// this.
137 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
138
Daniel Cheng0fff5c232022-09-21 17:43:34[diff] [blame]139static BASE_FEATURE(kFeature,"Feature", FEATURE_DISABLED_BY_DEFAULT);
Weilun Shie81c6b92020-07-06 20:33:59[diff] [blame]140for(constauto& test_case: test_cases){
141 SCOPED_TRACE(test_case.enable_features);
142
143auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]144 feature_list->InitFromCommandLine(test_case.enable_features,"");
Weilun Shie81c6b92020-07-06 20:33:59[diff] [blame]145 test::ScopedFeatureList scoped_feature_list;
146 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
147
148 EXPECT_TRUE(FeatureList::IsEnabled(kFeature));
149 EXPECT_TRUE(
150FieldTrialList::IsTrialActive(test_case.expected_field_trial_created));
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]151 std::map<std::string, std::string> actual_params;
152 EXPECT_TRUE(GetFieldTrialParamsByFeature(kFeature,&actual_params));
153 EXPECT_EQ(test_case.expected_feature_params, actual_params);
Weilun Shie81c6b92020-07-06 20:33:59[diff] [blame]154}
155}
156
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]157TEST_F(FeatureListTest,CheckFeatureIdentity){
158// Tests that CheckFeatureIdentity() correctly detects when two different
159// structs with the same feature name are passed to it.
160
Wezce49a7d2019-10-08 21:47:41[diff] [blame]161 test::ScopedFeatureList scoped_feature_list;
162 scoped_feature_list.InitWithFeatureList(std::make_unique<FeatureList>());
163FeatureList* feature_list=FeatureList::GetInstance();
164
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]165// Call it twice for each feature at the top of the file, since the first call
166// makes it remember the entry and the second call will verify it.
Wezce49a7d2019-10-08 21:47:41[diff] [blame]167 EXPECT_TRUE(feature_list->CheckFeatureIdentity(kFeatureOnByDefault));
168 EXPECT_TRUE(feature_list->CheckFeatureIdentity(kFeatureOnByDefault));
169 EXPECT_TRUE(feature_list->CheckFeatureIdentity(kFeatureOffByDefault));
170 EXPECT_TRUE(feature_list->CheckFeatureIdentity(kFeatureOffByDefault));
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]171
172// Now, call it with a distinct struct for |kFeatureOnByDefaultName|, which
173// should return false.
Daniel Cheng2628f682024-05-03 16:18:45[diff] [blame]174static BASE_FEATURE(kFeatureOnByDefault2, kFeatureOnByDefaultName,
175 FEATURE_ENABLED_BY_DEFAULT);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]176 EXPECT_FALSE(feature_list->CheckFeatureIdentity(kFeatureOnByDefault2));
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]177}
178
asvitkine8423d172015-09-28 23:23:44[diff] [blame]179TEST_F(FeatureListTest,FieldTrialOverrides){
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]180structTestCases{
asvitkine8423d172015-09-28 23:23:44[diff] [blame]181FeatureList::OverrideState trial1_state;
182FeatureList::OverrideState trial2_state;
asvitkine8423d172015-09-28 23:23:44[diff] [blame]183};
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]184auto test_cases= std::to_array<TestCases>({
185{FeatureList::OVERRIDE_DISABLE_FEATURE,
186FeatureList::OVERRIDE_DISABLE_FEATURE},
187{FeatureList::OVERRIDE_DISABLE_FEATURE,
188FeatureList::OVERRIDE_ENABLE_FEATURE},
189{FeatureList::OVERRIDE_ENABLE_FEATURE,
190FeatureList::OVERRIDE_DISABLE_FEATURE},
191{FeatureList::OVERRIDE_ENABLE_FEATURE,
192FeatureList::OVERRIDE_ENABLE_FEATURE},
193});
asvitkine8423d172015-09-28 23:23:44[diff] [blame]194
195FieldTrial::ActiveGroup active_group;
Daniel Chengf45f47602022-02-28 22:38:32[diff] [blame]196for(size_t i=0; i< std::size(test_cases);++i){
asvitkine8423d172015-09-28 23:23:44[diff] [blame]197constauto& test_case= test_cases[i];
198 SCOPED_TRACE(base::StringPrintf("Test[%"PRIuS"]", i));
199
Takashi Sakamoto15d4a672022-08-05 07:24:16[diff] [blame]200 test::ScopedFeatureList outer_scope;
201 outer_scope.InitWithEmptyFeatureAndFieldTrialLists();
202
Wezce49a7d2019-10-08 21:47:41[diff] [blame]203auto feature_list= std::make_unique<FeatureList>();
asvitkine8423d172015-09-28 23:23:44[diff] [blame]204
205FieldTrial* trial1=FieldTrialList::CreateFieldTrial("TrialExample1","A");
206FieldTrial* trial2=FieldTrialList::CreateFieldTrial("TrialExample2","B");
207 feature_list->RegisterFieldTrialOverride(kFeatureOnByDefaultName,
208 test_case.trial1_state, trial1);
209 feature_list->RegisterFieldTrialOverride(kFeatureOffByDefaultName,
210 test_case.trial2_state, trial2);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]211 test::ScopedFeatureList scoped_feature_list;
212 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]213
214// Initially, neither trial should be active.
215 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial1->trial_name()));
216 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
217
218constbool expected_enabled_1=
219(test_case.trial1_state==FeatureList::OVERRIDE_ENABLE_FEATURE);
220 EXPECT_EQ(expected_enabled_1,FeatureList::IsEnabled(kFeatureOnByDefault));
221// The above should have activated |trial1|.
222 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
223 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
224
225constbool expected_enabled_2=
226(test_case.trial2_state==FeatureList::OVERRIDE_ENABLE_FEATURE);
227 EXPECT_EQ(expected_enabled_2,FeatureList::IsEnabled(kFeatureOffByDefault));
228// The above should have activated |trial2|.
229 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
230 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial2->trial_name()));
231}
232}
233
asvitkine64e9e112016-03-17 17:32:00[diff] [blame]234TEST_F(FeatureListTest,FieldTrialAssociateUseDefault){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]235auto feature_list= std::make_unique<FeatureList>();
asvitkine64e9e112016-03-17 17:32:00[diff] [blame]236
237FieldTrial* trial1=FieldTrialList::CreateFieldTrial("TrialExample1","A");
238FieldTrial* trial2=FieldTrialList::CreateFieldTrial("TrialExample2","B");
239 feature_list->RegisterFieldTrialOverride(
240 kFeatureOnByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial1);
241 feature_list->RegisterFieldTrialOverride(
242 kFeatureOffByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial2);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]243 test::ScopedFeatureList scoped_feature_list;
244 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine64e9e112016-03-17 17:32:00[diff] [blame]245
246// Initially, neither trial should be active.
247 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial1->trial_name()));
248 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
249
250// Check the feature enabled state is its default.
251 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
252// The above should have activated |trial1|.
253 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
254 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
255
256// Check the feature enabled state is its default.
257 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
258// The above should have activated |trial2|.
259 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
260 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial2->trial_name()));
261}
262
Alexei Svitkined3a55e7d42019-02-19 17:09:32[diff] [blame]263TEST_F(FeatureListTest,CommandLineEnableTakesPrecedenceOverFieldTrial){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]264auto feature_list= std::make_unique<FeatureList>();
asvitkine8423d172015-09-28 23:23:44[diff] [blame]265
266// The feature is explicitly enabled on the command-line.
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]267 feature_list->InitFromCommandLine(kFeatureOffByDefaultName,"");
asvitkine8423d172015-09-28 23:23:44[diff] [blame]268
269// But the FieldTrial would set the feature to disabled.
270FieldTrial* trial=FieldTrialList::CreateFieldTrial("TrialExample2","A");
271 feature_list->RegisterFieldTrialOverride(
272 kFeatureOffByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]273 test::ScopedFeatureList scoped_feature_list;
274 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]275
276 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
277// Command-line should take precedence.
278 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
279// Since the feature is on due to the command-line, and not as a result of the
280// field trial, the field trial should not be activated (since the Associate*
281// API wasn't used.)
282 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
283}
284
Alexei Svitkined3a55e7d42019-02-19 17:09:32[diff] [blame]285TEST_F(FeatureListTest,CommandLineDisableTakesPrecedenceOverFieldTrial){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]286auto feature_list= std::make_unique<FeatureList>();
Alexei Svitkined3a55e7d42019-02-19 17:09:32[diff] [blame]287
288// The feature is explicitly disabled on the command-line.
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]289 feature_list->InitFromCommandLine("", kFeatureOffByDefaultName);
Alexei Svitkined3a55e7d42019-02-19 17:09:32[diff] [blame]290
291// But the FieldTrial would set the feature to enabled.
292FieldTrial* trial=FieldTrialList::CreateFieldTrial("TrialExample2","A");
293 feature_list->RegisterFieldTrialOverride(
294 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE, trial);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]295 test::ScopedFeatureList scoped_feature_list;
296 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
Alexei Svitkined3a55e7d42019-02-19 17:09:32[diff] [blame]297
298 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
299// Command-line should take precedence.
300 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
301// Since the feature is on due to the command-line, and not as a result of the
302// field trial, the field trial should not be activated (since the Associate*
303// API wasn't used.)
304 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
305}
306
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]307TEST_F(FeatureListTest,IsFeatureOverriddenFromFieldTrial){
308auto feature_list= std::make_unique<FeatureList>();
309
310// No features are overridden from the field trails yet.
311 EXPECT_FALSE(feature_list->IsFeatureOverridden(kFeatureOnByDefaultName));
312 EXPECT_FALSE(feature_list->IsFeatureOverridden(kFeatureOffByDefaultName));
313
Alexei Svitkineaadca902025-06-12 22:41:18[diff] [blame]314// Now, register field trials to override `kFeatureOnByDefaultName` state and
315// keeping `kFeatureOffByDefault` as the default. Check that both are
316// considered overridden.
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]317 feature_list->RegisterFieldTrialOverride(
318 kFeatureOffByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT,
319FieldTrialList::CreateFieldTrial("Trial1","A"));
320 feature_list->RegisterFieldTrialOverride(
321 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE,
322FieldTrialList::CreateFieldTrial("Trial2","A"));
323 EXPECT_TRUE(feature_list->IsFeatureOverridden(kFeatureOnByDefaultName));
324 EXPECT_TRUE(feature_list->IsFeatureOverridden(kFeatureOffByDefaultName));
325
326 test::ScopedFeatureList scoped_feature_list;
327 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
328// Check the expected feature states for good measure.
329 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
330 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
331}
332
asvitkine8423d172015-09-28 23:23:44[diff] [blame]333TEST_F(FeatureListTest,IsFeatureOverriddenFromCommandLine){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]334auto feature_list= std::make_unique<FeatureList>();
asvitkine8423d172015-09-28 23:23:44[diff] [blame]335
336// No features are overridden from the command line yet
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]337 EXPECT_FALSE(feature_list->IsFeatureOverridden(kFeatureOnByDefaultName));
Collin Baker3435ba662020-10-07 18:07:09[diff] [blame]338 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
339 kFeatureOnByDefaultName));
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]340 EXPECT_FALSE(feature_list->IsFeatureOverridden(kFeatureOffByDefaultName));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]341 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
Collin Baker3435ba662020-10-07 18:07:09[diff] [blame]342 kFeatureOffByDefaultName));
343 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
asvitkine8423d172015-09-28 23:23:44[diff] [blame]344 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
345 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
346 kFeatureOnByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
347 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
348 kFeatureOffByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
349 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
350 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
351
352// Now, enable |kFeatureOffByDefaultName| via the command-line.
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]353 feature_list->InitFromCommandLine(kFeatureOffByDefaultName,"");
asvitkine8423d172015-09-28 23:23:44[diff] [blame]354
355// It should now be overridden for the enabled group.
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]356 EXPECT_TRUE(feature_list->IsFeatureOverridden(kFeatureOffByDefaultName));
Collin Baker3435ba662020-10-07 18:07:09[diff] [blame]357 EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
358 kFeatureOffByDefaultName));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]359 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
360 kFeatureOffByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
361 EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
362 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
363
364// Register a field trial to associate with the feature and ensure that the
365// results are still the same.
366 feature_list->AssociateReportingFieldTrial(
367 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE,
368FieldTrialList::CreateFieldTrial("Trial1","A"));
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]369 EXPECT_TRUE(feature_list->IsFeatureOverridden(kFeatureOffByDefaultName));
Collin Baker3435ba662020-10-07 18:07:09[diff] [blame]370 EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
371 kFeatureOffByDefaultName));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]372 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
373 kFeatureOffByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
374 EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
375 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
376
377// Now, register a field trial to override |kFeatureOnByDefaultName| state
378// and check that the function still returns false for that feature.
379 feature_list->RegisterFieldTrialOverride(
380 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE,
381FieldTrialList::CreateFieldTrial("Trial2","A"));
Xianzhu Wang05355f4a2020-09-02 01:22:16[diff] [blame]382 EXPECT_TRUE(feature_list->IsFeatureOverridden(kFeatureOnByDefaultName));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]383 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
Collin Baker3435ba662020-10-07 18:07:09[diff] [blame]384 kFeatureOnByDefaultName));
385 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
asvitkine8423d172015-09-28 23:23:44[diff] [blame]386 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
387 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
388 kFeatureOnByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
Wezce49a7d2019-10-08 21:47:41[diff] [blame]389 test::ScopedFeatureList scoped_feature_list;
390 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]391
392// Check the expected feature states for good measure.
393 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
394 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
395}
396
397TEST_F(FeatureListTest,AssociateReportingFieldTrial){
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]398structTestCases{
asvitkine8423d172015-09-28 23:23:44[diff] [blame]399constchar* enable_features;
400constchar* disable_features;
401bool expected_enable_trial_created;
402bool expected_disable_trial_created;
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]403};
404auto test_cases= std::to_array<TestCases>({
asvitkine8423d172015-09-28 23:23:44[diff] [blame]405// If no enable/disable flags are specified, no trials should be created.
406{"","",false,false},
407// Enabling the feature should result in the enable trial created.
408{kFeatureOffByDefaultName,"",true,false},
409// Disabling the feature should result in the disable trial created.
410{"", kFeatureOffByDefaultName,false,true},
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]411});
asvitkine8423d172015-09-28 23:23:44[diff] [blame]412
413constchar kTrialName[]="ForcingTrial";
414constchar kForcedOnGroupName[]="ForcedOn";
415constchar kForcedOffGroupName[]="ForcedOff";
416
Daniel Chengf45f47602022-02-28 22:38:32[diff] [blame]417for(size_t i=0; i< std::size(test_cases);++i){
asvitkine8423d172015-09-28 23:23:44[diff] [blame]418constauto& test_case= test_cases[i];
419 SCOPED_TRACE(base::StringPrintf("Test[%"PRIuS"]: [%s] [%s]", i,
420 test_case.enable_features,
421 test_case.disable_features));
422
Takashi Sakamoto15d4a672022-08-05 07:24:16[diff] [blame]423 test::ScopedFeatureList outer_scope;
424 outer_scope.InitWithEmptyFeatureAndFieldTrialLists();
425
Wezce49a7d2019-10-08 21:47:41[diff] [blame]426auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]427 feature_list->InitFromCommandLine(test_case.enable_features,
428 test_case.disable_features);
asvitkine8423d172015-09-28 23:23:44[diff] [blame]429
430FieldTrial* enable_trial=nullptr;
431if(feature_list->IsFeatureOverriddenFromCommandLine(
432 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE)){
433 enable_trial= base::FieldTrialList::CreateFieldTrial(kTrialName,
434 kForcedOnGroupName);
435 feature_list->AssociateReportingFieldTrial(
436 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE,
437 enable_trial);
438}
439FieldTrial* disable_trial=nullptr;
440if(feature_list->IsFeatureOverriddenFromCommandLine(
441 kFeatureOffByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE)){
442 disable_trial= base::FieldTrialList::CreateFieldTrial(
443 kTrialName, kForcedOffGroupName);
444 feature_list->AssociateReportingFieldTrial(
445 kFeatureOffByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE,
446 disable_trial);
447}
448 EXPECT_EQ(test_case.expected_enable_trial_created, enable_trial!=nullptr);
449 EXPECT_EQ(test_case.expected_disable_trial_created,
450 disable_trial!=nullptr);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]451 test::ScopedFeatureList scoped_feature_list;
452 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine8423d172015-09-28 23:23:44[diff] [blame]453
454 EXPECT_FALSE(FieldTrialList::IsTrialActive(kTrialName));
455if(disable_trial){
456 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
457 EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
458 EXPECT_EQ(kForcedOffGroupName, disable_trial->group_name());
459}elseif(enable_trial){
460 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
461 EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
462 EXPECT_EQ(kForcedOnGroupName, enable_trial->group_name());
463}
464}
465}
466
Alexei Svitkinef3d64cae2024-11-20 19:55:56[diff] [blame]467TEST_F(FeatureListTest,RegisterExtraFeatureOverrides_ReplaceUseDefault){
468auto feature_list= std::make_unique<FeatureList>();
469
470FieldTrial* trial1=FieldTrialList::CreateFieldTrial("Trial1","Group");
471 feature_list->RegisterFieldTrialOverride(
472 kFeatureOnByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial1);
473
474FieldTrial* trial2=FieldTrialList::CreateFieldTrial("Trial2","Group");
475 feature_list->RegisterFieldTrialOverride(
476 kFeatureOffByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial2);
477
478 std::vector<FeatureList::FeatureOverrideInfo> overrides;
479 overrides.emplace_back(std::cref(kFeatureOnByDefault),
480FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE);
481 overrides.emplace_back(std::cref(kFeatureOffByDefault),
482FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE);
483 feature_list->RegisterExtraFeatureOverrides(
484 std::move(overrides),/*replace_use_default_overrides=*/true);
485 test::ScopedFeatureList scoped_feature_list;
486 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
487
488// OVERRIDE_USE_DEFAULT entries should be overridden by AwFeatureOverrides.
489// Before querying the feature, the trials shouldn't be active, but should
490// be activated after querying.
491
492 EXPECT_FALSE(base::FieldTrialList::IsTrialActive("Trial1"));
493 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
494 EXPECT_TRUE(base::FieldTrialList::IsTrialActive("Trial1"));
495
496 EXPECT_FALSE(base::FieldTrialList::IsTrialActive("Trial2"));
497 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
498 EXPECT_TRUE(base::FieldTrialList::IsTrialActive("Trial2"));
499}
500
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]501TEST_F(FeatureListTest,RegisterExtraFeatureOverrides){
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]502auto feature_list= std::make_unique<FeatureList>();
503 std::vector<FeatureList::FeatureOverrideInfo> overrides;
Alexei Svitkinef3d64cae2024-11-20 19:55:56[diff] [blame]504 overrides.emplace_back(std::cref(kFeatureOnByDefault),
505FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE);
506 overrides.emplace_back(std::cref(kFeatureOffByDefault),
507FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]508 feature_list->RegisterExtraFeatureOverrides(std::move(overrides));
Wezce49a7d2019-10-08 21:47:41[diff] [blame]509 test::ScopedFeatureList scoped_feature_list;
510 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]511
512 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
513 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
514}
515
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]516TEST_F(FeatureListTest,InitFromCommandLineThenRegisterExtraOverrides){
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]517auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]518 feature_list->InitFromCommandLine(kFeatureOnByDefaultName,
519 kFeatureOffByDefaultName);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]520 std::vector<FeatureList::FeatureOverrideInfo> overrides;
Alexei Svitkinef3d64cae2024-11-20 19:55:56[diff] [blame]521 overrides.emplace_back(std::cref(kFeatureOnByDefault),
522FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE);
523 overrides.emplace_back(std::cref(kFeatureOffByDefault),
524FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]525 feature_list->RegisterExtraFeatureOverrides(std::move(overrides));
Wezce49a7d2019-10-08 21:47:41[diff] [blame]526 test::ScopedFeatureList scoped_feature_list;
527 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]528
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]529// The InitFromCommandLine supersedes the RegisterExtraFeatureOverrides
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]530// because it was called first.
531 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
532 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
533
534 std::string enable_features;
535 std::string disable_features;
536FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
537&disable_features);
538 EXPECT_EQ(kFeatureOnByDefaultName,SortFeatureListString(enable_features));
539 EXPECT_EQ(kFeatureOffByDefaultName,SortFeatureListString(disable_features));
540}
541
asvitkine86340192015-12-01 00:45:29[diff] [blame]542TEST_F(FeatureListTest,GetFeatureOverrides){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]543auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]544 feature_list->InitFromCommandLine("A,X","D");
asvitkine86340192015-12-01 00:45:29[diff] [blame]545
Daniel Cheng2628f682024-05-03 16:18:45[diff] [blame]546static BASE_FEATURE(feature_b,"B", FEATURE_ENABLED_BY_DEFAULT);
547static BASE_FEATURE(feature_c,"C", FEATURE_DISABLED_BY_DEFAULT);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]548 std::vector<FeatureList::FeatureOverrideInfo> overrides;
Alexei Svitkinef3d64cae2024-11-20 19:55:56[diff] [blame]549 overrides.emplace_back(std::cref(feature_b),
550FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE);
551 overrides.emplace_back(std::cref(feature_c),
552FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]553 feature_list->RegisterExtraFeatureOverrides(std::move(overrides));
554
asvitkine86340192015-12-01 00:45:29[diff] [blame]555FieldTrial* trial=FieldTrialList::CreateFieldTrial("Trial","Group");
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]556 feature_list->RegisterFieldTrialOverride(
557 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE, trial);
asvitkine86340192015-12-01 00:45:29[diff] [blame]558
Wezce49a7d2019-10-08 21:47:41[diff] [blame]559 test::ScopedFeatureList scoped_feature_list;
560 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine86340192015-12-01 00:45:29[diff] [blame]561
562 std::string enable_features;
563 std::string disable_features;
564FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
565&disable_features);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]566 EXPECT_EQ("A,C,OffByDefault<Trial,X",SortFeatureListString(enable_features));
567 EXPECT_EQ("B,D",SortFeatureListString(disable_features));
Alexei Svitkine223d2282018-02-08 00:18:35[diff] [blame]568
569FeatureList::GetInstance()->GetCommandLineFeatureOverrides(&enable_features,
570&disable_features);
Lily Chend49e3752019-08-09 19:05:24[diff] [blame]571 EXPECT_EQ("A,C,X",SortFeatureListString(enable_features));
572 EXPECT_EQ("B,D",SortFeatureListString(disable_features));
asvitkine86340192015-12-01 00:45:29[diff] [blame]573}
574
asvitkine6d31c52e2016-03-22 15:37:52[diff] [blame]575TEST_F(FeatureListTest,GetFeatureOverrides_UseDefault){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]576auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]577 feature_list->InitFromCommandLine("A,X","D");
asvitkine6d31c52e2016-03-22 15:37:52[diff] [blame]578
579FieldTrial* trial=FieldTrialList::CreateFieldTrial("Trial","Group");
580 feature_list->RegisterFieldTrialOverride(
581 kFeatureOffByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial);
582
Wezce49a7d2019-10-08 21:47:41[diff] [blame]583 test::ScopedFeatureList scoped_feature_list;
584 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine6d31c52e2016-03-22 15:37:52[diff] [blame]585
586 std::string enable_features;
587 std::string disable_features;
588FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
589&disable_features);
590 EXPECT_EQ("*OffByDefault<Trial,A,X",SortFeatureListString(enable_features));
591 EXPECT_EQ("D",SortFeatureListString(disable_features));
592}
593
jwd07b90382016-05-06 20:39:42[diff] [blame]594TEST_F(FeatureListTest,GetFieldTrial){
jwd07b90382016-05-06 20:39:42[diff] [blame]595FieldTrial* trial=FieldTrialList::CreateFieldTrial("Trial","Group");
Wezce49a7d2019-10-08 21:47:41[diff] [blame]596auto feature_list= std::make_unique<FeatureList>();
jwd07b90382016-05-06 20:39:42[diff] [blame]597 feature_list->RegisterFieldTrialOverride(
598 kFeatureOnByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]599 test::ScopedFeatureList scoped_feature_list;
600 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
jwd07b90382016-05-06 20:39:42[diff] [blame]601
602 EXPECT_EQ(trial,FeatureList::GetFieldTrial(kFeatureOnByDefault));
603 EXPECT_EQ(nullptr,FeatureList::GetFieldTrial(kFeatureOffByDefault));
604}
605
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]606TEST_F(FeatureListTest,InitFromCommandLine_WithFieldTrials){
asvitkineb2e44d82015-12-01 04:10:28[diff] [blame]607FieldTrialList::CreateFieldTrial("Trial","Group");
Wezce49a7d2019-10-08 21:47:41[diff] [blame]608auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]609 feature_list->InitFromCommandLine("A,OffByDefault<Trial,X","D");
Wezce49a7d2019-10-08 21:47:41[diff] [blame]610 test::ScopedFeatureList scoped_feature_list;
611 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkineb2e44d82015-12-01 04:10:28[diff] [blame]612
613 EXPECT_FALSE(FieldTrialList::IsTrialActive("Trial"));
614 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
615 EXPECT_TRUE(FieldTrialList::IsTrialActive("Trial"));
616}
617
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]618TEST_F(FeatureListTest,InitFromCommandLine_UseDefault){
asvitkine6d31c52e2016-03-22 15:37:52[diff] [blame]619FieldTrialList::CreateFieldTrial("T1","Group");
620FieldTrialList::CreateFieldTrial("T2","Group");
Wezce49a7d2019-10-08 21:47:41[diff] [blame]621auto feature_list= std::make_unique<FeatureList>();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]622 feature_list->InitFromCommandLine("A,*OffByDefault<T1,*OnByDefault<T2,X",
623"D");
Wezce49a7d2019-10-08 21:47:41[diff] [blame]624 test::ScopedFeatureList scoped_feature_list;
625 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
asvitkine6d31c52e2016-03-22 15:37:52[diff] [blame]626
627 EXPECT_FALSE(FieldTrialList::IsTrialActive("T1"));
628 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
629 EXPECT_TRUE(FieldTrialList::IsTrialActive("T1"));
630
631 EXPECT_FALSE(FieldTrialList::IsTrialActive("T2"));
632 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
633 EXPECT_TRUE(FieldTrialList::IsTrialActive("T2"));
634}
635
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]636TEST_F(FeatureListTest,InitInstance){
dcheng093de9b2016-04-04 21:25:51[diff] [blame]637 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
Wezce49a7d2019-10-08 21:47:41[diff] [blame]638 test::ScopedFeatureList scoped_feature_list;
639 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
640
changwan5b9da192016-03-31 07:36:19[diff] [blame]641 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
642 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
643
644// Initialize from command line if we haven't yet.
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]645FeatureList::InitInstance("", kFeatureOnByDefaultName);
changwan5b9da192016-03-31 07:36:19[diff] [blame]646 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
647 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
648
649// Do not initialize from commandline if we have already.
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]650FeatureList::InitInstance(kFeatureOffByDefaultName,"");
changwan5b9da192016-03-31 07:36:19[diff] [blame]651 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
652 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
653}
654
joedow958f0472016-07-07 22:08:55[diff] [blame]655TEST_F(FeatureListTest,UninitializedInstance_IsEnabledReturnsFalse){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]656 std::unique_ptr<FeatureList> original_feature_list=
657FeatureList::ClearInstanceForTesting();
658
joedow958f0472016-07-07 22:08:55[diff] [blame]659// This test case simulates the calling pattern found in code which does not
660// explicitly initialize the features list.
661// All IsEnabled() calls should return the default value in this scenario.
662 EXPECT_EQ(nullptr,FeatureList::GetInstance());
663 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
664 EXPECT_EQ(nullptr,FeatureList::GetInstance());
665 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
Wezce49a7d2019-10-08 21:47:41[diff] [blame]666
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]667if(original_feature_list){
Wezce49a7d2019-10-08 21:47:41[diff] [blame]668FeatureList::RestoreInstanceForTesting(std::move(original_feature_list));
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]669}
joedow958f0472016-07-07 22:08:55[diff] [blame]670}
671
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]672TEST_F(FeatureListTest,StoreAndRetrieveFeaturesFromSharedMemory){
673 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
674
675// Create some overrides.
676 feature_list->RegisterOverride(kFeatureOffByDefaultName,
677FeatureList::OVERRIDE_ENABLE_FEATURE,nullptr);
678 feature_list->RegisterOverride(
679 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE,nullptr);
680 feature_list->FinalizeInitialization();
681
682// Create an allocator and store the overrides.
Alexandr Ilin027ca3d32019-02-12 18:37:33[diff] [blame]683 base::MappedReadOnlyRegion shm=
684 base::ReadOnlySharedMemoryRegion::Create(4<<10);
685WritableSharedPersistentMemoryAllocator allocator(std::move(shm.mapping),1,
686"");
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]687 feature_list->AddFeaturesToAllocator(&allocator);
688
689 std::unique_ptr<base::FeatureList> feature_list2(new base::FeatureList);
690
691// Check that the new feature list is empty.
692 EXPECT_FALSE(feature_list2->IsFeatureOverriddenFromCommandLine(
693 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
694 EXPECT_FALSE(feature_list2->IsFeatureOverriddenFromCommandLine(
695 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
696
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]697 feature_list2->InitFromSharedMemory(&allocator);
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]698// Check that the new feature list now has 2 overrides.
699 EXPECT_TRUE(feature_list2->IsFeatureOverriddenFromCommandLine(
700 kFeatureOffByDefaultName,FeatureList::OVERRIDE_ENABLE_FEATURE));
701 EXPECT_TRUE(feature_list2->IsFeatureOverriddenFromCommandLine(
702 kFeatureOnByDefaultName,FeatureList::OVERRIDE_DISABLE_FEATURE));
703}
704
705TEST_F(FeatureListTest,StoreAndRetrieveAssociatedFeaturesFromSharedMemory){
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]706 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
707
708// Create some overrides.
709FieldTrial* trial1=FieldTrialList::CreateFieldTrial("TrialExample1","A");
710FieldTrial* trial2=FieldTrialList::CreateFieldTrial("TrialExample2","B");
711 feature_list->RegisterFieldTrialOverride(
712 kFeatureOnByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial1);
713 feature_list->RegisterFieldTrialOverride(
714 kFeatureOffByDefaultName,FeatureList::OVERRIDE_USE_DEFAULT, trial2);
715 feature_list->FinalizeInitialization();
716
717// Create an allocator and store the overrides.
Alexandr Ilin027ca3d32019-02-12 18:37:33[diff] [blame]718 base::MappedReadOnlyRegion shm=
719 base::ReadOnlySharedMemoryRegion::Create(4<<10);
720WritableSharedPersistentMemoryAllocator allocator(std::move(shm.mapping),1,
721"");
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]722 feature_list->AddFeaturesToAllocator(&allocator);
723
724 std::unique_ptr<base::FeatureList> feature_list2(new base::FeatureList);
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]725 feature_list2->InitFromSharedMemory(&allocator);
lawrencewu5e03cd32016-12-05 16:23:28[diff] [blame]726 feature_list2->FinalizeInitialization();
727
728// Check that the field trials are still associated.
729FieldTrial* associated_trial1=
730 feature_list2->GetAssociatedFieldTrial(kFeatureOnByDefault);
731FieldTrial* associated_trial2=
732 feature_list2->GetAssociatedFieldTrial(kFeatureOffByDefault);
733 EXPECT_EQ(associated_trial1, trial1);
734 EXPECT_EQ(associated_trial2, trial2);
735}
736
Marijn Kruisselbrink1934df72023-12-04 22:30:55[diff] [blame]737TEST_F(FeatureListTest,SetEarlyAccessInstance_AllowList){
738 test::ScopedFeatureList clear_feature_list;
739 clear_feature_list.InitWithNullFeatureAndFieldTrialLists();
740
741auto early_access_feature_list= std::make_unique<FeatureList>();
742 early_access_feature_list->InitFromCommandLine("OffByDefault","OnByDefault");
743FeatureList::SetEarlyAccessInstance(std::move(early_access_feature_list),
Marijn Kruisselbrink0b6d5df2023-12-14 22:31:29[diff] [blame]744{"DcheckIsFatal","OnByDefault"});
Marijn Kruisselbrink1934df72023-12-04 22:30:55[diff] [blame]745 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
746 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
747 EXPECT_EQ(&kFeatureOffByDefault,
748FeatureList::GetEarlyAccessedFeatureForTesting());
749FeatureList::ResetEarlyFeatureAccessTrackerForTesting();
750}
751
752TEST_F(FeatureListTest,SetEarlyAccessInstance_ReplaceByRealList){
753 test::ScopedFeatureList clear_feature_list;
754 clear_feature_list.InitWithNullFeatureAndFieldTrialLists();
755
756auto early_access_feature_list= std::make_unique<FeatureList>();
757 early_access_feature_list->InitFromCommandLine("OffByDefault","OnByDefault");
Marijn Kruisselbrink0b6d5df2023-12-14 22:31:29[diff] [blame]758FeatureList::SetEarlyAccessInstance(
759 std::move(early_access_feature_list),
760{"DcheckIsFatal","OffByDefault","OnByDefault"});
Marijn Kruisselbrink1934df72023-12-04 22:30:55[diff] [blame]761 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
762 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
763
764auto feature_list= std::make_unique<FeatureList>();
765 feature_list->InitFromCommandLine("","");
766FeatureList::SetInstance(std::move(feature_list));
767 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
768 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
769}
770
Miriam Zimmermanb4683c12021-12-01 15:44:33[diff] [blame]771#if BUILDFLAG(ENABLE_BANNED_BASE_FEATURE_PREFIX) && \
772 defined(GTEST_HAS_DEATH_TEST)
773usingFeatureListDeathTest=FeatureListTest;
774TEST_F(FeatureListDeathTest,DiesWithBadFeatureName){
Daniel Cheng2628f682024-05-03 16:18:45[diff] [blame]775// TODO(dcheng): Add a nocompile version of this test. In general, people
776// should not be constructing features at runtime anyway but just in case...
Miriam Zimmermanb4683c12021-12-01 15:44:33[diff] [blame]777 EXPECT_DEATH(
778Feature(
779StrCat({BUILDFLAG(BANNED_BASE_FEATURE_PREFIX),"MyFeature"}).c_str(),
Daniel Cheng2628f682024-05-03 16:18:45[diff] [blame]780 FEATURE_DISABLED_BY_DEFAULT,
781 internal::FeatureMacroHandshake::kSecret),
Miriam Zimmermanb4683c12021-12-01 15:44:33[diff] [blame]782StrCat({"Invalid feature name ", BUILDFLAG(BANNED_BASE_FEATURE_PREFIX),
783"MyFeature"}));
784}
785#endif// BUILDFLAG(ENABLE_BANNED_BASE_FEATURE_PREFIX) &&
786// defined(GTEST_HAS_DEATH_TEST)
787
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]788TEST(FeatureListAccessorTest,DefaultStates){
Tom Sepezc0c75bee2022-12-16 03:12:38[diff] [blame]789 test::ScopedFeatureList scoped_feature_list;
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]790auto feature_list= std::make_unique<FeatureList>();
791auto feature_list_accessor= feature_list->ConstructAccessor();
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]792 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
793
794 EXPECT_EQ(feature_list_accessor->GetOverrideStateByFeatureName(
795 kFeatureOnByDefault.name),
796FeatureList::OVERRIDE_USE_DEFAULT);
797 EXPECT_EQ(feature_list_accessor->GetOverrideStateByFeatureName(
798 kFeatureOffByDefault.name),
799FeatureList::OVERRIDE_USE_DEFAULT);
800}
801
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]802TEST(FeatureListAccessorTest,InitFromCommandLine){
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]803structTestCases{
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]804constchar* enable_features;
805constchar* disable_features;
806FeatureList::OverrideState expected_feature_on_state;
807FeatureList::OverrideState expected_feature_off_state;
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]808};
809auto test_cases= std::to_array<TestCases>({
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]810{"","",FeatureList::OVERRIDE_USE_DEFAULT,
811FeatureList::OVERRIDE_USE_DEFAULT},
812{"OffByDefault","",FeatureList::OVERRIDE_USE_DEFAULT,
813FeatureList::OVERRIDE_ENABLE_FEATURE},
814{"OffByDefault","OnByDefault",FeatureList::OVERRIDE_DISABLE_FEATURE,
815FeatureList::OVERRIDE_ENABLE_FEATURE},
816{"OnByDefault,OffByDefault","",FeatureList::OVERRIDE_ENABLE_FEATURE,
817FeatureList::OVERRIDE_ENABLE_FEATURE},
818{"","OnByDefault,OffByDefault",FeatureList::OVERRIDE_DISABLE_FEATURE,
819FeatureList::OVERRIDE_DISABLE_FEATURE},
820// In the case an entry is both, disable takes precedence.
821{"OnByDefault","OnByDefault,OffByDefault",
822FeatureList::OVERRIDE_DISABLE_FEATURE,
823FeatureList::OVERRIDE_DISABLE_FEATURE},
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]824});
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]825
Daniel Chengf45f47602022-02-28 22:38:32[diff] [blame]826for(size_t i=0; i< std::size(test_cases);++i){
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]827constauto& test_case= test_cases[i];
828 SCOPED_TRACE(base::StringPrintf("Test[%"PRIuS"]: [%s] [%s]", i,
829 test_case.enable_features,
830 test_case.disable_features));
831
Tom Sepezc0c75bee2022-12-16 03:12:38[diff] [blame]832 test::ScopedFeatureList scoped_feature_list;
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]833auto feature_list= std::make_unique<FeatureList>();
834auto feature_list_accessor= feature_list->ConstructAccessor();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]835 feature_list->InitFromCommandLine(test_case.enable_features,
836 test_case.disable_features);
Miriam Zimmermandfe28072021-11-22 22:16:31[diff] [blame]837 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
838
839 EXPECT_EQ(test_case.expected_feature_on_state,
840 feature_list_accessor->GetOverrideStateByFeatureName(
841 kFeatureOnByDefault.name))
842<< i;
843 EXPECT_EQ(test_case.expected_feature_off_state,
844 feature_list_accessor->GetOverrideStateByFeatureName(
845 kFeatureOffByDefault.name))
846<< i;
847}
848}
849
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]850TEST(FeatureListAccessorTest,InitFromCommandLineWithFeatureParams){
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]851structTestCases{
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]852const std::string enable_features;
853const std::map<std::string, std::string> expected_feature_params;
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]854};
855auto test_cases= std::to_array<TestCases>({
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]856{"Feature:x/100/y/test",{{"x","100"},{"y","test"}}},
857{"Feature<Trial:asdf/ghjkl/y/123",{{"asdf","ghjkl"},{"y","123"}}},
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]858});
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]859
860// Clear global state so that repeated runs of this test don't flake.
861// When https://crrev.com/c/3694674 is submitted, we should be able to remove
862// this.
863 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
864
865for(size_t i=0; i< std::size(test_cases);++i){
866constauto& test_case= test_cases[i];
867 SCOPED_TRACE(test_case.enable_features);
868
Tom Sepezc0c75bee2022-12-16 03:12:38[diff] [blame]869 test::ScopedFeatureList scoped_feature_list;
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]870auto feature_list= std::make_unique<FeatureList>();
871auto feature_list_accessor= feature_list->ConstructAccessor();
Gabriel Gauthier-Shalom89627a67a2023-11-29 22:11:19[diff] [blame]872 feature_list->InitFromCommandLine(test_case.enable_features,"");
Miriam Zimmerman79f6cac2022-06-17 17:58:25[diff] [blame]873 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
874
875 EXPECT_EQ(FeatureList::OVERRIDE_ENABLE_FEATURE,
876 feature_list_accessor->GetOverrideStateByFeatureName("Feature"))
877<< i;
878 std::map<std::string, std::string> actual_params;
879 EXPECT_TRUE(feature_list_accessor->GetParamsByFeatureName("Feature",
880&actual_params))
881<< i;
882 EXPECT_EQ(test_case.expected_feature_params, actual_params)<< i;
883}
884}
885
Kendrake Tsuid3895ec2024-01-22 22:08:39[diff] [blame]886// Test only class to verify correctness of
887// FeatureList::VisitFeaturesAndParams().
888classTestFeatureVisitor:publicFeatureVisitor{
889public:
890TestFeatureVisitor()=default;
891
892TestFeatureVisitor(constTestFeatureVisitor&)=delete;
893TestFeatureVisitor&operator=(constTestFeatureVisitor&)=delete;
894
895~TestFeatureVisitor() override=default;
896
897structVisitedFeatureState{
898autooperator<=>(constVisitedFeatureState&)const=default;
899
900 std::string feature_name;
901const base::FeatureList::OverrideState override_state;
902 base::FieldTrialParams params;
903 std::string trial_name;
904 std::string group_name;
905};
906
907voidVisit(const std::string& feature_name,
908FeatureList::OverrideState override_state,
909constFieldTrialParams& params,
910const std::string& trial_name,
911const std::string& group_name) override{
912 feature_state_.insert(TestFeatureVisitor::VisitedFeatureState{
913 feature_name, override_state, params, trial_name, group_name});
914}
915
916const std::multiset<TestFeatureVisitor::VisitedFeatureState>&
917 feature_state(){
918return feature_state_;
919}
920
921private:
922 std::multiset<VisitedFeatureState> feature_state_;
923};
924
925// Makes test output human readable.
926std::ostream&operator<<(std::ostream& out,
927constTestFeatureVisitor::VisitedFeatureState& state){
928 out<<".feature_name='"<< state.feature_name
929<<"', .override_state="<< state.override_state<<", .params={";
930
931for(constauto& param: state.params){
932 out<< param.first<<"="<< param.second<<", ";
933}
934
935 out<<"}, .trial_name='"<< state.trial_name<<"', .group_name='"
936<< state.group_name<<"'";
937return out;
938}
939
940TEST(TestFeatureVisitor,FeatureWithNoFieldTrial){
941 base::test::ScopedFeatureList outer_scope;
942 outer_scope.InitWithEmptyFeatureAndFieldTrialLists();
943
944 base::test::ScopedFeatureList feature_list;
945 feature_list.InitWithFeatures(/*enabled_features=*/{kFeatureOffByDefault},
946/*disabled_features=*/{kFeatureOnByDefault});
947
948TestFeatureVisitor visitor;
949 base::FeatureList::VisitFeaturesAndParams(visitor);
950 std::multiset<TestFeatureVisitor::VisitedFeatureState> actual_feature_state=
951 visitor.feature_state();
952
953 std::multiset<TestFeatureVisitor::VisitedFeatureState>
954 expected_feature_state={
955{"OnByDefault",FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE,
956FieldTrialParams{},"",""},
957{"OffByDefault",FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE,
958FieldTrialParams{},"",""},
959};
960
961 EXPECT_EQ(actual_feature_state, expected_feature_state);
962}
963
964TEST(TestFeatureVisitor,FeatureOverrideUseDefault){
965 base::test::ScopedFeatureList outer_scope;
966 outer_scope.InitWithEmptyFeatureAndFieldTrialLists();
967
968auto feature_list= std::make_unique<base::FeatureList>();
969 base::FieldTrial* trial=
970 base::FieldTrialList::CreateFieldTrial("TrialExample","A");
971 feature_list->RegisterFieldTrialOverride(
972"TestFeature", base::FeatureList::OVERRIDE_USE_DEFAULT, trial);
973
974 base::test::ScopedFeatureList initialized_feature_list;
975 initialized_feature_list.InitWithFeatureList(std::move(feature_list));
976
977TestFeatureVisitor visitor;
978 base::FeatureList::VisitFeaturesAndParams(visitor);
979 std::multiset<TestFeatureVisitor::VisitedFeatureState> actual_feature_state=
980 visitor.feature_state();
981
982 std::multiset<TestFeatureVisitor::VisitedFeatureState>
983 expected_feature_state={
984{"TestFeature",FeatureList::OverrideState::OVERRIDE_USE_DEFAULT,
985FieldTrialParams{},"TrialExample","A"}};
986
987 EXPECT_EQ(actual_feature_state, expected_feature_state);
988}
989
990TEST(TestFeatureVisitor,FeatureHasParams){
991 base::test::ScopedFeatureList outer_scope;
992 outer_scope.InitWithEmptyFeatureAndFieldTrialLists();
993
994 base::test::ScopedFeatureList initialized_feature_list;
995
996 initialized_feature_list.InitFromCommandLine(
Peter Kasting811504a72025-01-09 03:18:50[diff] [blame]997/*enable_features=*/"TestFeature<foo.bar:k1/v1/k2/v2",
998/*disable_features=*/"");
Kendrake Tsuid3895ec2024-01-22 22:08:39[diff] [blame]999
Alex Kalugin1c7d85c92025-06-04 18:08:19[diff] [blame]1000const std::multiset<TestFeatureVisitor::VisitedFeatureState>
Kendrake Tsuid3895ec2024-01-22 22:08:39[diff] [blame]1001 expected_feature_state={
1002{"TestFeature",FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE,
1003FieldTrialParams{{"k1","v1"},{"k2","v2"}},"foo","bar"},
1004};
1005
Alex Kalugin1c7d85c92025-06-04 18:08:19[diff] [blame]1006{// Check cached params.
1007TestFeatureVisitor visitor;
1008 base::FeatureList::VisitFeaturesAndParams(visitor);
1009 std::multiset<TestFeatureVisitor::VisitedFeatureState>
1010 actual_feature_state= visitor.feature_state();
1011
1012 EXPECT_EQ(actual_feature_state, expected_feature_state);
1013}
1014
1015{// Check that we fetch params from shared memory.
1016FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded();
1017FieldTrialParamAssociator::GetInstance()->ClearAllCachedParamsForTesting();
1018
1019TestFeatureVisitor visitor;
1020 base::FeatureList::VisitFeaturesAndParams(visitor);
1021 std::multiset<TestFeatureVisitor::VisitedFeatureState>
1022 actual_feature_state= visitor.feature_state();
1023
1024 EXPECT_EQ(actual_feature_state, expected_feature_state);
1025}
Kendrake Tsuid3895ec2024-01-22 22:08:39[diff] [blame]1026}
Leszek Swirskif7f53b432024-09-30 10:12:10[diff] [blame]1027
1028TEST(TestFeatureVisitor,FeatureWithPrefix){
1029 base::test::ScopedFeatureList outer_scope;
1030 outer_scope.InitWithEmptyFeatureAndFieldTrialLists();
1031
1032 base::test::ScopedFeatureList initialized_feature_list;
1033
1034 initialized_feature_list.InitFromCommandLine(
1035/*enable_features=*/
1036"AFeature,AnotherFeature,TestFeature,TestFeature2,PrefixedFeature,"
1037"PrefixedFeature2",
1038/*disable_features=*/"");
1039
1040TestFeatureVisitor visitor;
1041 base::FeatureList::VisitFeaturesAndParams(visitor,"Prefixed");
1042 std::multiset<TestFeatureVisitor::VisitedFeatureState> actual_feature_state=
1043 visitor.feature_state();
1044
1045 std::multiset<TestFeatureVisitor::VisitedFeatureState>
1046 expected_feature_state={
1047{"PrefixedFeature",
1048FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE,
1049FieldTrialParams{},"",""},
1050{"PrefixedFeature2",
1051FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE,
1052FieldTrialParams{},"",""},
1053};
1054
1055 EXPECT_EQ(actual_feature_state, expected_feature_state);
1056}
Kendrake Tsuid3895ec2024-01-22 22:08:39[diff] [blame]1057
asvitkinebccbb862015-09-04 17:17:45[diff] [blame]1058}// namespace base

[8]ページ先頭

©2009-2025 Movatter.jp