OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |