blob: 25db43d3354531c0fc10a46bc78f73df138457f3 [file] [log] [blame]
[email protected]1bc78422011-03-31 08:41:381// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]e2ddbc92010-10-15 20:02:072// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]3853a4c2013-02-11 17:15:575#include "base/prefs/pref_registry_simple.h"
[email protected]e5ba874f2013-02-14 17:20:196#include "base/prefs/testing_pref_service.h"
[email protected]3ea1b182013-02-08 22:38:417#include "base/strings/string_number_conversions.h"
[email protected]a82744532011-02-11 16:15:538#include "base/utf_string_conversions.h"
[email protected]a314ee5a2010-10-26 21:23:289#include "base/values.h"
[email protected]8a6ff28d2010-12-02 16:35:1910#include "chrome/browser/about_flags.h"
[email protected]e2ddbc92010-10-15 20:02:0711#include "chrome/common/chrome_switches.h"
12#include "chrome/common/pref_names.h"
[email protected]a314ee5a2010-10-26 21:23:2813#include "grit/chromium_strings.h"
[email protected]e2ddbc92010-10-15 20:02:0714#include "testing/gtest/include/gtest/gtest.h"
15
[email protected]a314ee5a2010-10-26 21:23:2816const char kFlags1[] = "flag1";
17const char kFlags2[] = "flag2";
18const char kFlags3[] = "flag3";
[email protected]8a6ff28d2010-12-02 16:35:1919const char kFlags4[] = "flag4";
[email protected]83e9fa702013-02-25 19:30:4420const char kFlags5[] = "flag5";
[email protected]e2ddbc92010-10-15 20:02:0721
[email protected]a314ee5a2010-10-26 21:23:2822const char kSwitch1[] = "switch";
23const char kSwitch2[] = "switch2";
24const char kSwitch3[] = "switch3";
[email protected]a82744532011-02-11 16:15:5325const char kValueForSwitch2[] = "value_for_switch2";
[email protected]e2ddbc92010-10-15 20:02:0726
[email protected]8a6ff28d2010-12-02 16:35:1927const char kMultiSwitch1[] = "multi_switch1";
28const char kMultiSwitch2[] = "multi_switch2";
[email protected]a82744532011-02-11 16:15:5329const char kValueForMultiSwitch2[] = "value_for_multi_switch2";
[email protected]8a6ff28d2010-12-02 16:35:1930
[email protected]83e9fa702013-02-25 19:30:4431const char kEnableDisableValue1[] = "value1";
32const char kEnableDisableValue2[] = "value2";
33
[email protected]e2ddbc92010-10-15 20:02:0734namespace about_flags {
35
[email protected]8a6ff28d2010-12-02 16:35:1936const Experiment::Choice kMultiChoices[] = {
[email protected]a82744532011-02-11 16:15:5337 { IDS_PRODUCT_NAME, "", "" },
38 { IDS_PRODUCT_NAME, kMultiSwitch1, "" },
39 { IDS_PRODUCT_NAME, kMultiSwitch2, kValueForMultiSwitch2 },
[email protected]8a6ff28d2010-12-02 16:35:1940};
41
42// The experiments that are set for these tests. The 3rd experiment is not
43// supported on the current platform, all others are.
[email protected]a314ee5a2010-10-26 21:23:2844static Experiment kExperiments[] = {
45 {
46 kFlags1,
47 IDS_PRODUCT_NAME,
48 IDS_PRODUCT_NAME,
49 0, // Ends up being mapped to the current platform.
[email protected]8a6ff28d2010-12-02 16:35:1950 Experiment::SINGLE_VALUE,
51 kSwitch1,
[email protected]a82744532011-02-11 16:15:5352 "",
[email protected]8a6ff28d2010-12-02 16:35:1953 NULL,
[email protected]83e9fa702013-02-25 19:30:4454 NULL,
55 NULL,
[email protected]8a6ff28d2010-12-02 16:35:1956 0
[email protected]a314ee5a2010-10-26 21:23:2857 },
58 {
59 kFlags2,
60 IDS_PRODUCT_NAME,
61 IDS_PRODUCT_NAME,
62 0, // Ends up being mapped to the current platform.
[email protected]8a6ff28d2010-12-02 16:35:1963 Experiment::SINGLE_VALUE,
64 kSwitch2,
[email protected]a82744532011-02-11 16:15:5365 kValueForSwitch2,
[email protected]8a6ff28d2010-12-02 16:35:1966 NULL,
[email protected]83e9fa702013-02-25 19:30:4467 NULL,
68 NULL,
[email protected]8a6ff28d2010-12-02 16:35:1969 0
[email protected]a314ee5a2010-10-26 21:23:2870 },
71 {
72 kFlags3,
73 IDS_PRODUCT_NAME,
74 IDS_PRODUCT_NAME,
75 0, // This ends up enabling for an OS other than the current.
[email protected]8a6ff28d2010-12-02 16:35:1976 Experiment::SINGLE_VALUE,
77 kSwitch3,
[email protected]a82744532011-02-11 16:15:5378 "",
[email protected]8a6ff28d2010-12-02 16:35:1979 NULL,
[email protected]83e9fa702013-02-25 19:30:4480 NULL,
81 NULL,
[email protected]8a6ff28d2010-12-02 16:35:1982 0
83 },
84 {
85 kFlags4,
86 IDS_PRODUCT_NAME,
87 IDS_PRODUCT_NAME,
88 0, // Ends up being mapped to the current platform.
89 Experiment::MULTI_VALUE,
90 "",
[email protected]a82744532011-02-11 16:15:5391 "",
[email protected]83e9fa702013-02-25 19:30:4492 "",
93 "",
[email protected]8a6ff28d2010-12-02 16:35:1994 kMultiChoices,
95 arraysize(kMultiChoices)
[email protected]a314ee5a2010-10-26 21:23:2896 },
[email protected]83e9fa702013-02-25 19:30:4497 {
98 kFlags5,
99 IDS_PRODUCT_NAME,
100 IDS_PRODUCT_NAME,
101 0, // Ends up being mapped to the current platform.
102 Experiment::ENABLE_DISABLE_VALUE,
103 kSwitch1,
104 kEnableDisableValue1,
105 kSwitch2,
106 kEnableDisableValue2,
107 NULL,
108 3
109 },
[email protected]a314ee5a2010-10-26 21:23:28110};
111
[email protected]e2ddbc92010-10-15 20:02:07112class AboutFlagsTest : public ::testing::Test {
113 protected:
114 AboutFlagsTest() {
[email protected]b1de2c72013-02-06 02:45:47115 prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments);
[email protected]e2ddbc92010-10-15 20:02:07116 testing::ClearState();
117 }
118
[email protected]83e9fa702013-02-25 19:30:44119 virtual void SetUp() OVERRIDE {
[email protected]a314ee5a2010-10-26 21:23:28120 for (size_t i = 0; i < arraysize(kExperiments); ++i)
121 kExperiments[i].supported_platforms = GetCurrentPlatform();
122
123 int os_other_than_current = 1;
124 while (os_other_than_current == GetCurrentPlatform())
125 os_other_than_current <<= 1;
126 kExperiments[2].supported_platforms = os_other_than_current;
127
128 testing::SetExperiments(kExperiments, arraysize(kExperiments));
129 }
130
[email protected]83e9fa702013-02-25 19:30:44131 virtual void TearDown() OVERRIDE {
[email protected]a314ee5a2010-10-26 21:23:28132 testing::SetExperiments(NULL, 0);
133 }
134
[email protected]5b199522012-12-22 17:24:44135 TestingPrefServiceSimple prefs_;
[email protected]e2ddbc92010-10-15 20:02:07136};
137
138TEST_F(AboutFlagsTest, ChangeNeedsRestart) {
[email protected]e2ddbc92010-10-15 20:02:07139 EXPECT_FALSE(IsRestartNeededToCommitChanges());
140 SetExperimentEnabled(&prefs_, kFlags1, true);
141 EXPECT_TRUE(IsRestartNeededToCommitChanges());
142}
143
144TEST_F(AboutFlagsTest, AddTwoFlagsRemoveOne) {
[email protected]e2ddbc92010-10-15 20:02:07145 // Add two experiments, check they're there.
146 SetExperimentEnabled(&prefs_, kFlags1, true);
147 SetExperimentEnabled(&prefs_, kFlags2, true);
148
[email protected]1bc78422011-03-31 08:41:38149 const ListValue* experiments_list = prefs_.GetList(
[email protected]e2ddbc92010-10-15 20:02:07150 prefs::kEnabledLabsExperiments);
151 ASSERT_TRUE(experiments_list != NULL);
152
153 ASSERT_EQ(2u, experiments_list->GetSize());
154
155 std::string s0;
156 ASSERT_TRUE(experiments_list->GetString(0, &s0));
157 std::string s1;
158 ASSERT_TRUE(experiments_list->GetString(1, &s1));
159
160 EXPECT_TRUE(s0 == kFlags1 || s1 == kFlags1);
161 EXPECT_TRUE(s0 == kFlags2 || s1 == kFlags2);
162
163 // Remove one experiment, check the other's still around.
164 SetExperimentEnabled(&prefs_, kFlags2, false);
165
[email protected]1bc78422011-03-31 08:41:38166 experiments_list = prefs_.GetList(prefs::kEnabledLabsExperiments);
[email protected]e2ddbc92010-10-15 20:02:07167 ASSERT_TRUE(experiments_list != NULL);
168 ASSERT_EQ(1u, experiments_list->GetSize());
169 ASSERT_TRUE(experiments_list->GetString(0, &s0));
170 EXPECT_TRUE(s0 == kFlags1);
171}
172
173TEST_F(AboutFlagsTest, AddTwoFlagsRemoveBoth) {
[email protected]e2ddbc92010-10-15 20:02:07174 // Add two experiments, check the pref exists.
175 SetExperimentEnabled(&prefs_, kFlags1, true);
176 SetExperimentEnabled(&prefs_, kFlags2, true);
[email protected]1bc78422011-03-31 08:41:38177 const ListValue* experiments_list = prefs_.GetList(
[email protected]e2ddbc92010-10-15 20:02:07178 prefs::kEnabledLabsExperiments);
179 ASSERT_TRUE(experiments_list != NULL);
180
181 // Remove both, the pref should have been removed completely.
182 SetExperimentEnabled(&prefs_, kFlags1, false);
183 SetExperimentEnabled(&prefs_, kFlags2, false);
[email protected]1bc78422011-03-31 08:41:38184 experiments_list = prefs_.GetList(prefs::kEnabledLabsExperiments);
[email protected]e2ddbc92010-10-15 20:02:07185 EXPECT_TRUE(experiments_list == NULL || experiments_list->GetSize() == 0);
186}
187
188TEST_F(AboutFlagsTest, ConvertFlagsToSwitches) {
[email protected]e2ddbc92010-10-15 20:02:07189 SetExperimentEnabled(&prefs_, kFlags1, true);
190
[email protected]947446b2010-10-21 03:36:31191 CommandLine command_line(CommandLine::NO_PROGRAM);
[email protected]e2ddbc92010-10-15 20:02:07192 command_line.AppendSwitch("foo");
193
194 EXPECT_TRUE(command_line.HasSwitch("foo"));
[email protected]a314ee5a2010-10-26 21:23:28195 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
[email protected]e2ddbc92010-10-15 20:02:07196
197 ConvertFlagsToSwitches(&prefs_, &command_line);
198
199 EXPECT_TRUE(command_line.HasSwitch("foo"));
[email protected]cd7fa99f2011-09-07 01:24:55200 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
[email protected]e2ddbc92010-10-15 20:02:07201}
202
203TEST_F(AboutFlagsTest, RemoveFlagSwitches) {
[email protected]e2ddbc92010-10-15 20:02:07204 std::map<std::string, CommandLine::StringType> switch_list;
[email protected]a314ee5a2010-10-26 21:23:28205 switch_list[kSwitch1] = CommandLine::StringType();
[email protected]e2ddbc92010-10-15 20:02:07206 switch_list[switches::kFlagSwitchesBegin] = CommandLine::StringType();
207 switch_list[switches::kFlagSwitchesEnd] = CommandLine::StringType();
208 switch_list["foo"] = CommandLine::StringType();
209
210 SetExperimentEnabled(&prefs_, kFlags1, true);
211
212 // This shouldn't do anything before ConvertFlagsToSwitches() wasn't called.
213 RemoveFlagsSwitches(&switch_list);
214 ASSERT_EQ(4u, switch_list.size());
[email protected]a314ee5a2010-10-26 21:23:28215 EXPECT_TRUE(switch_list.find(kSwitch1) != switch_list.end());
[email protected]e2ddbc92010-10-15 20:02:07216 EXPECT_TRUE(switch_list.find(switches::kFlagSwitchesBegin) !=
217 switch_list.end());
218 EXPECT_TRUE(switch_list.find(switches::kFlagSwitchesEnd) !=
219 switch_list.end());
220 EXPECT_TRUE(switch_list.find("foo") != switch_list.end());
221
222 // Call ConvertFlagsToSwitches(), then RemoveFlagsSwitches() again.
[email protected]947446b2010-10-21 03:36:31223 CommandLine command_line(CommandLine::NO_PROGRAM);
[email protected]e2ddbc92010-10-15 20:02:07224 command_line.AppendSwitch("foo");
225 ConvertFlagsToSwitches(&prefs_, &command_line);
226 RemoveFlagsSwitches(&switch_list);
227
228 // Now the about:flags-related switch should have been removed.
229 ASSERT_EQ(1u, switch_list.size());
230 EXPECT_TRUE(switch_list.find("foo") != switch_list.end());
231}
232
[email protected]a314ee5a2010-10-26 21:23:28233// Tests enabling experiments that aren't supported on the current platform.
234TEST_F(AboutFlagsTest, PersistAndPrune) {
[email protected]8a6ff28d2010-12-02 16:35:19235 // Enable experiments 1 and 3.
[email protected]a314ee5a2010-10-26 21:23:28236 SetExperimentEnabled(&prefs_, kFlags1, true);
237 SetExperimentEnabled(&prefs_, kFlags3, true);
238 CommandLine command_line(CommandLine::NO_PROGRAM);
239 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
240 EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
241
242 // Convert the flags to switches. Experiment 3 shouldn't be among the switches
243 // as it is not applicable to the current platform.
244 ConvertFlagsToSwitches(&prefs_, &command_line);
[email protected]cd7fa99f2011-09-07 01:24:55245 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
[email protected]a314ee5a2010-10-26 21:23:28246 EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
247
248 // Experiment 3 should show still be persisted in preferences though.
249 scoped_ptr<ListValue> switch_prefs(GetFlagsExperimentsData(&prefs_));
250 ASSERT_TRUE(switch_prefs.get());
[email protected]cc3e2052011-12-20 01:01:40251 EXPECT_EQ(arraysize(kExperiments), switch_prefs->GetSize());
[email protected]8a6ff28d2010-12-02 16:35:19252}
253
[email protected]a82744532011-02-11 16:15:53254// Tests that switches which should have values get them in the command
255// line.
256TEST_F(AboutFlagsTest, CheckValues) {
257 // Enable experiments 1 and 2.
258 SetExperimentEnabled(&prefs_, kFlags1, true);
259 SetExperimentEnabled(&prefs_, kFlags2, true);
260 CommandLine command_line(CommandLine::NO_PROGRAM);
261 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
262 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
263
264 // Convert the flags to switches.
265 ConvertFlagsToSwitches(&prefs_, &command_line);
[email protected]cd7fa99f2011-09-07 01:24:55266 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
[email protected]61a4c6f2011-07-20 04:54:52267 EXPECT_EQ(std::string(""), command_line.GetSwitchValueASCII(kSwitch1));
[email protected]cd7fa99f2011-09-07 01:24:55268 EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
269 EXPECT_EQ(std::string(kValueForSwitch2),
[email protected]a82744532011-02-11 16:15:53270 command_line.GetSwitchValueASCII(kSwitch2));
271
272 // Confirm that there is no '=' in the command line for simple switches.
273 std::string switch1_with_equals = std::string("--") +
274 std::string(kSwitch1) +
275 std::string("=");
276#if defined(OS_WIN)
277 EXPECT_EQ(std::wstring::npos,
[email protected]61a4c6f2011-07-20 04:54:52278 command_line.GetCommandLineString().find(
[email protected]47e870b2013-02-24 21:14:53279 ASCIIToWide(switch1_with_equals)));
[email protected]a82744532011-02-11 16:15:53280#else
281 EXPECT_EQ(std::string::npos,
[email protected]61a4c6f2011-07-20 04:54:52282 command_line.GetCommandLineString().find(switch1_with_equals));
[email protected]a82744532011-02-11 16:15:53283#endif
284
285 // And confirm there is a '=' for switches with values.
286 std::string switch2_with_equals = std::string("--") +
287 std::string(kSwitch2) +
288 std::string("=");
[email protected]5b199522012-12-22 17:24:44289#if defined(OS_WIN)
[email protected]cd7fa99f2011-09-07 01:24:55290 EXPECT_NE(std::wstring::npos,
[email protected]61a4c6f2011-07-20 04:54:52291 command_line.GetCommandLineString().find(
[email protected]47e870b2013-02-24 21:14:53292 ASCIIToWide(switch2_with_equals)));
[email protected]a82744532011-02-11 16:15:53293#else
[email protected]cd7fa99f2011-09-07 01:24:55294 EXPECT_NE(std::string::npos,
[email protected]61a4c6f2011-07-20 04:54:52295 command_line.GetCommandLineString().find(switch2_with_equals));
[email protected]a82744532011-02-11 16:15:53296#endif
297
298 // And it should persist
299 scoped_ptr<ListValue> switch_prefs(GetFlagsExperimentsData(&prefs_));
300 ASSERT_TRUE(switch_prefs.get());
[email protected]cc3e2052011-12-20 01:01:40301 EXPECT_EQ(arraysize(kExperiments), switch_prefs->GetSize());
[email protected]a82744532011-02-11 16:15:53302}
303
[email protected]28e35af2011-02-09 12:56:22304// Tests multi-value type experiments.
[email protected]8a6ff28d2010-12-02 16:35:19305TEST_F(AboutFlagsTest, MultiValues) {
[email protected]83e9fa702013-02-25 19:30:44306 const Experiment& experiment = kExperiments[3];
307 ASSERT_EQ(kFlags4, experiment.internal_name);
308
[email protected]28e35af2011-02-09 12:56:22309 // Initially, the first "deactivated" option of the multi experiment should
310 // be set.
[email protected]8a6ff28d2010-12-02 16:35:19311 {
312 CommandLine command_line(CommandLine::NO_PROGRAM);
313 ConvertFlagsToSwitches(&prefs_, &command_line);
[email protected]28e35af2011-02-09 12:56:22314 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
[email protected]8a6ff28d2010-12-02 16:35:19315 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
316 }
317
[email protected]28e35af2011-02-09 12:56:22318 // Enable the 2nd choice of the multi-value.
[email protected]83e9fa702013-02-25 19:30:44319 SetExperimentEnabled(&prefs_, experiment.NameForChoice(2), true);
[email protected]8a6ff28d2010-12-02 16:35:19320 {
321 CommandLine command_line(CommandLine::NO_PROGRAM);
322 ConvertFlagsToSwitches(&prefs_, &command_line);
323 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
[email protected]cd7fa99f2011-09-07 01:24:55324 EXPECT_TRUE(command_line.HasSwitch(kMultiSwitch2));
325 EXPECT_EQ(std::string(kValueForMultiSwitch2),
[email protected]a82744532011-02-11 16:15:53326 command_line.GetSwitchValueASCII(kMultiSwitch2));
[email protected]8a6ff28d2010-12-02 16:35:19327 }
328
329 // Disable the multi-value experiment.
[email protected]83e9fa702013-02-25 19:30:44330 SetExperimentEnabled(&prefs_, experiment.NameForChoice(0), true);
331 {
332 CommandLine command_line(CommandLine::NO_PROGRAM);
333 ConvertFlagsToSwitches(&prefs_, &command_line);
334 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
335 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
336 }
337}
338
339TEST_F(AboutFlagsTest, EnableDisableValues) {
340 const Experiment& experiment = kExperiments[4];
341 ASSERT_EQ(kFlags5, experiment.internal_name);
342
343 // Nothing selected.
344 {
345 CommandLine command_line(CommandLine::NO_PROGRAM);
346 ConvertFlagsToSwitches(&prefs_, &command_line);
347 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
348 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
349 }
350
351 // "Enable" option selected.
352 SetExperimentEnabled(&prefs_, experiment.NameForChoice(1), true);
353 {
354 CommandLine command_line(CommandLine::NO_PROGRAM);
355 ConvertFlagsToSwitches(&prefs_, &command_line);
356 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
357 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
358 EXPECT_EQ(kEnableDisableValue1, command_line.GetSwitchValueASCII(kSwitch1));
359 }
360
361 // "Disable" option selected.
362 SetExperimentEnabled(&prefs_, experiment.NameForChoice(2), true);
363 {
364 CommandLine command_line(CommandLine::NO_PROGRAM);
365 ConvertFlagsToSwitches(&prefs_, &command_line);
366 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
367 EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
368 EXPECT_EQ(kEnableDisableValue2, command_line.GetSwitchValueASCII(kSwitch2));
369 }
370
371 // "Default" option selected, same as nothing selected.
372 SetExperimentEnabled(&prefs_, experiment.NameForChoice(0), true);
[email protected]8a6ff28d2010-12-02 16:35:19373 {
374 CommandLine command_line(CommandLine::NO_PROGRAM);
375 ConvertFlagsToSwitches(&prefs_, &command_line);
376 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
377 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
378 }
379}
380
381// Makes sure there are no separators in any of the experiment names.
382TEST_F(AboutFlagsTest, NoSeparators) {
383 testing::SetExperiments(NULL, 0);
384 size_t count;
385 const Experiment* experiments = testing::GetExperiments(&count);
386 for (size_t i = 0; i < count; ++i) {
387 std::string name = experiments->internal_name;
388 EXPECT_EQ(std::string::npos, name.find(testing::kMultiSeparator)) << i;
389 }
[email protected]a314ee5a2010-10-26 21:23:28390}
391
[email protected]e2ddbc92010-10-15 20:02:07392} // namespace about_flags