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

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

Issue 344883002: Collect UMA statistics on which chrome://flags lead to chrome restart on ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update after review. Created 6 years, 4 months 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
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 "base/files/file_path.h"
6 #include "base/memory/scoped_vector.h"
7 #include "base/path_service.h"
5 #include "base/prefs/pref_registry_simple.h" 8 #include "base/prefs/pref_registry_simple.h"
6 #include "base/prefs/testing_pref_service.h" 9 #include "base/prefs/testing_pref_service.h"
7 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h" 12 #include "base/values.h"
10 #include "chrome/browser/about_flags.h" 13 #include "chrome/browser/about_flags.h"
11 #include "chrome/browser/pref_service_flags_storage.h" 14 #include "chrome/browser/pref_service_flags_storage.h"
12 #include "chrome/common/chrome_switches.h" 15 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
14 #include "grit/chromium_strings.h" 17 #include "grit/chromium_strings.h"
15 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/libxml/chromium/libxml_utils.h"
20
21 namespace {
16 22
17 const char kFlags1[] = "flag1"; 23 const char kFlags1[] = "flag1";
18 const char kFlags2[] = "flag2"; 24 const char kFlags2[] = "flag2";
19 const char kFlags3[] = "flag3"; 25 const char kFlags3[] = "flag3";
20 const char kFlags4[] = "flag4"; 26 const char kFlags4[] = "flag4";
21 const char kFlags5[] = "flag5"; 27 const char kFlags5[] = "flag5";
22 28
23 const char kSwitch1[] = "switch"; 29 const char kSwitch1[] = "switch";
24 const char kSwitch2[] = "switch2"; 30 const char kSwitch2[] = "switch2";
25 const char kSwitch3[] = "switch3"; 31 const char kSwitch3[] = "switch3";
26 const char kValueForSwitch2[] = "value_for_switch2"; 32 const char kValueForSwitch2[] = "value_for_switch2";
27 33
28 const char kMultiSwitch1[] = "multi_switch1"; 34 const char kMultiSwitch1[] = "multi_switch1";
29 const char kMultiSwitch2[] = "multi_switch2"; 35 const char kMultiSwitch2[] = "multi_switch2";
30 const char kValueForMultiSwitch2[] = "value_for_multi_switch2"; 36 const char kValueForMultiSwitch2[] = "value_for_multi_switch2";
31 37
32 const char kEnableDisableValue1[] = "value1"; 38 const char kEnableDisableValue1[] = "value1";
33 const char kEnableDisableValue2[] = "value2"; 39 const char kEnableDisableValue2[] = "value2";
34 40
41 std::map<int, std::string> ParseEnumFromHistogramsXml(
42 const std::string& enum_name,
43 XmlReader& reader);
Ilya Sherman 2014/07/31 00:37:51 Please define the function here, rather than forwa
Alexander Alekseev 2014/07/31 01:32:06 Done.
44
45 // Find and read given enum (with integer values) from histograms.xml.
46 // |enum_name| - enum name.
47 // |histograms_xml| - must be loaded histograms.xml file.
48 //
49 // Returns map { value => label } so that:
50 // <int value="9" label="enable-pinch-virtual-viewport"/>
51 // becomes:
52 // { 9 => "enable-pinch-virtual-viewport" }
53 // Returns empty map on error.
54 std::map<int, std::string> ReadEnumFromHistogramsXml(
55 const std::string& enum_name,
56 XmlReader& histograms_xml) {
Ilya Sherman 2014/07/31 00:37:51 nit: Variables should be passed either by const-re
Alexander Alekseev 2014/07/31 01:32:06 Done.
57 std::map<int, std::string> login_custom_flags;
58
59 // Implement simple DFS.
Ilya Sherman 2014/07/31 00:37:51 nit: "DFS" -> "depth first search"
Alexander Alekseev 2014/07/31 01:32:06 Done.
60 while (true) {
61 const std::string node_name = histograms_xml.NodeName();
62 if (node_name == "enum") {
63 std::string name;
64 if (histograms_xml.NodeAttribute("name", &name) && name == enum_name) {
65 if (!login_custom_flags.empty()) {
66 EXPECT_TRUE(login_custom_flags.empty())
67 << "Duplicate enum '" << enum_name << "' found in histograms.xml";
68 return std::map<int, std::string>();
69 }
70
71 const bool got_into_enum = histograms_xml.Read();
72 if (got_into_enum) {
73 login_custom_flags =
74 ParseEnumFromHistogramsXml(enum_name, histograms_xml);
75 EXPECT_FALSE(login_custom_flags.empty())
76 << "Bad enum '" << enum_name
77 << "' found in histograms.xml (format error).";
78 } else {
79 EXPECT_TRUE(got_into_enum)
80 << "Bad enum '" << enum_name
81 << "' (looks empty) found in histograms.xml.";
82 }
83 if (login_custom_flags.empty())
84 return std::map<int, std::string>();
85 }
86 }
87 // Go deeper if possible (stops at the closing tag of the deepest node).
88 if (histograms_xml.Read())
89 continue;
90
91 // Try next node on the same level (skips closing tag).
92 if (histograms_xml.Next())
93 continue;
94
95 // Go up until next node on the same level exists.
96 while (histograms_xml.Depth() && !histograms_xml.SkipToElement()) {
97 }
98
99 // Reached top. histograms.xml consists of the single top level node
100 // 'histogram-configuration', so this is the end.
101 if (!histograms_xml.Depth())
102 break;
103 }
104 EXPECT_FALSE(login_custom_flags.empty())
105 << "Enum '" << enum_name << "' is not found in histograms.xml.";
106 return login_custom_flags;
107 }
108
109 // This is a helper function to the previous one.
110 // Extracts single enum (with integer values) from histograms.xml.
111 // Expects |reader| to point at given enum.
112 // Returns map { value => label }.
113 // Returns empty map on error.
114 std::map<int, std::string> ParseEnumFromHistogramsXml(
115 const std::string& enum_name,
116 XmlReader& reader) {
Ilya Sherman 2014/07/31 00:37:51 Ditto.
Alexander Alekseev 2014/07/31 01:32:06 Done.
117 int entries_index = -1;
118
119 std::map<int, std::string> result;
120 bool success = true;
121
122 while (true) {
123 const std::string node_name = reader.NodeName();
124 if (node_name == "enum" && reader.IsClosingElement())
125 break;
126
127 if (node_name == "int") {
128 ++entries_index;
129 std::string value_str;
130 std::string label;
131 const bool has_value = reader.NodeAttribute("value", &value_str);
132 const bool has_label = reader.NodeAttribute("label", &label);
133 if (!has_value) {
134 ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
135 << entries_index << ", label='" << label
136 << "'): No 'value' attribute.";
137 success = false;
138 }
139 if (!has_label) {
140 ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
141 << entries_index << ", value_str='" << value_str
142 << "'): No 'label' attribute.";
143 success = false;
144 }
145
146 int value;
147 if (has_value && !base::StringToInt(value_str, &value)) {
148 ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
149 << entries_index << ", label='" << label
150 << "', value_str='" << value_str
151 << "'): 'value' attribute is not integer.";
152 success = false;
153 }
154 if (success) {
155 result[value] = label;
156 }
157 }
158 // All enum entries are on the same level, so it is enough to iterate
159 // until possible.
160 reader.Next();
161 }
162 return (success ? result : std::map<int, std::string>());
163 }
164
165 std::string FilePathStringTypeToString(const base::FilePath::StringType& path) {
166 #if defined(OS_WIN)
167 return UTF16ToUTF8(path);
168 #else
169 return path;
170 #endif
171 }
172
173 } // anonymous namespace
174
35 namespace about_flags { 175 namespace about_flags {
36 176
177 enum TestSwitchesHistogramIDs {
178 ID_UNKNOWN_FLAG = UMA_HISTOGRAM_ID_UNKNOWN_FLAG,
179 ID_BAD_FLAG_FORMAT = UMA_HISTOGRAM_ID_BAD_FLAG_FORMAT,
180 ID_kMultiSwitch1,
181 ID_kMultiSwitch2,
182 ID_kSwitch1,
183 ID_kSwitch2,
184 ID_kSwitch3,
185 };
186
187 #define ID(x) static_cast<const about_flags::SwitchesUmaHistogramId>(x)
188
37 const Experiment::Choice kMultiChoices[] = { 189 const Experiment::Choice kMultiChoices[] = {
38 { IDS_PRODUCT_NAME, "", "" }, 190 { IDS_PRODUCT_NAME, "", "", ID(ID_UNKNOWN_FLAG) },
39 { IDS_PRODUCT_NAME, kMultiSwitch1, "" }, 191 { IDS_PRODUCT_NAME, kMultiSwitch1, "", ID(ID_kMultiSwitch1) },
40 { IDS_PRODUCT_NAME, kMultiSwitch2, kValueForMultiSwitch2 }, 192 { IDS_PRODUCT_NAME,
193 kMultiSwitch2, kValueForMultiSwitch2, ID(ID_kMultiSwitch2) },
41 }; 194 };
42 195
196 #undef ID
197
43 // The experiments that are set for these tests. The 3rd experiment is not 198 // The experiments that are set for these tests. The 3rd experiment is not
44 // supported on the current platform, all others are. 199 // supported on the current platform, all others are.
45 static Experiment kExperiments[] = { 200 static Experiment kExperiments[] = {
46 { 201 {
47 kFlags1, 202 kFlags1,
48 IDS_PRODUCT_NAME, 203 IDS_PRODUCT_NAME,
49 IDS_PRODUCT_NAME, 204 IDS_PRODUCT_NAME,
50 0, // Ends up being mapped to the current platform. 205 0, // Ends up being mapped to the current platform.
51 Experiment::SINGLE_VALUE, 206 Experiment::SINGLE_VALUE,
52 kSwitch1, 207 kSwitch1,
53 "", 208 "",
209 ID_kSwitch1,
54 NULL, 210 NULL,
55 NULL, 211 NULL,
212 0,
56 NULL, 213 NULL,
57 0 214 0
58 }, 215 },
59 { 216 {
60 kFlags2, 217 kFlags2,
61 IDS_PRODUCT_NAME, 218 IDS_PRODUCT_NAME,
62 IDS_PRODUCT_NAME, 219 IDS_PRODUCT_NAME,
63 0, // Ends up being mapped to the current platform. 220 0, // Ends up being mapped to the current platform.
64 Experiment::SINGLE_VALUE, 221 Experiment::SINGLE_VALUE,
65 kSwitch2, 222 kSwitch2,
66 kValueForSwitch2, 223 kValueForSwitch2,
224 ID_kSwitch2,
67 NULL, 225 NULL,
68 NULL, 226 NULL,
227 0,
69 NULL, 228 NULL,
70 0 229 0
71 }, 230 },
72 { 231 {
73 kFlags3, 232 kFlags3,
74 IDS_PRODUCT_NAME, 233 IDS_PRODUCT_NAME,
75 IDS_PRODUCT_NAME, 234 IDS_PRODUCT_NAME,
76 0, // This ends up enabling for an OS other than the current. 235 0, // This ends up enabling for an OS other than the current.
77 Experiment::SINGLE_VALUE, 236 Experiment::SINGLE_VALUE,
78 kSwitch3, 237 kSwitch3,
79 "", 238 "",
239 ID_kSwitch3,
80 NULL, 240 NULL,
81 NULL, 241 NULL,
242 0,
82 NULL, 243 NULL,
83 0 244 0
84 }, 245 },
85 { 246 {
86 kFlags4, 247 kFlags4,
87 IDS_PRODUCT_NAME, 248 IDS_PRODUCT_NAME,
88 IDS_PRODUCT_NAME, 249 IDS_PRODUCT_NAME,
89 0, // Ends up being mapped to the current platform. 250 0, // Ends up being mapped to the current platform.
90 Experiment::MULTI_VALUE, 251 Experiment::MULTI_VALUE,
91 "", 252 "",
92 "", 253 "",
254 0,
93 "", 255 "",
94 "", 256 "",
257 0,
95 kMultiChoices, 258 kMultiChoices,
96 arraysize(kMultiChoices) 259 arraysize(kMultiChoices)
97 }, 260 },
98 { 261 {
99 kFlags5, 262 kFlags5,
100 IDS_PRODUCT_NAME, 263 IDS_PRODUCT_NAME,
101 IDS_PRODUCT_NAME, 264 IDS_PRODUCT_NAME,
102 0, // Ends up being mapped to the current platform. 265 0, // Ends up being mapped to the current platform.
103 Experiment::ENABLE_DISABLE_VALUE, 266 Experiment::ENABLE_DISABLE_VALUE,
104 kSwitch1, 267 kSwitch1,
105 kEnableDisableValue1, 268 kEnableDisableValue1,
269 ID_kSwitch1,
106 kSwitch2, 270 kSwitch2,
107 kEnableDisableValue2, 271 kEnableDisableValue2,
272 ID_kSwitch2,
108 NULL, 273 NULL,
109 3 274 3
110 }, 275 },
111 }; 276 };
112 277
278 /*
279 This table contains histogram IDs for switches. Switch ID must never change!
280 */
281 const char* const HistogramSwitchesOrdered[] = {
282 NULL, /* No flag */
283 NULL, /* Bad flag format */
284 NULL, /* reserved */
285 NULL, /* reserved */
286 NULL, /* reserved */
287 "disable-webrtc-hw-encoding",
288 "disable-minimize-on-second-launcher-item-click",
289 "disable-virtual-keyboard-overscroll",
290 "disable-virtual-keyboard-overscroll",
291 "enable-pinch-virtual-viewport",
292 "prefetch-search-results",
293 "enable-experimental-app-list",
294 "enable-devtools-experiments",
295 "enable-centered-app-list",
296 "enable-accelerated-overflow-scroll",
297 "enable-tcp-fastopen",
298 "enable-zero-suggest-personalized",
299 "enable-experimental-web-platform-features",
300 "use-simple-cache-backend",
301 "disable-search-button-in-omnibox",
302 "file-manager-enable-new-audio-player",
303 "disable-prefixed-encrypted-media",
304 "disable-origin-chip",
305 "disable-touch-adjustment",
306 "disable-offline-auto-reload",
307 "enable-fixed-position-compositing",
308 "enable-nacl",
309 "disable-saml-signin",
310 "disable-views-rect-based-targeting",
311 "enable-linkable-ephemeral-apps",
312 "enable-zero-copy",
313 "enable-session-crashed-bubble",
314 "enable-spelling-auto-correct",
315 "disable-suggestions-service",
316 "disable-app-list-app-info",
317 "allow-insecure-websocket-from-https-origin",
318 "enable-input-view",
319 "enable-web-midi",
320 "disable-app-list-voice-search",
321 "disable-offline-load-stale-cache",
322 "manual-enhanced-bookmarks",
323 "num-raster-threads",
324 "disable-cast",
325 "enable-instant-search-clicks",
326 "enable-zero-suggest-ether-noserp",
327 "enable-overlay-scrollbar",
328 "enable-spdy4",
329 "disable-boot-animation",
330 "disable-password-generation",
331 "disable-software-rasterizer",
332 "enable-avfoundation",
333 "disable-spdy-proxy-dev-auth-origin",
334 "disable-new-profile-management",
335 "mediadrm-enable-non-compositing",
336 "disable-text-input-focus-manager",
337 "enable-smooth-scrolling",
338 "enable-password-generation",
339 "disable-device-discovery",
340 "scroll-end-effect",
341 "enable-delegated-renderer",
342 "ash-enable-touch-view-testing",
343 "touch-events",
344 "disable-new-ntp",
345 "disable-permissions-bubbles",
346 "enable-network-portal-notification",
347 "disable-media-source",
348 "enable-encrypted-media",
349 "enable-apps-file-associations",
350 "enable-search-button-in-omnibox-for-str",
351 "disable-sync-app-list",
352 "file-manager-enable-new-gallery",
353 "enable-fast-unload",
354 "disable-fast-text-autosizing",
355 "tab-capture-upscale-quality",
356 "disable-threaded-compositing",
357 "enable-accelerated-fixed-root-background",
358 "enable-lcd-text",
359 "nacl-debug-mask",
360 "disable-transition-compositing",
361 "enable-embeddedsearch-api",
362 "enable-settings-window",
363 "force-device-scale-factor",
364 "disable-password-manager-reauthentication",
365 "disable-pinch-virtual-viewport",
366 "disable-webgl",
367 "save-page-as-mhtml",
368 "disable-zero-suggest",
369 "show-composited-layer-borders",
370 "enable-zero-suggest-most-visited",
371 "enable-answers-in-suggest",
372 "malware-interstitial-v3",
373 "enable-virtual-keyboard",
374 "disable-quic",
375 "default-tile-width",
376 "enable-automatic-password-saving",
377 "enable-search-button-in-omnibox-always",
378 "disable-input-view",
379 "enable-one-copy",
380 "overscroll-history-navigation",
381 "enable-quic-https",
382 "js-flags",
383 "enable-nacl-debug",
384 "enable-viewport-meta",
385 "enable-experimental-input-view-features",
386 "disable-gpu-rasterization",
387 "enable-print-preview-register-promos",
388 "enable-simplified-fullscreen",
389 "enable-accessibility-tab-switcher",
390 "enable-quic",
391 "enable-origin-chip-on-srp",
392 "fast-user-switching",
393 "enable-touch-editing",
394 "wallet-service-use-sandbox",
395 "enable-carrier-switching",
396 "disable-contextual-search",
397 "enable-zero-suggest-ether-serp",
398 "enable-cloud-devices",
399 "disable-quic-https",
400 "enable-touch-drag-drop",
401 "enable-permissions-bubbles",
402 "enable-first-run-ui-transitions",
403 "disable-device-discovery-notifications",
404 "enable-threaded-compositing",
405 "enable-easy-unlock",
406 "enable-origin-chip-always",
407 "enable-pinch",
408 "enable-bleeding-edge-rendering-fast-paths",
409 "disable-lcd-text",
410 "enable-streamlined-hosted-apps",
411 "disable-webrtc",
412 "enable-save-password-bubble",
413 "enable-apps-show-on-first-paint",
414 "enable-new-ntp",
415 "enable-text-input-focus-manager",
416 "enable-service-worker-sync",
417 "enable-harfbuzz-rendertext",
418 "enable-download-resumption",
419 "new-profile-management",
420 "disable-touch-editing",
421 "google-profile-info",
422 "enable-impl-side-painting",
423 "enable-distance-field-text",
424 "enable-deferred-image-decoding",
425 "manual-enhanced-bookmarks-optout",
426 "enable-search-button-in-omnibox-for-str-or-iip",
427 "enable-offline-auto-reload",
428 "enable-experimental-canvas-features",
429 "enable-app-install-alerts",
430 "enable-cloud-print-xps",
431 "max-tiles-for-interest-area",
432 "enable-app-list",
433 "disable-accelerated-video-decode",
434 "out-of-process-pdf",
435 "disable-session-crashed-bubble",
436 "enable-swipe-selection",
437 "disable-fixed-position-compositing",
438 "enable-web-based-signin",
439 "ssl-interstitial-v2-gray",
440 "enable-sync-app-list",
441 "disable-compositor-touch-hit-testing",
442 "disable-accelerated-fixed-root-background",
443 "enhanced-bookmarks-experiment",
444 "disable-pnacl",
445 "extension-content-verification",
446 "disable-touch-drag-drop",
447 "default-tile-height",
448 "disable-sync-synced-notifications",
449 "new-avatar-menu",
450 "allow-nacl-socket-api",
451 "enable-experimental-extension-apis",
452 "enable-app-window-controls",
453 "silent-debugger-extension-api",
454 "enable-suggestions-service",
455 "enable-contextual-search",
456 "enable-fast-text-autosizing",
457 "ash-touch-hud",
458 "disable-accelerated-overflow-scroll",
459 "disable-async-dns",
460 "disable-webaudio",
461 "disable-delegated-renderer",
462 "disable-save-password-bubble",
463 "enable-offline-load-stale-cache",
464 "disable-display-color-calibration",
465 "debug-packed-apps",
466 "enable-gpu-rasterization",
467 "disable-impl-side-painting",
468 "disable-distance-field-text",
469 "performance-monitor-gathering",
470 "disable-pinch",
471 "enable-syncfs-directory-operation",
472 "disable-ntp-other-sessions-menu",
473 "enable-spelling-feedback-field-trial",
474 "ssl-interstitial-v1",
475 "disable-gesture-requirement-for-media-playback",
476 "touch-scrolling-mode",
477 "enable-touchpad-three-finger-click",
478 "disable-quickoffice-component-app",
479 "enable-transition-compositing",
480 "disable-account-consistency",
481 "enable-request-tablet-site",
482 "tab-capture-downscale-quality",
483 "enable-service-worker",
484 "ash-debug-shortcuts",
485 "enable-sync-synced-notifications",
486 "ignore-gpu-blacklist",
487 "ssl-interstitial-v2-colorful",
488 "do-not-ignore-autocomplete-off",
489 "disable-accelerated-2d-canvas",
490 "enable-gesture-tap-highlight",
491 "reset-app-list-install-state",
492 "enable-scroll-prediction",
493 "enable-ephemeral-apps",
494 "enable-webgl-draft-extensions",
495 "disable-network-portal-notification",
496 "enable-device-discovery-notifications",
497 "disable-layer-squashing",
498 "disable-gesture-tap-highlight",
499 "enable-offline-auto-reload-visible-only",
500 "enable-spdy-proxy-dev-auth-origin",
501 "enable-translate-new-ux",
502 "no-pings",
503 "enable-scripts-require-action",
504 "disable-webrtc-hw-decoding",
505 "enable-virtual-keyboard-overscroll",
506 "disable-direct-write",
507 "extensions-on-chrome-urls",
508 "malware-interstitial-v2",
509 "enable-account-consistency",
510 "disable-offline-auto-reload-visible-only",
511 "disable-settings-window",
512 "disable-embedded-shared-worker",
513 "show-autofill-type-predictions",
514 "enable-async-dns",
515 "enable-prominent-url-app-flow",
516 "enable-high-dpi-fixed-position-compositing",
517 "force-gpu-rasterization",
518 "disable-device-enumeration",
519 "show-fps-counter",
520 "apps-keep-chrome-alive",
521 "enable-filemanager-mtp",
522 "enable-panels",
523 "disable-overlay-scrollbar",
524 "disable-zero-copy",
525 "disable-click-delay",
526 };
527
113 class AboutFlagsTest : public ::testing::Test { 528 class AboutFlagsTest : public ::testing::Test {
114 protected: 529 protected:
115 AboutFlagsTest() : flags_storage_(&prefs_) { 530 AboutFlagsTest() : flags_storage_(&prefs_) {
116 prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments); 531 prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments);
117 testing::ClearState(); 532 testing::ClearState();
533 InitHistogramIdToSwitch();
118 } 534 }
119 535
120 virtual void SetUp() OVERRIDE { 536 virtual void SetUp() OVERRIDE {
121 for (size_t i = 0; i < arraysize(kExperiments); ++i) 537 for (size_t i = 0; i < arraysize(kExperiments); ++i)
122 kExperiments[i].supported_platforms = GetCurrentPlatform(); 538 kExperiments[i].supported_platforms = GetCurrentPlatform();
123 539
124 int os_other_than_current = 1; 540 int os_other_than_current = 1;
125 while (os_other_than_current == GetCurrentPlatform()) 541 while (os_other_than_current == GetCurrentPlatform())
126 os_other_than_current <<= 1; 542 os_other_than_current <<= 1;
127 kExperiments[2].supported_platforms = os_other_than_current; 543 kExperiments[2].supported_platforms = os_other_than_current;
128 544
129 testing::SetExperiments(kExperiments, arraysize(kExperiments)); 545 testing::SetExperiments(kExperiments, arraysize(kExperiments));
130 } 546 }
131 547
132 virtual void TearDown() OVERRIDE { 548 virtual void TearDown() OVERRIDE {
133 testing::SetExperiments(NULL, 0); 549 testing::SetExperiments(NULL, 0);
134 } 550 }
135 551
552 private:
553 void InitHistogramIdToSwitch() {
554 // Extract command-line switches from kExperiments to
555 // histogram_id_to_switch_ in the order of UMA IDs. Each switch is stored
556 // by the idex equal to its ID.
557 const SwitchesHistogramIDs& switch_histogram_id = GetSwitchesHistogramIds();
558 for (SwitchesHistogramIDs::const_iterator it = switch_histogram_id.begin();
559 it != switch_histogram_id.end();
560 ++it) {
561 const int id = it->second;
562 if (static_cast<int>(histogram_id_to_switch_.size()) > id) {
563 // Check that enum values are not reused in kExperiments[], i.e.
564 // different switches have different UMA IDs values.
565 // (There is another check for equal switches below.)
566 EXPECT_FALSE(histogram_id_to_switch_[id])
567 << "Duplicate switch histogram ID: " << id << ": '"
568 << *(histogram_id_to_switch_[id]) << "' conflicts with '"
569 << it->first << "'.";
570 } else {
571 histogram_id_to_switch_.resize(id + 1);
572 }
573 histogram_id_to_switch_[id] = new std::string(it->first);
574 }
575 }
576
577 protected:
136 TestingPrefServiceSimple prefs_; 578 TestingPrefServiceSimple prefs_;
137 PrefServiceFlagsStorage flags_storage_; 579 PrefServiceFlagsStorage flags_storage_;
580 ScopedVector<std::string> histogram_id_to_switch_;
138 }; 581 };
139 582
140
141 TEST_F(AboutFlagsTest, NoChangeNoRestart) { 583 TEST_F(AboutFlagsTest, NoChangeNoRestart) {
142 EXPECT_FALSE(IsRestartNeededToCommitChanges()); 584 EXPECT_FALSE(IsRestartNeededToCommitChanges());
143 SetExperimentEnabled(&flags_storage_, kFlags1, false); 585 SetExperimentEnabled(&flags_storage_, kFlags1, false);
144 EXPECT_FALSE(IsRestartNeededToCommitChanges()); 586 EXPECT_FALSE(IsRestartNeededToCommitChanges());
145 } 587 }
146 588
147 TEST_F(AboutFlagsTest, ChangeNeedsRestart) { 589 TEST_F(AboutFlagsTest, ChangeNeedsRestart) {
148 EXPECT_FALSE(IsRestartNeededToCommitChanges()); 590 EXPECT_FALSE(IsRestartNeededToCommitChanges());
149 SetExperimentEnabled(&flags_storage_, kFlags1, true); 591 SetExperimentEnabled(&flags_storage_, kFlags1, true);
150 EXPECT_TRUE(IsRestartNeededToCommitChanges()); 592 EXPECT_TRUE(IsRestartNeededToCommitChanges());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 668
227 CommandLine command_line2(CommandLine::NO_PROGRAM); 669 CommandLine command_line2(CommandLine::NO_PROGRAM);
228 670
229 ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels); 671 ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels);
230 672
231 EXPECT_TRUE(command_line2.HasSwitch(kSwitch1)); 673 EXPECT_TRUE(command_line2.HasSwitch(kSwitch1));
232 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin)); 674 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin));
233 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd)); 675 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd));
234 } 676 }
235 677
678 CommandLine::StringType CreateSwitch(const std::string& value) {
679 #if defined(OS_WIN)
680 return ASCIIToUTF16(value);
681 #else
682 return value;
683 #endif
684 }
685
236 TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) { 686 TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) {
237 SetExperimentEnabled(&flags_storage_, kFlags1, true); 687 SetExperimentEnabled(&flags_storage_, kFlags1, true);
238 688
689 const std::string kDoubleDash("--");
690
239 CommandLine command_line(CommandLine::NO_PROGRAM); 691 CommandLine command_line(CommandLine::NO_PROGRAM);
240 command_line.AppendSwitch("foo"); 692 command_line.AppendSwitch("foo");
241 693
242 CommandLine new_command_line(CommandLine::NO_PROGRAM); 694 CommandLine new_command_line(CommandLine::NO_PROGRAM);
243 ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels); 695 ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels);
244 696
245 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, 697 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
246 command_line)); 698 new_command_line, command_line, NULL));
699 {
700 std::set<CommandLine::StringType> difference;
701 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
702 new_command_line, command_line, &difference));
703 EXPECT_EQ(1U, difference.size());
704 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
705 }
247 706
248 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); 707 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels);
249 708
250 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, 709 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(
251 command_line)); 710 new_command_line, command_line, NULL));
711 {
712 std::set<CommandLine::StringType> difference;
713 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(
714 new_command_line, command_line, &difference));
715 EXPECT_TRUE(difference.empty());
716 }
252 717
253 // Now both have flags but different. 718 // Now both have flags but different.
254 SetExperimentEnabled(&flags_storage_, kFlags1, false); 719 SetExperimentEnabled(&flags_storage_, kFlags1, false);
255 SetExperimentEnabled(&flags_storage_, kFlags2, true); 720 SetExperimentEnabled(&flags_storage_, kFlags2, true);
256 721
257 CommandLine another_command_line(CommandLine::NO_PROGRAM); 722 CommandLine another_command_line(CommandLine::NO_PROGRAM);
258 ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels); 723 ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels);
259 724
260 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, 725 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
261 another_command_line)); 726 new_command_line, another_command_line, NULL));
727 {
728 std::set<CommandLine::StringType> difference;
729 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(
730 new_command_line, another_command_line, &difference));
731 EXPECT_EQ(2U, difference.size());
732 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
733 EXPECT_EQ(1U,
734 difference.count(CreateSwitch(kDoubleDash + kSwitch2 + "=" +
735 kValueForSwitch2)));
736 }
262 } 737 }
263 738
264 TEST_F(AboutFlagsTest, RemoveFlagSwitches) { 739 TEST_F(AboutFlagsTest, RemoveFlagSwitches) {
265 std::map<std::string, CommandLine::StringType> switch_list; 740 std::map<std::string, CommandLine::StringType> switch_list;
266 switch_list[kSwitch1] = CommandLine::StringType(); 741 switch_list[kSwitch1] = CommandLine::StringType();
267 switch_list[switches::kFlagSwitchesBegin] = CommandLine::StringType(); 742 switch_list[switches::kFlagSwitchesBegin] = CommandLine::StringType();
268 switch_list[switches::kFlagSwitchesEnd] = CommandLine::StringType(); 743 switch_list[switches::kFlagSwitchesEnd] = CommandLine::StringType();
269 switch_list["foo"] = CommandLine::StringType(); 744 switch_list["foo"] = CommandLine::StringType();
270 745
271 SetExperimentEnabled(&flags_storage_, kFlags1, true); 746 SetExperimentEnabled(&flags_storage_, kFlags1, true);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 TEST_F(AboutFlagsTest, NoSeparators) { 932 TEST_F(AboutFlagsTest, NoSeparators) {
458 testing::SetExperiments(NULL, 0); 933 testing::SetExperiments(NULL, 0);
459 size_t count; 934 size_t count;
460 const Experiment* experiments = testing::GetExperiments(&count); 935 const Experiment* experiments = testing::GetExperiments(&count);
461 for (size_t i = 0; i < count; ++i) { 936 for (size_t i = 0; i < count; ++i) {
462 std::string name = experiments->internal_name; 937 std::string name = experiments->internal_name;
463 EXPECT_EQ(std::string::npos, name.find(testing::kMultiSeparator)) << i; 938 EXPECT_EQ(std::string::npos, name.find(testing::kMultiSeparator)) << i;
464 } 939 }
465 } 940 }
466 941
942 // Checks that enum values are not reused in kExperiments[], i.e. equal
943 // switches have equal UMA IDs. (Different switches are checked in
944 // AboutFlagsTest::AboutFlagsTest().)
945 TEST_F(AboutFlagsTest, SwitchHistogramTableValid) {
946 if (histogram_id_to_switch_[0])
947 EXPECT_EQ(std::string(), histogram_id_to_switch_[0]->c_str());
948 ASSERT_GT(histogram_id_to_switch_.size(), 5U);
949 EXPECT_FALSE(histogram_id_to_switch_[1]); /* BAD_FLAG_FORMAT, */
950 EXPECT_FALSE(histogram_id_to_switch_[2]); /* RESERVED1 */
951 EXPECT_FALSE(histogram_id_to_switch_[3]); /* RESERVED2 */
952 EXPECT_FALSE(histogram_id_to_switch_[4]); /* RESERVED3 */
953 for (size_t i = 5; i < histogram_id_to_switch_.size(); ++i) {
954 // Some values may be missing from histogram_id_to_switch_[] because
955 // they are under #ifdef and were not compiled.
956 if (histogram_id_to_switch_[i]) {
957 EXPECT_LT(i, arraysize(HistogramSwitchesOrdered))
958 << "Switch index " << i << " (switch name '"
959 << histogram_id_to_switch_[i]->c_str()
960 << "') is found in about_flags, but missing from the test.";
961 } else {
962 EXPECT_LT(i, arraysize(HistogramSwitchesOrdered))
963 << "Switch index " << i
964 << " is found in about_flags, but missing from the test.";
965 }
966 if (i >= arraysize(HistogramSwitchesOrdered))
967 continue;
968
969 if (histogram_id_to_switch_[i]) {
970 EXPECT_STREQ(HistogramSwitchesOrdered[i],
971 histogram_id_to_switch_[i]->c_str())
972 << "Switch index " << i << " is wrong.";
973 }
974 }
975 }
976
977 TEST_F(AboutFlagsTest, CheckHistograms) {
978 base::FilePath histograms_xml_file_path;
979 ASSERT_TRUE(
980 PathService::Get(base::DIR_SOURCE_ROOT, &histograms_xml_file_path));
981 histograms_xml_file_path = histograms_xml_file_path.AppendASCII("tools")
982 .AppendASCII("metrics")
983 .AppendASCII("histograms")
984 .AppendASCII("histograms.xml");
985
986 XmlReader histograms_xml;
987 ASSERT_TRUE(histograms_xml.LoadFile(
988 FilePathStringTypeToString(histograms_xml_file_path.value())));
989 // Check that order and labels of <enum name="LoginCustomFlags" type="int">
990 // match HistogramSwitchesOrdered.
991 std::map<int, std::string> login_custom_flags =
992 ReadEnumFromHistogramsXml("LoginCustomFlags", histograms_xml);
993 ASSERT_TRUE(login_custom_flags.size())
994 << "Error reading enum 'LoginCustomFlags' from histograms.xml.";
995
996 for (size_t i = 5; i < arraysize(HistogramSwitchesOrdered); ++i) {
997 EXPECT_TRUE(login_custom_flags.count(i))
998 << "histograms.xml enum LoginCustomFlags doesn't contain switch '"
999 << HistogramSwitchesOrdered[i] << "'";
1000
1001 if (login_custom_flags.count(i)) {
1002 EXPECT_STREQ(HistogramSwitchesOrdered[i], login_custom_flags[i].c_str())
1003 << "Bad histograms.xml enum LoginCustomFlags entry with value='" << i
1004 << "'.";
1005 }
1006 }
1007
1008 // If maximum index in histograms.xml is greater than in test,
1009 // report all extra items.
1010 if (static_cast<size_t>(login_custom_flags.rbegin()->first) >=
1011 arraysize(HistogramSwitchesOrdered)) {
1012 for (std::map<int, std::string>::reverse_iterator iter =
1013 login_custom_flags.rbegin();
1014 iter != login_custom_flags.rend();
1015 ++iter) {
1016 if (static_cast<size_t>(iter->first) <
1017 arraysize(HistogramSwitchesOrdered)) {
1018 break;
1019 }
1020 EXPECT_LT(static_cast<size_t>(iter->first),
1021 arraysize(HistogramSwitchesOrdered))
1022 << "Test has no data for histograms.xml enum LoginCustomFlags entry "
1023 "with value='" << iter->first << "' label='" << iter->second
1024 << "'";
1025 }
1026 }
1027 }
1028
467 } // namespace about_flags 1029 } // namespace about_flags
OLDNEW
« no previous file with comments | « chrome/browser/about_flags_switches_histogram_ids.h ('k') | chrome/browser/chromeos/login/login_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698