Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: chrome/browser/about_flags_unittest.cc

Issue 1411453004: Componentize internal class FlagsState in flags_ui component. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@feature_entry
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/about_flags.cc ('k') | chrome/browser/chrome_browser_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/about_flags.h" 5 #include "chrome/browser/about_flags.h"
6 6
7 #include <stdint.h> 7 #include <map>
8 #include <utility> 8 #include <set>
9 #include <string>
9 10
10 #include "base/feature_list.h" 11 #include "base/feature_list.h"
11 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
12 #include "base/format_macros.h" 13 #include "base/format_macros.h"
13 #include "base/path_service.h" 14 #include "base/path_service.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/testing_pref_service.h"
16 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h"
18 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
20 #include "base/values.h" 18 #include "base/values.h"
21 #include "chrome/common/chrome_switches.h" 19 #include "components/flags_ui/feature_entry.h"
22 #include "chrome/grit/chromium_strings.h"
23 #include "components/flags_ui/flags_ui_pref_names.h"
24 #include "components/flags_ui/pref_service_flags_storage.h"
25 #include "content/public/common/content_switches.h"
26 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/libxml/chromium/libxml_utils.h" 21 #include "third_party/libxml/chromium/libxml_utils.h"
28 22
29 using flags_ui::FeatureEntry;
30
31 namespace about_flags { 23 namespace about_flags {
32 24
33 namespace { 25 namespace {
34 26
35 const char kFlags1[] = "flag1";
36 const char kFlags2[] = "flag2";
37 const char kFlags3[] = "flag3";
38 const char kFlags4[] = "flag4";
39 const char kFlags5[] = "flag5";
40 const char kFlags6[] = "flag6";
41 const char kFlags7[] = "flag7";
42
43 const char kSwitch1[] = "switch";
44 const char kSwitch2[] = "switch2";
45 const char kSwitch3[] = "switch3";
46 const char kSwitch6[] = "switch6";
47 const char kValueForSwitch2[] = "value_for_switch2";
48
49 const char kMultiSwitch1[] = "multi_switch1";
50 const char kMultiSwitch2[] = "multi_switch2";
51 const char kValueForMultiSwitch2[] = "value_for_multi_switch2";
52
53 const char kEnableDisableValue1[] = "value1";
54 const char kEnableDisableValue2[] = "value2";
55
56 typedef base::HistogramBase::Sample Sample; 27 typedef base::HistogramBase::Sample Sample;
57 typedef std::map<std::string, Sample> SwitchToIdMap; 28 typedef std::map<std::string, Sample> SwitchToIdMap;
58 29
59 // This is a helper function to the ReadEnumFromHistogramsXml(). 30 // This is a helper function to the ReadEnumFromHistogramsXml().
60 // Extracts single enum (with integer values) from histograms.xml. 31 // Extracts single enum (with integer values) from histograms.xml.
61 // Expects |reader| to point at given enum. 32 // Expects |reader| to point at given enum.
62 // Returns map { value => label }. 33 // Returns map { value => label }.
63 // Returns empty map on error. 34 // Returns empty map on error.
64 std::map<Sample, std::string> ParseEnumFromHistogramsXml( 35 std::map<Sample, std::string> ParseEnumFromHistogramsXml(
65 const std::string& enum_name, 36 const std::string& enum_name,
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 return path; 163 return path;
193 #endif 164 #endif
194 } 165 }
195 166
196 // Get all associated switches corresponding to defined about_flags.cc entries. 167 // Get all associated switches corresponding to defined about_flags.cc entries.
197 // Does not include information about FEATURE_VALUE entries. 168 // Does not include information about FEATURE_VALUE entries.
198 std::set<std::string> GetAllSwitchesForTesting() { 169 std::set<std::string> GetAllSwitchesForTesting() {
199 std::set<std::string> result; 170 std::set<std::string> result;
200 171
201 size_t num_entries = 0; 172 size_t num_entries = 0;
202 const FeatureEntry* entries = 173 const flags_ui::FeatureEntry* entries =
203 testing::GetFeatureEntries(&num_entries); 174 testing::GetFeatureEntries(&num_entries);
204 175
205 for (size_t i = 0; i < num_entries; ++i) { 176 for (size_t i = 0; i < num_entries; ++i) {
206 const FeatureEntry& entry = entries[i]; 177 const flags_ui::FeatureEntry& entry = entries[i];
207 switch (entry.type) { 178 switch (entry.type) {
208 case FeatureEntry::SINGLE_VALUE: 179 case flags_ui::FeatureEntry::SINGLE_VALUE:
209 case FeatureEntry::SINGLE_DISABLE_VALUE: 180 case flags_ui::FeatureEntry::SINGLE_DISABLE_VALUE:
210 result.insert(entry.command_line_switch); 181 result.insert(entry.command_line_switch);
211 break; 182 break;
212 case FeatureEntry::MULTI_VALUE: 183 case flags_ui::FeatureEntry::MULTI_VALUE:
213 for (int j = 0; j < entry.num_choices; ++j) { 184 for (int j = 0; j < entry.num_choices; ++j) {
214 result.insert(entry.choices[j].command_line_switch); 185 result.insert(entry.choices[j].command_line_switch);
215 } 186 }
216 break; 187 break;
217 case FeatureEntry::ENABLE_DISABLE_VALUE: 188 case flags_ui::FeatureEntry::ENABLE_DISABLE_VALUE:
218 result.insert(entry.command_line_switch); 189 result.insert(entry.command_line_switch);
219 result.insert(entry.disable_command_line_switch); 190 result.insert(entry.disable_command_line_switch);
220 break; 191 break;
221 case FeatureEntry::FEATURE_VALUE: 192 case flags_ui::FeatureEntry::FEATURE_VALUE:
222 break; 193 break;
223 } 194 }
224 } 195 }
225 return result; 196 return result;
226 } 197 }
227 198
228 } // anonymous namespace 199 } // anonymous namespace
229 200
230 const FeatureEntry::Choice kMultiChoices[] = {
231 { IDS_PRODUCT_NAME, "", "" },
232 { IDS_PRODUCT_NAME, kMultiSwitch1, "" },
233 { IDS_PRODUCT_NAME, kMultiSwitch2, kValueForMultiSwitch2 },
234 };
235
236 const base::Feature kTestFeature{"FeatureName",
237 base::FEATURE_ENABLED_BY_DEFAULT};
238
239 // The entries that are set for these tests. The 3rd entry is not supported on
240 // the current platform, all others are.
241 static FeatureEntry kEntries[] = {
242 {kFlags1, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME,
243 0, // Ends up being mapped to the current platform.
244 FeatureEntry::SINGLE_VALUE, kSwitch1, "", nullptr, nullptr, nullptr,
245 nullptr, 0},
246 {kFlags2, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME,
247 0, // Ends up being mapped to the current platform.
248 FeatureEntry::SINGLE_VALUE, kSwitch2, kValueForSwitch2, nullptr, nullptr,
249 nullptr, nullptr, 0},
250 {kFlags3, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME,
251 0, // This ends up enabling for an OS other than the current.
252 FeatureEntry::SINGLE_VALUE, kSwitch3, "", nullptr, nullptr, nullptr,
253 nullptr, 0},
254 {kFlags4, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME,
255 0, // Ends up being mapped to the current platform.
256 FeatureEntry::MULTI_VALUE, "", "", "", "", nullptr, kMultiChoices,
257 arraysize(kMultiChoices)},
258 {kFlags5, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME,
259 0, // Ends up being mapped to the current platform.
260 FeatureEntry::ENABLE_DISABLE_VALUE, kSwitch1, kEnableDisableValue1,
261 kSwitch2, kEnableDisableValue2, nullptr, nullptr, 3},
262 {kFlags6, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, 0,
263 FeatureEntry::SINGLE_DISABLE_VALUE, kSwitch6, "", nullptr, nullptr,
264 nullptr, nullptr, 0},
265 {kFlags7, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME,
266 0, // Ends up being mapped to the current platform.
267 FeatureEntry::FEATURE_VALUE, nullptr, nullptr, nullptr, nullptr,
268 &kTestFeature, nullptr, 3},
269 };
270
271 class AboutFlagsTest : public ::testing::Test {
272 protected:
273 AboutFlagsTest() : flags_storage_(&prefs_) {
274 prefs_.registry()->RegisterListPref(
275 flags_ui::prefs::kEnabledLabsExperiments);
276 testing::ClearState();
277 }
278
279 void SetUp() override {
280 for (size_t i = 0; i < arraysize(kEntries); ++i)
281 kEntries[i].supported_platforms = GetCurrentPlatform();
282
283 int os_other_than_current = 1;
284 while (os_other_than_current == GetCurrentPlatform())
285 os_other_than_current <<= 1;
286 kEntries[2].supported_platforms = os_other_than_current;
287
288 testing::SetFeatureEntries(kEntries, arraysize(kEntries));
289 }
290
291 void TearDown() override { testing::SetFeatureEntries(nullptr, 0); }
292
293 TestingPrefServiceSimple prefs_;
294 flags_ui::PrefServiceFlagsStorage flags_storage_;
295 };
296
297
298 TEST_F(AboutFlagsTest, NoChangeNoRestart) {
299 EXPECT_FALSE(IsRestartNeededToCommitChanges());
300 SetFeatureEntryEnabled(&flags_storage_, kFlags1, false);
301 EXPECT_FALSE(IsRestartNeededToCommitChanges());
302
303 // kFlags6 is enabled by default, so enabling should not require a restart.
304 SetFeatureEntryEnabled(&flags_storage_, kFlags6, true);
305 EXPECT_FALSE(IsRestartNeededToCommitChanges());
306 }
307
308 TEST_F(AboutFlagsTest, ChangeNeedsRestart) {
309 EXPECT_FALSE(IsRestartNeededToCommitChanges());
310 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
311 EXPECT_TRUE(IsRestartNeededToCommitChanges());
312 }
313
314 // Tests that disabling a default enabled entry requires a restart.
315 TEST_F(AboutFlagsTest, DisableChangeNeedsRestart) {
316 EXPECT_FALSE(IsRestartNeededToCommitChanges());
317 SetFeatureEntryEnabled(&flags_storage_, kFlags6, false);
318 EXPECT_TRUE(IsRestartNeededToCommitChanges());
319 }
320
321 TEST_F(AboutFlagsTest, MultiFlagChangeNeedsRestart) {
322 const FeatureEntry& entry = kEntries[3];
323 ASSERT_EQ(kFlags4, entry.internal_name);
324 EXPECT_FALSE(IsRestartNeededToCommitChanges());
325 // Enable the 2nd choice of the multi-value.
326 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2), true);
327 EXPECT_TRUE(IsRestartNeededToCommitChanges());
328 testing::ClearState();
329 EXPECT_FALSE(IsRestartNeededToCommitChanges());
330 // Enable the default choice now.
331 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0), true);
332 EXPECT_TRUE(IsRestartNeededToCommitChanges());
333 }
334
335 TEST_F(AboutFlagsTest, AddTwoFlagsRemoveOne) {
336 // Add two entries, check they're there.
337 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
338 SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
339
340 const base::ListValue* entries_list =
341 prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments);
342 ASSERT_TRUE(entries_list != nullptr);
343
344 ASSERT_EQ(2u, entries_list->GetSize());
345
346 std::string s0;
347 ASSERT_TRUE(entries_list->GetString(0, &s0));
348 std::string s1;
349 ASSERT_TRUE(entries_list->GetString(1, &s1));
350
351 EXPECT_TRUE(s0 == kFlags1 || s1 == kFlags1);
352 EXPECT_TRUE(s0 == kFlags2 || s1 == kFlags2);
353
354 // Remove one entry, check the other's still around.
355 SetFeatureEntryEnabled(&flags_storage_, kFlags2, false);
356
357 entries_list = prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments);
358 ASSERT_TRUE(entries_list != nullptr);
359 ASSERT_EQ(1u, entries_list->GetSize());
360 ASSERT_TRUE(entries_list->GetString(0, &s0));
361 EXPECT_TRUE(s0 == kFlags1);
362 }
363
364 TEST_F(AboutFlagsTest, AddTwoFlagsRemoveBoth) {
365 // Add two entries, check the pref exists.
366 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
367 SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
368 const base::ListValue* entries_list =
369 prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments);
370 ASSERT_TRUE(entries_list != nullptr);
371
372 // Remove both, the pref should have been removed completely.
373 SetFeatureEntryEnabled(&flags_storage_, kFlags1, false);
374 SetFeatureEntryEnabled(&flags_storage_, kFlags2, false);
375 entries_list = prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments);
376 EXPECT_TRUE(entries_list == nullptr || entries_list->GetSize() == 0);
377 }
378
379 TEST_F(AboutFlagsTest, ConvertFlagsToSwitches) {
380 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
381
382 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
383 command_line.AppendSwitch("foo");
384
385 EXPECT_TRUE(command_line.HasSwitch("foo"));
386 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
387
388 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
389
390 EXPECT_TRUE(command_line.HasSwitch("foo"));
391 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
392 EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesBegin));
393 EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesEnd));
394
395 base::CommandLine command_line2(base::CommandLine::NO_PROGRAM);
396
397 ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels);
398
399 EXPECT_TRUE(command_line2.HasSwitch(kSwitch1));
400 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin));
401 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd));
402 }
403
404 base::CommandLine::StringType CreateSwitch(const std::string& value) {
405 #if defined(OS_WIN)
406 return base::ASCIIToUTF16(value);
407 #else
408 return value;
409 #endif
410 }
411
412 TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) {
413 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
414
415 const std::string kDoubleDash("--");
416
417 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
418 command_line.AppendSwitch("foo");
419
420 base::CommandLine new_command_line(base::CommandLine::NO_PROGRAM);
421 ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels);
422
423 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line,
424 command_line, nullptr));
425 {
426 std::set<base::CommandLine::StringType> difference;
427 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
428 new_command_line, command_line, &difference));
429 EXPECT_EQ(1U, difference.size());
430 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
431 }
432
433 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
434
435 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line,
436 command_line, nullptr));
437 {
438 std::set<base::CommandLine::StringType> difference;
439 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(
440 new_command_line, command_line, &difference));
441 EXPECT_TRUE(difference.empty());
442 }
443
444 // Now both have flags but different.
445 SetFeatureEntryEnabled(&flags_storage_, kFlags1, false);
446 SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
447
448 base::CommandLine another_command_line(base::CommandLine::NO_PROGRAM);
449 ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels);
450
451 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
452 new_command_line, another_command_line, nullptr));
453 {
454 std::set<base::CommandLine::StringType> difference;
455 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
456 new_command_line, another_command_line, &difference));
457 EXPECT_EQ(2U, difference.size());
458 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
459 EXPECT_EQ(1U,
460 difference.count(CreateSwitch(kDoubleDash + kSwitch2 + "=" +
461 kValueForSwitch2)));
462 }
463 }
464
465 TEST_F(AboutFlagsTest, RemoveFlagSwitches) {
466 std::map<std::string, base::CommandLine::StringType> switch_list;
467 switch_list[kSwitch1] = base::CommandLine::StringType();
468 switch_list[switches::kFlagSwitchesBegin] = base::CommandLine::StringType();
469 switch_list[switches::kFlagSwitchesEnd] = base::CommandLine::StringType();
470 switch_list["foo"] = base::CommandLine::StringType();
471
472 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
473
474 // This shouldn't do anything before ConvertFlagsToSwitches() wasn't called.
475 RemoveFlagsSwitches(&switch_list);
476 ASSERT_EQ(4u, switch_list.size());
477 EXPECT_TRUE(ContainsKey(switch_list, kSwitch1));
478 EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesBegin));
479 EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesEnd));
480 EXPECT_TRUE(ContainsKey(switch_list, "foo"));
481
482 // Call ConvertFlagsToSwitches(), then RemoveFlagsSwitches() again.
483 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
484 command_line.AppendSwitch("foo");
485 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
486 RemoveFlagsSwitches(&switch_list);
487
488 // Now the about:flags-related switch should have been removed.
489 ASSERT_EQ(1u, switch_list.size());
490 EXPECT_TRUE(ContainsKey(switch_list, "foo"));
491 }
492
493 TEST_F(AboutFlagsTest, RemoveFlagSwitches_Features) {
494 struct {
495 int enabled_choice; // 0: default, 1: enabled, 2: disabled.
496 const char* existing_enable_features;
497 const char* existing_disable_features;
498 const char* expected_enable_features;
499 const char* expected_disable_features;
500 } cases[] = {
501 // Default value: Should not affect existing flags.
502 {0, nullptr, nullptr, nullptr, nullptr},
503 {0, "A,B", "C", "A,B", "C"},
504 // "Enable" option: should only affect enabled list.
505 {1, nullptr, nullptr, "FeatureName", nullptr},
506 {1, "A,B", "C", "A,B,FeatureName", "C"},
507 // "Disable" option: should only affect disabled list.
508 {2, nullptr, nullptr, nullptr, "FeatureName"},
509 {2, "A,B", "C", "A,B", "C,FeatureName"},
510 };
511
512 for (size_t i = 0; i < arraysize(cases); ++i) {
513 SCOPED_TRACE(base::StringPrintf(
514 "Test[%" PRIuS "]: %d [%s] [%s]", i, cases[i].enabled_choice,
515 cases[i].existing_enable_features ? cases[i].existing_enable_features
516 : "null",
517 cases[i].existing_disable_features ? cases[i].existing_disable_features
518 : "null"));
519
520 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
521 if (cases[i].existing_enable_features) {
522 command_line.AppendSwitchASCII(switches::kEnableFeatures,
523 cases[i].existing_enable_features);
524 }
525 if (cases[i].existing_disable_features) {
526 command_line.AppendSwitchASCII(switches::kDisableFeatures,
527 cases[i].existing_disable_features);
528 }
529
530 testing::ClearState();
531
532 const std::string entry_name = base::StringPrintf(
533 "%s%s%d", kFlags7, flags_ui::testing::kMultiSeparator,
534 cases[i].enabled_choice);
535 SetFeatureEntryEnabled(&flags_storage_, entry_name, true);
536
537 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
538 auto switch_list = command_line.GetSwitches();
539 EXPECT_EQ(cases[i].expected_enable_features != nullptr,
540 ContainsKey(switch_list, switches::kEnableFeatures));
541 if (cases[i].expected_enable_features)
542 EXPECT_EQ(CreateSwitch(cases[i].expected_enable_features),
543 switch_list[switches::kEnableFeatures]);
544
545 EXPECT_EQ(cases[i].expected_disable_features != nullptr,
546 ContainsKey(switch_list, switches::kDisableFeatures));
547 if (cases[i].expected_disable_features)
548 EXPECT_EQ(CreateSwitch(cases[i].expected_disable_features),
549 switch_list[switches::kDisableFeatures]);
550
551 // RemoveFlagsSwitches() should result in the original values for these
552 // switches.
553 switch_list = command_line.GetSwitches();
554 RemoveFlagsSwitches(&switch_list);
555 EXPECT_EQ(cases[i].existing_enable_features != nullptr,
556 ContainsKey(switch_list, switches::kEnableFeatures));
557 if (cases[i].existing_enable_features)
558 EXPECT_EQ(CreateSwitch(cases[i].existing_enable_features),
559 switch_list[switches::kEnableFeatures]);
560 EXPECT_EQ(cases[i].existing_disable_features != nullptr,
561 ContainsKey(switch_list, switches::kEnableFeatures));
562 if (cases[i].existing_disable_features)
563 EXPECT_EQ(CreateSwitch(cases[i].existing_disable_features),
564 switch_list[switches::kDisableFeatures]);
565 }
566 }
567
568 // Tests enabling entries that aren't supported on the current platform.
569 TEST_F(AboutFlagsTest, PersistAndPrune) {
570 // Enable entries 1 and 3.
571 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
572 SetFeatureEntryEnabled(&flags_storage_, kFlags3, true);
573 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
574 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
575 EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
576
577 // Convert the flags to switches. Entry 3 shouldn't be among the switches
578 // as it is not applicable to the current platform.
579 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
580 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
581 EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
582
583 // FeatureEntry 3 should show still be persisted in preferences though.
584 const base::ListValue* entries_list =
585 prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments);
586 ASSERT_TRUE(entries_list);
587 EXPECT_EQ(2U, entries_list->GetSize());
588 std::string s0;
589 ASSERT_TRUE(entries_list->GetString(0, &s0));
590 EXPECT_EQ(kFlags1, s0);
591 std::string s1;
592 ASSERT_TRUE(entries_list->GetString(1, &s1));
593 EXPECT_EQ(kFlags3, s1);
594 }
595
596 // Tests that switches which should have values get them in the command
597 // line.
598 TEST_F(AboutFlagsTest, CheckValues) {
599 // Enable entries 1 and 2.
600 SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
601 SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
602 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
603 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
604 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
605
606 // Convert the flags to switches.
607 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
608 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
609 EXPECT_EQ(std::string(), command_line.GetSwitchValueASCII(kSwitch1));
610 EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
611 EXPECT_EQ(std::string(kValueForSwitch2),
612 command_line.GetSwitchValueASCII(kSwitch2));
613
614 // Confirm that there is no '=' in the command line for simple switches.
615 std::string switch1_with_equals = std::string("--") +
616 std::string(kSwitch1) +
617 std::string("=");
618 #if defined(OS_WIN)
619 EXPECT_EQ(base::string16::npos,
620 command_line.GetCommandLineString().find(
621 base::ASCIIToUTF16(switch1_with_equals)));
622 #else
623 EXPECT_EQ(std::string::npos,
624 command_line.GetCommandLineString().find(switch1_with_equals));
625 #endif
626
627 // And confirm there is a '=' for switches with values.
628 std::string switch2_with_equals = std::string("--") +
629 std::string(kSwitch2) +
630 std::string("=");
631 #if defined(OS_WIN)
632 EXPECT_NE(base::string16::npos,
633 command_line.GetCommandLineString().find(
634 base::ASCIIToUTF16(switch2_with_equals)));
635 #else
636 EXPECT_NE(std::string::npos,
637 command_line.GetCommandLineString().find(switch2_with_equals));
638 #endif
639
640 // And it should persist.
641 const base::ListValue* entries_list =
642 prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments);
643 ASSERT_TRUE(entries_list);
644 EXPECT_EQ(2U, entries_list->GetSize());
645 std::string s0;
646 ASSERT_TRUE(entries_list->GetString(0, &s0));
647 EXPECT_EQ(kFlags1, s0);
648 std::string s1;
649 ASSERT_TRUE(entries_list->GetString(1, &s1));
650 EXPECT_EQ(kFlags2, s1);
651 }
652
653 // Tests multi-value type entries.
654 TEST_F(AboutFlagsTest, MultiValues) {
655 const FeatureEntry& entry = kEntries[3];
656 ASSERT_EQ(kFlags4, entry.internal_name);
657
658 // Initially, the first "deactivated" option of the multi entry should
659 // be set.
660 {
661 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
662 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
663 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
664 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
665 }
666
667 // Enable the 2nd choice of the multi-value.
668 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2), true);
669 {
670 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
671 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
672 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
673 EXPECT_TRUE(command_line.HasSwitch(kMultiSwitch2));
674 EXPECT_EQ(std::string(kValueForMultiSwitch2),
675 command_line.GetSwitchValueASCII(kMultiSwitch2));
676 }
677
678 // Disable the multi-value entry.
679 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0), true);
680 {
681 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
682 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
683 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
684 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
685 }
686 }
687
688 // Tests that disable flags are added when an entry is disabled.
689 TEST_F(AboutFlagsTest, DisableFlagCommandLine) {
690 // Nothing selected.
691 {
692 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
693 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
694 EXPECT_FALSE(command_line.HasSwitch(kSwitch6));
695 }
696
697 // Disable the entry 6.
698 SetFeatureEntryEnabled(&flags_storage_, kFlags6, false);
699 {
700 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
701 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
702 EXPECT_TRUE(command_line.HasSwitch(kSwitch6));
703 }
704
705 // Enable entry 6.
706 SetFeatureEntryEnabled(&flags_storage_, kFlags6, true);
707 {
708 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
709 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
710 EXPECT_FALSE(command_line.HasSwitch(kSwitch6));
711 }
712 }
713
714 TEST_F(AboutFlagsTest, EnableDisableValues) {
715 const FeatureEntry& entry = kEntries[4];
716 ASSERT_EQ(kFlags5, entry.internal_name);
717
718 // Nothing selected.
719 {
720 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
721 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
722 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
723 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
724 }
725
726 // "Enable" option selected.
727 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(1), true);
728 {
729 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
730 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
731 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
732 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
733 EXPECT_EQ(kEnableDisableValue1, command_line.GetSwitchValueASCII(kSwitch1));
734 }
735
736 // "Disable" option selected.
737 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2), true);
738 {
739 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
740 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
741 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
742 EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
743 EXPECT_EQ(kEnableDisableValue2, command_line.GetSwitchValueASCII(kSwitch2));
744 }
745
746 // "Default" option selected, same as nothing selected.
747 SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0), true);
748 {
749 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
750 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
751 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
752 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
753 }
754 }
755
756 TEST_F(AboutFlagsTest, FeatureValues) {
757 const FeatureEntry& entry = kEntries[6];
758 ASSERT_EQ(kFlags7, entry.internal_name);
759
760 struct {
761 int enabled_choice;
762 const char* existing_enable_features;
763 const char* existing_disable_features;
764 const char* expected_enable_features;
765 const char* expected_disable_features;
766 } cases[] = {
767 // Nothing selected.
768 {-1, nullptr, nullptr, "", ""},
769 // "Default" option selected, same as nothing selected.
770 {0, nullptr, nullptr, "", ""},
771 // "Enable" option selected.
772 {1, nullptr, nullptr, "FeatureName", ""},
773 // "Disable" option selected.
774 {2, nullptr, nullptr, "", "FeatureName"},
775 // "Enable" option should get added to the existing list.
776 {1, "Foo,Bar", nullptr, "Foo,Bar,FeatureName", ""},
777 // "Disable" option should get added to the existing list.
778 {2, nullptr, "Foo,Bar", "", "Foo,Bar,FeatureName"},
779 };
780
781 for (size_t i = 0; i < arraysize(cases); ++i) {
782 SCOPED_TRACE(base::StringPrintf(
783 "Test[%" PRIuS "]: %d [%s] [%s]", i, cases[i].enabled_choice,
784 cases[i].existing_enable_features ? cases[i].existing_enable_features
785 : "null",
786 cases[i].existing_disable_features ? cases[i].existing_disable_features
787 : "null"));
788
789 if (cases[i].enabled_choice != -1) {
790 SetFeatureEntryEnabled(
791 &flags_storage_, entry.NameForChoice(cases[i].enabled_choice), true);
792 }
793
794 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
795 if (cases[i].existing_enable_features) {
796 command_line.AppendSwitchASCII(switches::kEnableFeatures,
797 cases[i].existing_enable_features);
798 }
799 if (cases[i].existing_disable_features) {
800 command_line.AppendSwitchASCII(switches::kDisableFeatures,
801 cases[i].existing_disable_features);
802 }
803
804 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
805 EXPECT_EQ(cases[i].expected_enable_features,
806 command_line.GetSwitchValueASCII(switches::kEnableFeatures));
807 EXPECT_EQ(cases[i].expected_disable_features,
808 command_line.GetSwitchValueASCII(switches::kDisableFeatures));
809 }
810 }
811
812 // Makes sure there are no separators in any of the entry names. 201 // Makes sure there are no separators in any of the entry names.
813 TEST_F(AboutFlagsTest, NoSeparators) { 202 TEST(AboutFlagsTest, NoSeparators) {
814 testing::SetFeatureEntries(nullptr, 0);
815 size_t count; 203 size_t count;
816 const FeatureEntry* entries = testing::GetFeatureEntries(&count); 204 const flags_ui::FeatureEntry* entries = testing::GetFeatureEntries(&count);
817 for (size_t i = 0; i < count; ++i) { 205 for (size_t i = 0; i < count; ++i) {
818 std::string name = entries[i].internal_name; 206 std::string name = entries[i].internal_name;
819 EXPECT_EQ(std::string::npos, name.find(flags_ui::testing::kMultiSeparator)) 207 EXPECT_EQ(std::string::npos, name.find(flags_ui::testing::kMultiSeparator))
820 << i; 208 << i;
821 } 209 }
822 } 210 }
823 211
824 TEST_F(AboutFlagsTest, GetFlagFeatureEntries) {
825 base::ListValue supported_entries;
826 base::ListValue unsupported_entries;
827 GetFlagFeatureEntries(&flags_storage_, kGeneralAccessFlagsOnly,
828 &supported_entries, &unsupported_entries);
829 // All |kEntries| except for |kFlags3| should be supported.
830 EXPECT_EQ(6u, supported_entries.GetSize());
831 EXPECT_EQ(1u, unsupported_entries.GetSize());
832 EXPECT_EQ(arraysize(kEntries),
833 supported_entries.GetSize() + unsupported_entries.GetSize());
834 }
835
836 class AboutFlagsHistogramTest : public ::testing::Test { 212 class AboutFlagsHistogramTest : public ::testing::Test {
837 protected: 213 protected:
838 // This is a helper function to check that all IDs in enum LoginCustomFlags in 214 // This is a helper function to check that all IDs in enum LoginCustomFlags in
839 // histograms.xml are unique. 215 // histograms.xml are unique.
840 void SetSwitchToHistogramIdMapping(const std::string& switch_name, 216 void SetSwitchToHistogramIdMapping(const std::string& switch_name,
841 const Sample switch_histogram_id, 217 const Sample switch_histogram_id,
842 std::map<std::string, Sample>* out_map) { 218 std::map<std::string, Sample>* out_map) {
843 const std::pair<std::map<std::string, Sample>::iterator, bool> status = 219 const std::pair<std::map<std::string, Sample>::iterator, bool> status =
844 out_map->insert(std::make_pair(switch_name, switch_histogram_id)); 220 out_map->insert(std::make_pair(switch_name, switch_histogram_id));
845 if (!status.second) { 221 if (!status.second) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 EXPECT_TRUE(enum_entry != histograms_xml_switches_ids.end() && 298 EXPECT_TRUE(enum_entry != histograms_xml_switches_ids.end() &&
923 enum_entry->first == flag) 299 enum_entry->first == flag)
924 << "histograms.xml enum LoginCustomFlags doesn't contain switch '" 300 << "histograms.xml enum LoginCustomFlags doesn't contain switch '"
925 << flag << "' (value=" << uma_id 301 << flag << "' (value=" << uma_id
926 << " expected). Consider adding entry:\n" 302 << " expected). Consider adding entry:\n"
927 << " " << GetHistogramEnumEntryText(flag, uma_id); 303 << " " << GetHistogramEnumEntryText(flag, uma_id);
928 } 304 }
929 } 305 }
930 306
931 } // namespace about_flags 307 } // namespace about_flags
OLDNEW
« no previous file with comments | « chrome/browser/about_flags.cc ('k') | chrome/browser/chrome_browser_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698