Chromium Code Reviews| 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" | |
| 16 | 20 |
| 17 const char kFlags1[] = "flag1"; | 21 const char kFlags1[] = "flag1"; |
| 18 const char kFlags2[] = "flag2"; | 22 const char kFlags2[] = "flag2"; |
| 19 const char kFlags3[] = "flag3"; | 23 const char kFlags3[] = "flag3"; |
| 20 const char kFlags4[] = "flag4"; | 24 const char kFlags4[] = "flag4"; |
| 21 const char kFlags5[] = "flag5"; | 25 const char kFlags5[] = "flag5"; |
| 22 | 26 |
| 23 const char kSwitch1[] = "switch"; | 27 const char kSwitch1[] = "switch"; |
| 24 const char kSwitch2[] = "switch2"; | 28 const char kSwitch2[] = "switch2"; |
| 25 const char kSwitch3[] = "switch3"; | 29 const char kSwitch3[] = "switch3"; |
| 26 const char kValueForSwitch2[] = "value_for_switch2"; | 30 const char kValueForSwitch2[] = "value_for_switch2"; |
| 27 | 31 |
| 28 const char kMultiSwitch1[] = "multi_switch1"; | 32 const char kMultiSwitch1[] = "multi_switch1"; |
| 29 const char kMultiSwitch2[] = "multi_switch2"; | 33 const char kMultiSwitch2[] = "multi_switch2"; |
| 30 const char kValueForMultiSwitch2[] = "value_for_multi_switch2"; | 34 const char kValueForMultiSwitch2[] = "value_for_multi_switch2"; |
| 31 | 35 |
| 32 const char kEnableDisableValue1[] = "value1"; | 36 const char kEnableDisableValue1[] = "value1"; |
| 33 const char kEnableDisableValue2[] = "value2"; | 37 const char kEnableDisableValue2[] = "value2"; |
| 34 | 38 |
| 35 namespace about_flags { | 39 namespace about_flags { |
| 36 | 40 |
| 41 enum TestSwitchesHistogramIDs { | |
| 42 ID_UNKNOWN_FLAG = UMA_HISTOGRAM_ID_UNKNOWN_FLAG, | |
| 43 ID_BAD_FLAG_FORMAT = UMA_HISTOGRAM_ID_BAD_FLAG_FORMAT, | |
| 44 ID_kMultiSwitch1, | |
| 45 ID_kMultiSwitch2, | |
| 46 ID_kSwitch1, | |
| 47 ID_kSwitch2, | |
| 48 ID_kSwitch3, | |
| 49 }; | |
| 50 | |
| 51 #define ID(x) static_cast<const about_flags::SwitchesUmaHistogramId>(x) | |
| 52 | |
| 37 const Experiment::Choice kMultiChoices[] = { | 53 const Experiment::Choice kMultiChoices[] = { |
| 38 { IDS_PRODUCT_NAME, "", "" }, | 54 { IDS_PRODUCT_NAME, "", "", ID(ID_UNKNOWN_FLAG) }, |
| 39 { IDS_PRODUCT_NAME, kMultiSwitch1, "" }, | 55 { IDS_PRODUCT_NAME, kMultiSwitch1, "", ID(ID_kMultiSwitch1) }, |
| 40 { IDS_PRODUCT_NAME, kMultiSwitch2, kValueForMultiSwitch2 }, | 56 { IDS_PRODUCT_NAME, |
| 57 kMultiSwitch2, kValueForMultiSwitch2, ID(ID_kMultiSwitch2) }, | |
| 41 }; | 58 }; |
| 42 | 59 |
| 60 #undef ID | |
| 61 | |
| 43 // The experiments that are set for these tests. The 3rd experiment is not | 62 // The experiments that are set for these tests. The 3rd experiment is not |
| 44 // supported on the current platform, all others are. | 63 // supported on the current platform, all others are. |
| 45 static Experiment kExperiments[] = { | 64 static Experiment kExperiments[] = { |
| 46 { | 65 { |
| 47 kFlags1, | 66 kFlags1, |
| 48 IDS_PRODUCT_NAME, | 67 IDS_PRODUCT_NAME, |
| 49 IDS_PRODUCT_NAME, | 68 IDS_PRODUCT_NAME, |
| 50 0, // Ends up being mapped to the current platform. | 69 0, // Ends up being mapped to the current platform. |
| 51 Experiment::SINGLE_VALUE, | 70 Experiment::SINGLE_VALUE, |
| 52 kSwitch1, | 71 kSwitch1, |
| 53 "", | 72 "", |
| 73 ID_kSwitch1, | |
| 54 NULL, | 74 NULL, |
| 55 NULL, | 75 NULL, |
| 76 0, | |
| 56 NULL, | 77 NULL, |
| 57 0 | 78 0 |
| 58 }, | 79 }, |
| 59 { | 80 { |
| 60 kFlags2, | 81 kFlags2, |
| 61 IDS_PRODUCT_NAME, | 82 IDS_PRODUCT_NAME, |
| 62 IDS_PRODUCT_NAME, | 83 IDS_PRODUCT_NAME, |
| 63 0, // Ends up being mapped to the current platform. | 84 0, // Ends up being mapped to the current platform. |
| 64 Experiment::SINGLE_VALUE, | 85 Experiment::SINGLE_VALUE, |
| 65 kSwitch2, | 86 kSwitch2, |
| 66 kValueForSwitch2, | 87 kValueForSwitch2, |
| 88 ID_kSwitch2, | |
| 67 NULL, | 89 NULL, |
| 68 NULL, | 90 NULL, |
| 91 0, | |
| 69 NULL, | 92 NULL, |
| 70 0 | 93 0 |
| 71 }, | 94 }, |
| 72 { | 95 { |
| 73 kFlags3, | 96 kFlags3, |
| 74 IDS_PRODUCT_NAME, | 97 IDS_PRODUCT_NAME, |
| 75 IDS_PRODUCT_NAME, | 98 IDS_PRODUCT_NAME, |
| 76 0, // This ends up enabling for an OS other than the current. | 99 0, // This ends up enabling for an OS other than the current. |
| 77 Experiment::SINGLE_VALUE, | 100 Experiment::SINGLE_VALUE, |
| 78 kSwitch3, | 101 kSwitch3, |
| 79 "", | 102 "", |
| 103 ID_kSwitch3, | |
| 80 NULL, | 104 NULL, |
| 81 NULL, | 105 NULL, |
| 106 0, | |
| 82 NULL, | 107 NULL, |
| 83 0 | 108 0 |
| 84 }, | 109 }, |
| 85 { | 110 { |
| 86 kFlags4, | 111 kFlags4, |
| 87 IDS_PRODUCT_NAME, | 112 IDS_PRODUCT_NAME, |
| 88 IDS_PRODUCT_NAME, | 113 IDS_PRODUCT_NAME, |
| 89 0, // Ends up being mapped to the current platform. | 114 0, // Ends up being mapped to the current platform. |
| 90 Experiment::MULTI_VALUE, | 115 Experiment::MULTI_VALUE, |
| 91 "", | 116 "", |
| 92 "", | 117 "", |
| 118 0, | |
| 93 "", | 119 "", |
| 94 "", | 120 "", |
| 121 0, | |
| 95 kMultiChoices, | 122 kMultiChoices, |
| 96 arraysize(kMultiChoices) | 123 arraysize(kMultiChoices) |
| 97 }, | 124 }, |
| 98 { | 125 { |
| 99 kFlags5, | 126 kFlags5, |
| 100 IDS_PRODUCT_NAME, | 127 IDS_PRODUCT_NAME, |
| 101 IDS_PRODUCT_NAME, | 128 IDS_PRODUCT_NAME, |
| 102 0, // Ends up being mapped to the current platform. | 129 0, // Ends up being mapped to the current platform. |
| 103 Experiment::ENABLE_DISABLE_VALUE, | 130 Experiment::ENABLE_DISABLE_VALUE, |
| 104 kSwitch1, | 131 kSwitch1, |
| 105 kEnableDisableValue1, | 132 kEnableDisableValue1, |
| 133 ID_kSwitch1, | |
| 106 kSwitch2, | 134 kSwitch2, |
| 107 kEnableDisableValue2, | 135 kEnableDisableValue2, |
| 136 ID_kSwitch2, | |
| 108 NULL, | 137 NULL, |
| 109 3 | 138 3 |
| 110 }, | 139 }, |
| 111 }; | 140 }; |
| 112 | 141 |
| 142 /* | |
| 143 This table contains histogram IDs for switches. Switch ID must never change! | |
| 144 */ | |
| 145 const char* const HistogramSwitchesOrdered[] = { | |
| 146 NULL, /* No flag */ | |
| 147 NULL, /* Bad flag format */ | |
| 148 NULL, /* reserved */ | |
| 149 NULL, /* reserved */ | |
| 150 NULL, /* reserved */ | |
| 151 "disable-webrtc-hw-encoding", | |
| 152 "disable-minimize-on-second-launcher-item-click", | |
| 153 "disable-virtual-keyboard-overscroll", | |
| 154 "disable-virtual-keyboard-overscroll", | |
| 155 "enable-pinch-virtual-viewport", | |
| 156 "prefetch-search-results", | |
| 157 "enable-experimental-app-list", | |
| 158 "enable-devtools-experiments", | |
| 159 "enable-centered-app-list", | |
| 160 "enable-accelerated-overflow-scroll", | |
| 161 "enable-tcp-fastopen", | |
| 162 "enable-zero-suggest-personalized", | |
| 163 "enable-experimental-web-platform-features", | |
| 164 "use-simple-cache-backend", | |
| 165 "disable-search-button-in-omnibox", | |
| 166 "file-manager-enable-new-audio-player", | |
| 167 "disable-prefixed-encrypted-media", | |
| 168 "disable-origin-chip", | |
| 169 "disable-touch-adjustment", | |
| 170 "disable-offline-auto-reload", | |
| 171 "enable-fixed-position-compositing", | |
| 172 "enable-nacl", | |
| 173 "disable-saml-signin", | |
| 174 "disable-views-rect-based-targeting", | |
| 175 "enable-linkable-ephemeral-apps", | |
| 176 "enable-zero-copy", | |
| 177 "enable-session-crashed-bubble", | |
| 178 "enable-spelling-auto-correct", | |
| 179 "disable-suggestions-service", | |
| 180 "disable-app-list-app-info", | |
| 181 "allow-insecure-websocket-from-https-origin", | |
| 182 "enable-input-view", | |
| 183 "enable-web-midi", | |
| 184 "disable-app-list-voice-search", | |
| 185 "disable-offline-load-stale-cache", | |
| 186 "manual-enhanced-bookmarks", | |
| 187 "num-raster-threads", | |
| 188 "disable-cast", | |
| 189 "enable-instant-search-clicks", | |
| 190 "enable-zero-suggest-ether-noserp", | |
| 191 "enable-overlay-scrollbar", | |
| 192 "enable-spdy4", | |
| 193 "disable-boot-animation", | |
| 194 "disable-password-generation", | |
| 195 "disable-software-rasterizer", | |
| 196 "enable-avfoundation", | |
| 197 "disable-spdy-proxy-dev-auth-origin", | |
| 198 "disable-new-profile-management", | |
| 199 "mediadrm-enable-non-compositing", | |
| 200 "disable-text-input-focus-manager", | |
| 201 "enable-smooth-scrolling", | |
| 202 "enable-password-generation", | |
| 203 "disable-device-discovery", | |
| 204 "scroll-end-effect", | |
| 205 "enable-delegated-renderer", | |
| 206 "ash-enable-touch-view-testing", | |
| 207 "touch-events", | |
| 208 "disable-new-ntp", | |
| 209 "disable-permissions-bubbles", | |
| 210 "enable-network-portal-notification", | |
| 211 "disable-media-source", | |
| 212 "enable-encrypted-media", | |
| 213 "enable-apps-file-associations", | |
| 214 "enable-search-button-in-omnibox-for-str", | |
| 215 "disable-sync-app-list", | |
| 216 "file-manager-enable-new-gallery", | |
| 217 "enable-fast-unload", | |
| 218 "disable-fast-text-autosizing", | |
| 219 "tab-capture-upscale-quality", | |
| 220 "disable-threaded-compositing", | |
| 221 "enable-accelerated-fixed-root-background", | |
| 222 "enable-lcd-text", | |
| 223 "nacl-debug-mask", | |
| 224 "disable-transition-compositing", | |
| 225 "enable-embeddedsearch-api", | |
| 226 "enable-settings-window", | |
| 227 "force-device-scale-factor", | |
| 228 "disable-password-manager-reauthentication", | |
| 229 "disable-pinch-virtual-viewport", | |
| 230 "disable-webgl", | |
| 231 "save-page-as-mhtml", | |
| 232 "disable-zero-suggest", | |
| 233 "show-composited-layer-borders", | |
| 234 "enable-zero-suggest-most-visited", | |
| 235 "enable-answers-in-suggest", | |
| 236 "malware-interstitial-v3", | |
| 237 "enable-virtual-keyboard", | |
| 238 "disable-quic", | |
| 239 "default-tile-width", | |
| 240 "enable-automatic-password-saving", | |
| 241 "enable-search-button-in-omnibox-always", | |
| 242 "disable-input-view", | |
| 243 "enable-one-copy", | |
| 244 "overscroll-history-navigation", | |
| 245 "enable-quic-https", | |
| 246 "js-flags", | |
| 247 "enable-nacl-debug", | |
| 248 "enable-viewport-meta", | |
| 249 "enable-experimental-input-view-features", | |
| 250 "disable-gpu-rasterization", | |
| 251 "enable-print-preview-register-promos", | |
| 252 "enable-simplified-fullscreen", | |
| 253 "enable-accessibility-tab-switcher", | |
| 254 "enable-quic", | |
| 255 "enable-origin-chip-on-srp", | |
| 256 "fast-user-switching", | |
| 257 "enable-touch-editing", | |
| 258 "wallet-service-use-sandbox", | |
| 259 "enable-carrier-switching", | |
| 260 "disable-contextual-search", | |
| 261 "enable-zero-suggest-ether-serp", | |
| 262 "enable-cloud-devices", | |
| 263 "disable-quic-https", | |
| 264 "enable-touch-drag-drop", | |
| 265 "enable-permissions-bubbles", | |
| 266 "enable-first-run-ui-transitions", | |
| 267 "disable-device-discovery-notifications", | |
| 268 "enable-threaded-compositing", | |
| 269 "enable-easy-unlock", | |
| 270 "enable-origin-chip-always", | |
| 271 "enable-pinch", | |
| 272 "enable-bleeding-edge-rendering-fast-paths", | |
| 273 "disable-lcd-text", | |
| 274 "enable-streamlined-hosted-apps", | |
| 275 "disable-webrtc", | |
| 276 "enable-save-password-bubble", | |
| 277 "enable-apps-show-on-first-paint", | |
| 278 "enable-new-ntp", | |
| 279 "enable-text-input-focus-manager", | |
| 280 "enable-service-worker-sync", | |
| 281 "enable-harfbuzz-rendertext", | |
| 282 "enable-download-resumption", | |
| 283 "new-profile-management", | |
| 284 "disable-touch-editing", | |
| 285 "google-profile-info", | |
| 286 "enable-impl-side-painting", | |
| 287 "enable-distance-field-text", | |
| 288 "enable-deferred-image-decoding", | |
| 289 "manual-enhanced-bookmarks-optout", | |
| 290 "enable-search-button-in-omnibox-for-str-or-iip", | |
| 291 "enable-offline-auto-reload", | |
| 292 "enable-experimental-canvas-features", | |
| 293 "enable-app-install-alerts", | |
| 294 "enable-cloud-print-xps", | |
| 295 "max-tiles-for-interest-area", | |
| 296 "enable-app-list", | |
| 297 "disable-accelerated-video-decode", | |
| 298 "out-of-process-pdf", | |
| 299 "disable-session-crashed-bubble", | |
| 300 "enable-swipe-selection", | |
| 301 "disable-fixed-position-compositing", | |
| 302 "enable-web-based-signin", | |
| 303 "ssl-interstitial-v2-gray", | |
| 304 "enable-sync-app-list", | |
| 305 "disable-compositor-touch-hit-testing", | |
| 306 "disable-accelerated-fixed-root-background", | |
| 307 "enhanced-bookmarks-experiment", | |
| 308 "disable-pnacl", | |
| 309 "extension-content-verification", | |
| 310 "disable-touch-drag-drop", | |
| 311 "default-tile-height", | |
| 312 "disable-sync-synced-notifications", | |
| 313 "new-avatar-menu", | |
| 314 "allow-nacl-socket-api", | |
| 315 "enable-experimental-extension-apis", | |
| 316 "enable-app-window-controls", | |
| 317 "silent-debugger-extension-api", | |
| 318 "enable-suggestions-service", | |
| 319 "enable-contextual-search", | |
| 320 "enable-fast-text-autosizing", | |
| 321 "ash-touch-hud", | |
| 322 "disable-accelerated-overflow-scroll", | |
| 323 "disable-async-dns", | |
| 324 "disable-webaudio", | |
| 325 "disable-delegated-renderer", | |
| 326 "disable-save-password-bubble", | |
| 327 "enable-offline-load-stale-cache", | |
| 328 "disable-display-color-calibration", | |
| 329 "debug-packed-apps", | |
| 330 "enable-gpu-rasterization", | |
| 331 "disable-impl-side-painting", | |
| 332 "disable-distance-field-text", | |
| 333 "performance-monitor-gathering", | |
| 334 "disable-pinch", | |
| 335 "enable-syncfs-directory-operation", | |
| 336 "disable-ntp-other-sessions-menu", | |
| 337 "enable-spelling-feedback-field-trial", | |
| 338 "ssl-interstitial-v1", | |
| 339 "disable-gesture-requirement-for-media-playback", | |
| 340 "touch-scrolling-mode", | |
| 341 "enable-touchpad-three-finger-click", | |
| 342 "disable-quickoffice-component-app", | |
| 343 "enable-transition-compositing", | |
| 344 "disable-account-consistency", | |
| 345 "enable-request-tablet-site", | |
| 346 "tab-capture-downscale-quality", | |
| 347 "enable-service-worker", | |
| 348 "ash-debug-shortcuts", | |
| 349 "enable-sync-synced-notifications", | |
| 350 "ignore-gpu-blacklist", | |
| 351 "ssl-interstitial-v2-colorful", | |
| 352 "do-not-ignore-autocomplete-off", | |
| 353 "disable-accelerated-2d-canvas", | |
| 354 "enable-gesture-tap-highlight", | |
| 355 "reset-app-list-install-state", | |
| 356 "enable-scroll-prediction", | |
| 357 "enable-ephemeral-apps", | |
| 358 "enable-webgl-draft-extensions", | |
| 359 "disable-network-portal-notification", | |
| 360 "enable-device-discovery-notifications", | |
| 361 "disable-layer-squashing", | |
| 362 "disable-gesture-tap-highlight", | |
| 363 "enable-offline-auto-reload-visible-only", | |
| 364 "enable-spdy-proxy-dev-auth-origin", | |
| 365 "enable-translate-new-ux", | |
| 366 "no-pings", | |
| 367 "enable-scripts-require-action", | |
| 368 "disable-webrtc-hw-decoding", | |
| 369 "enable-virtual-keyboard-overscroll", | |
| 370 "disable-direct-write", | |
| 371 "extensions-on-chrome-urls", | |
| 372 "malware-interstitial-v2", | |
| 373 "enable-account-consistency", | |
| 374 "disable-offline-auto-reload-visible-only", | |
| 375 "disable-settings-window", | |
| 376 "disable-embedded-shared-worker", | |
| 377 "show-autofill-type-predictions", | |
| 378 "enable-async-dns", | |
| 379 "enable-prominent-url-app-flow", | |
| 380 "enable-high-dpi-fixed-position-compositing", | |
| 381 "force-gpu-rasterization", | |
| 382 "disable-device-enumeration", | |
| 383 "show-fps-counter", | |
| 384 "apps-keep-chrome-alive", | |
| 385 "enable-filemanager-mtp", | |
| 386 "enable-panels", | |
| 387 "disable-overlay-scrollbar", | |
| 388 "disable-zero-copy", | |
| 389 "disable-click-delay", | |
| 390 }; | |
| 391 | |
| 113 class AboutFlagsTest : public ::testing::Test { | 392 class AboutFlagsTest : public ::testing::Test { |
| 114 protected: | 393 protected: |
| 115 AboutFlagsTest() : flags_storage_(&prefs_) { | 394 AboutFlagsTest() : flags_storage_(&prefs_) { |
| 116 prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments); | 395 prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments); |
| 117 testing::ClearState(); | 396 testing::ClearState(); |
| 397 | |
| 398 // Extract command-line switches from kExperiments to | |
| 399 // histogram_id_to_switch_ in the order of UMA IDs. Each switch is stored | |
| 400 // by the idex equal to its ID. | |
| 401 const SwitchesHistogramIDs& switch_histogram_id = GetSwitchesHistogramIds(); | |
| 402 for (SwitchesHistogramIDs::const_iterator i = switch_histogram_id.begin(); | |
|
Ilya Sherman
2014/07/29 07:16:45
nit: Please use "it" or "iter" for generic iterato
Alexander Alekseev
2014/07/31 00:18:07
Done.
| |
| 403 i != switch_histogram_id.end(); | |
| 404 ++i) { | |
| 405 const int id = i->second; | |
| 406 if (static_cast<int>(histogram_id_to_switch_.size()) > id) { | |
| 407 // Check that enum values are not reused in kExperiments[], i.e. | |
| 408 // different switches have different UMA IDs values. | |
| 409 // (There is another check for equal switches below.) | |
| 410 EXPECT_FALSE(histogram_id_to_switch_[id]) | |
| 411 << "Duplicate switch histogram ID: " << id << ": '" | |
| 412 << *(histogram_id_to_switch_[id]) << "' conflicts with '" | |
| 413 << i->first << "'."; | |
| 414 } else { | |
|
Ilya Sherman
2014/07/29 07:16:45
nit: Please add ASSERT_EQ(id, histogram_id_to_swit
Alexander Alekseev
2014/07/31 00:18:08
The order of IDs in about_flags is undefined, so i
Ilya Sherman
2014/07/31 00:37:51
In that case, it really sounds like you ought to u
| |
| 415 histogram_id_to_switch_.resize(id + 1); | |
| 416 } | |
| 417 histogram_id_to_switch_[id] = new std::string(i->first); | |
| 418 } | |
| 118 } | 419 } |
| 119 | 420 |
| 120 virtual void SetUp() OVERRIDE { | 421 virtual void SetUp() OVERRIDE { |
| 121 for (size_t i = 0; i < arraysize(kExperiments); ++i) | 422 for (size_t i = 0; i < arraysize(kExperiments); ++i) |
| 122 kExperiments[i].supported_platforms = GetCurrentPlatform(); | 423 kExperiments[i].supported_platforms = GetCurrentPlatform(); |
| 123 | 424 |
| 124 int os_other_than_current = 1; | 425 int os_other_than_current = 1; |
| 125 while (os_other_than_current == GetCurrentPlatform()) | 426 while (os_other_than_current == GetCurrentPlatform()) |
| 126 os_other_than_current <<= 1; | 427 os_other_than_current <<= 1; |
| 127 kExperiments[2].supported_platforms = os_other_than_current; | 428 kExperiments[2].supported_platforms = os_other_than_current; |
| 128 | 429 |
| 129 testing::SetExperiments(kExperiments, arraysize(kExperiments)); | 430 testing::SetExperiments(kExperiments, arraysize(kExperiments)); |
| 130 } | 431 } |
| 131 | 432 |
| 132 virtual void TearDown() OVERRIDE { | 433 virtual void TearDown() OVERRIDE { |
| 133 testing::SetExperiments(NULL, 0); | 434 testing::SetExperiments(NULL, 0); |
| 134 } | 435 } |
| 135 | 436 |
| 136 TestingPrefServiceSimple prefs_; | 437 TestingPrefServiceSimple prefs_; |
| 137 PrefServiceFlagsStorage flags_storage_; | 438 PrefServiceFlagsStorage flags_storage_; |
| 439 ScopedVector<std::string> histogram_id_to_switch_; | |
|
Ilya Sherman
2014/07/29 07:16:45
Why is this a ScopedVector, rather than just a reg
Alexander Alekseev
2014/07/31 00:18:08
This is scoped vector to store the special value "
Ilya Sherman
2014/07/31 00:37:51
Checking whether a value exists in a map is easy:
| |
| 138 }; | 440 }; |
| 139 | 441 |
| 140 | |
| 141 TEST_F(AboutFlagsTest, NoChangeNoRestart) { | 442 TEST_F(AboutFlagsTest, NoChangeNoRestart) { |
| 142 EXPECT_FALSE(IsRestartNeededToCommitChanges()); | 443 EXPECT_FALSE(IsRestartNeededToCommitChanges()); |
| 143 SetExperimentEnabled(&flags_storage_, kFlags1, false); | 444 SetExperimentEnabled(&flags_storage_, kFlags1, false); |
| 144 EXPECT_FALSE(IsRestartNeededToCommitChanges()); | 445 EXPECT_FALSE(IsRestartNeededToCommitChanges()); |
| 145 } | 446 } |
| 146 | 447 |
| 147 TEST_F(AboutFlagsTest, ChangeNeedsRestart) { | 448 TEST_F(AboutFlagsTest, ChangeNeedsRestart) { |
| 148 EXPECT_FALSE(IsRestartNeededToCommitChanges()); | 449 EXPECT_FALSE(IsRestartNeededToCommitChanges()); |
| 149 SetExperimentEnabled(&flags_storage_, kFlags1, true); | 450 SetExperimentEnabled(&flags_storage_, kFlags1, true); |
| 150 EXPECT_TRUE(IsRestartNeededToCommitChanges()); | 451 EXPECT_TRUE(IsRestartNeededToCommitChanges()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 | 527 |
| 227 CommandLine command_line2(CommandLine::NO_PROGRAM); | 528 CommandLine command_line2(CommandLine::NO_PROGRAM); |
| 228 | 529 |
| 229 ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels); | 530 ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels); |
| 230 | 531 |
| 231 EXPECT_TRUE(command_line2.HasSwitch(kSwitch1)); | 532 EXPECT_TRUE(command_line2.HasSwitch(kSwitch1)); |
| 232 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin)); | 533 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin)); |
| 233 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd)); | 534 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd)); |
| 234 } | 535 } |
| 235 | 536 |
| 537 CommandLine::StringType CreateSwitch(const std::string& value) { | |
| 538 #if defined(OS_WIN) | |
| 539 return ASCIIToUTF16(value); | |
| 540 #else | |
| 541 return value; | |
| 542 #endif | |
| 543 } | |
| 544 | |
| 236 TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) { | 545 TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) { |
| 237 SetExperimentEnabled(&flags_storage_, kFlags1, true); | 546 SetExperimentEnabled(&flags_storage_, kFlags1, true); |
| 238 | 547 |
| 548 // double dash | |
| 549 const std::string kDD("--"); | |
|
Ilya Sherman
2014/07/29 07:16:45
nit: Please name this something like "kDoubleDash"
Alexander Alekseev
2014/07/31 00:18:07
Yes, you're right. Done.
| |
| 550 | |
| 239 CommandLine command_line(CommandLine::NO_PROGRAM); | 551 CommandLine command_line(CommandLine::NO_PROGRAM); |
| 240 command_line.AppendSwitch("foo"); | 552 command_line.AppendSwitch("foo"); |
| 241 | 553 |
| 242 CommandLine new_command_line(CommandLine::NO_PROGRAM); | 554 CommandLine new_command_line(CommandLine::NO_PROGRAM); |
| 243 ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels); | 555 ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels); |
| 244 | 556 |
| 245 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, | 557 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( |
| 246 command_line)); | 558 new_command_line, command_line, NULL)); |
| 559 { | |
| 560 std::set<CommandLine::StringType> difference; | |
| 561 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( | |
| 562 new_command_line, command_line, &difference)); | |
| 563 EXPECT_EQ(1U, difference.size()); | |
| 564 EXPECT_EQ(1U, difference.count(CreateSwitch(kDD + kSwitch1))); | |
| 565 } | |
| 247 | 566 |
| 248 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); | 567 ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |
| 249 | 568 |
| 250 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, | 569 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine( |
| 251 command_line)); | 570 new_command_line, command_line, NULL)); |
| 571 { | |
| 572 std::set<CommandLine::StringType> difference; | |
| 573 EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine( | |
| 574 new_command_line, command_line, &difference)); | |
| 575 EXPECT_TRUE(difference.empty()); | |
| 576 } | |
| 252 | 577 |
| 253 // Now both have flags but different. | 578 // Now both have flags but different. |
| 254 SetExperimentEnabled(&flags_storage_, kFlags1, false); | 579 SetExperimentEnabled(&flags_storage_, kFlags1, false); |
| 255 SetExperimentEnabled(&flags_storage_, kFlags2, true); | 580 SetExperimentEnabled(&flags_storage_, kFlags2, true); |
| 256 | 581 |
| 257 CommandLine another_command_line(CommandLine::NO_PROGRAM); | 582 CommandLine another_command_line(CommandLine::NO_PROGRAM); |
| 258 ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels); | 583 ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels); |
| 259 | 584 |
| 260 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, | 585 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( |
| 261 another_command_line)); | 586 new_command_line, another_command_line, NULL)); |
| 587 { | |
| 588 std::set<CommandLine::StringType> difference; | |
| 589 EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( | |
| 590 new_command_line, another_command_line, &difference)); | |
| 591 EXPECT_EQ(2U, difference.size()); | |
| 592 EXPECT_EQ(1U, difference.count(CreateSwitch(kDD + kSwitch1))); | |
| 593 EXPECT_EQ(1U, | |
| 594 difference.count( | |
| 595 CreateSwitch(kDD + kSwitch2 + "=" + kValueForSwitch2))); | |
| 596 } | |
| 262 } | 597 } |
| 263 | 598 |
| 264 TEST_F(AboutFlagsTest, RemoveFlagSwitches) { | 599 TEST_F(AboutFlagsTest, RemoveFlagSwitches) { |
| 265 std::map<std::string, CommandLine::StringType> switch_list; | 600 std::map<std::string, CommandLine::StringType> switch_list; |
| 266 switch_list[kSwitch1] = CommandLine::StringType(); | 601 switch_list[kSwitch1] = CommandLine::StringType(); |
| 267 switch_list[switches::kFlagSwitchesBegin] = CommandLine::StringType(); | 602 switch_list[switches::kFlagSwitchesBegin] = CommandLine::StringType(); |
| 268 switch_list[switches::kFlagSwitchesEnd] = CommandLine::StringType(); | 603 switch_list[switches::kFlagSwitchesEnd] = CommandLine::StringType(); |
| 269 switch_list["foo"] = CommandLine::StringType(); | 604 switch_list["foo"] = CommandLine::StringType(); |
| 270 | 605 |
| 271 SetExperimentEnabled(&flags_storage_, kFlags1, true); | 606 SetExperimentEnabled(&flags_storage_, kFlags1, true); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 TEST_F(AboutFlagsTest, NoSeparators) { | 792 TEST_F(AboutFlagsTest, NoSeparators) { |
| 458 testing::SetExperiments(NULL, 0); | 793 testing::SetExperiments(NULL, 0); |
| 459 size_t count; | 794 size_t count; |
| 460 const Experiment* experiments = testing::GetExperiments(&count); | 795 const Experiment* experiments = testing::GetExperiments(&count); |
| 461 for (size_t i = 0; i < count; ++i) { | 796 for (size_t i = 0; i < count; ++i) { |
| 462 std::string name = experiments->internal_name; | 797 std::string name = experiments->internal_name; |
| 463 EXPECT_EQ(std::string::npos, name.find(testing::kMultiSeparator)) << i; | 798 EXPECT_EQ(std::string::npos, name.find(testing::kMultiSeparator)) << i; |
| 464 } | 799 } |
| 465 } | 800 } |
| 466 | 801 |
| 802 // Checks that enum values are not reused in kExperiments[], i.e. equal | |
| 803 // switches have equal UMA IDs. (Different switches are checked in | |
| 804 // AboutFlagsTest::AboutFlagsTest().) | |
| 805 TEST_F(AboutFlagsTest, SwitchHistogramTableValid) { | |
| 806 if (histogram_id_to_switch_[0]) | |
| 807 EXPECT_STREQ("", histogram_id_to_switch_[0]->c_str()); | |
|
Ilya Sherman
2014/07/29 07:16:45
nit: Prefer std::string() to ""
Alexander Alekseev
2014/07/31 00:18:08
Done.
| |
| 808 EXPECT_FALSE(histogram_id_to_switch_[1]); /* BAD_FLAG_FORMAT, */ | |
| 809 EXPECT_FALSE(histogram_id_to_switch_[2]); /* RESERVED2 */ | |
|
Ilya Sherman
2014/07/29 07:16:45
Why is this RESERVED2 rather than RESERVED1?
Alexander Alekseev
2014/07/31 00:18:07
The idea was to reflect index in constant name.
Bu
| |
| 810 EXPECT_FALSE(histogram_id_to_switch_[3]); /* RESERVED3 */ | |
| 811 EXPECT_FALSE(histogram_id_to_switch_[4]); /* RESERVED4 */ | |
|
Ilya Sherman
2014/07/29 07:16:45
Please assert that the array size is at least 5, s
Alexander Alekseev
2014/07/31 00:18:07
Done.
| |
| 812 for (size_t i = 5; i < histogram_id_to_switch_.size(); ++i) { | |
| 813 // Some values may be missing from histogram_id_to_switch_[] because | |
| 814 // they are under #ifdef and were not compiled. | |
| 815 if (histogram_id_to_switch_[i]) { | |
| 816 EXPECT_LT(i, arraysize(HistogramSwitchesOrdered)) | |
| 817 << "Switch index " << i << " (switch name '" | |
| 818 << histogram_id_to_switch_[i]->c_str() | |
|
Ilya Sherman
2014/07/29 07:16:45
nit: No need for c_str().
Alexander Alekseev
2014/07/31 00:18:08
This is because of ScopedVector .
Ilya Sherman
2014/07/31 00:37:51
I don't understand -- why does a ScopedVector requ
| |
| 819 << "') is found in about_flags, but missing from the test."; | |
| 820 } else { | |
| 821 EXPECT_LT(i, arraysize(HistogramSwitchesOrdered)) | |
| 822 << "Switch index " << i | |
| 823 << " is found in about_flags, but missing from the test."; | |
| 824 } | |
| 825 if (i >= arraysize(HistogramSwitchesOrdered)) | |
| 826 continue; | |
| 827 if (histogram_id_to_switch_[i]) | |
| 828 EXPECT_STREQ(HistogramSwitchesOrdered[i], | |
| 829 histogram_id_to_switch_[i]->c_str()) | |
| 830 << "Switch index " << i << " is wrong."; | |
| 831 } | |
| 832 } | |
| 833 | |
| 834 // Expects |reader| to point at given enum. | |
| 835 // Returns map { value => label }. | |
| 836 // Returns empty map on error. | |
|
Ilya Sherman
2014/07/29 07:16:45
Please expand this comment to be more detailed.
Alexander Alekseev
2014/07/31 00:18:08
Done.
| |
| 837 std::map<int, std::string> ParseEnumFromHistogramsXml( | |
|
Ilya Sherman
2014/07/29 07:16:45
Please move helper functions into the anonymous na
Alexander Alekseev
2014/07/31 00:18:08
Done.
| |
| 838 const std::string& enum_name, | |
| 839 XmlReader& reader) { | |
| 840 size_t entries_index = 0; | |
| 841 | |
| 842 std::map<int, std::string> result; | |
| 843 bool success = true; | |
|
Ilya Sherman
2014/07/29 07:16:45
It looks like you can entirely replace this with e
Alexander Alekseev
2014/07/31 00:18:07
This is to report maximum number of errors on a si
| |
| 844 | |
| 845 while (true) { | |
| 846 const std::string node_name = reader.NodeName(); | |
| 847 if (node_name == "enum" && reader.IsClosingElement()) | |
| 848 break; | |
| 849 | |
| 850 if (node_name == "int") { | |
| 851 ++entries_index; | |
| 852 std::string value_str; | |
| 853 std::string label; | |
| 854 if (!reader.NodeAttribute("value", &value_str)) { | |
| 855 LOG(ERROR) << "Bad " << enum_name << " enum entry (at index " | |
| 856 << entries_index << "): No 'value' attribute."; | |
|
Ilya Sherman
2014/07/29 07:16:45
Did you mean to use an EXPECT_ or ASSERT_ statemen
Alexander Alekseev
2014/07/31 00:18:07
Done.
| |
| 857 success = false; | |
| 858 } | |
| 859 if (!reader.NodeAttribute("label", &label)) { | |
| 860 LOG(ERROR) << "Bad " << enum_name << " enum entry (at index " | |
| 861 << entries_index << "): No 'label' attribute."; | |
| 862 success = false; | |
| 863 } | |
| 864 int value; | |
| 865 if (!base::StringToInt(value_str, &value)) { | |
| 866 LOG(ERROR) << "Bad " << enum_name << " enum entry (at index " | |
| 867 << entries_index << "): No 'label' attribute."; | |
| 868 success = false; | |
| 869 } | |
| 870 if (success) { | |
| 871 result[value] = label; | |
| 872 } | |
| 873 } | |
| 874 reader.Next(); | |
| 875 } | |
| 876 return (success ? result : std::map<int, std::string>()); | |
| 877 } | |
| 878 | |
| 879 // Find and read given enum in histograms.xml. | |
| 880 // Returns map { value => label } so that: | |
| 881 // <int value="9" label="enable-pinch-virtual-viewport"/> | |
| 882 // becomes: | |
| 883 // { 9 => "enable-pinch-virtual-viewport" } | |
| 884 // Returns empty map on error. | |
| 885 std::map<int, std::string> ReadEnumFromHistogramsXml( | |
| 886 const std::string& enum_name, | |
| 887 XmlReader& histograms_xml) { | |
| 888 std::map<int, std::string> login_custom_flags; | |
| 889 | |
| 890 while (true) { | |
| 891 const std::string node_name = histograms_xml.NodeName(); | |
| 892 if (node_name == "enum") { | |
| 893 std::string name; | |
| 894 if (histograms_xml.NodeAttribute("name", &name) && name == enum_name) { | |
| 895 EXPECT_TRUE(login_custom_flags.empty()) | |
| 896 << "Duplicate enum " << enum_name << " found in histograms.xml"; | |
| 897 | |
| 898 if (!login_custom_flags.empty()) | |
| 899 return std::map<int, std::string>(); | |
| 900 | |
| 901 if (histograms_xml.Read()) { | |
| 902 login_custom_flags = | |
| 903 ParseEnumFromHistogramsXml(enum_name, histograms_xml); | |
| 904 EXPECT_FALSE(login_custom_flags.empty()); | |
| 905 if (login_custom_flags.empty()) | |
| 906 return std::map<int, std::string>(); | |
| 907 } | |
| 908 } | |
| 909 } | |
| 910 if (histograms_xml.Read()) | |
| 911 continue; | |
| 912 | |
| 913 if (histograms_xml.Next()) | |
| 914 continue; | |
| 915 | |
| 916 while (histograms_xml.Depth() && !histograms_xml.SkipToElement()) { | |
| 917 } | |
| 918 | |
| 919 if (!histograms_xml.Depth()) | |
| 920 break; | |
|
Ilya Sherman
2014/07/29 07:16:45
Please document what these four control statements
Alexander Alekseev
2014/07/31 00:18:07
Done.
| |
| 921 } | |
| 922 EXPECT_FALSE(login_custom_flags.empty()) << "enum " << enum_name | |
| 923 << " is not found in histograms.xml"; | |
| 924 return login_custom_flags; | |
| 925 } | |
| 926 | |
| 927 std::string FilePathStringTypeToString(const base::FilePath::StringType& path) { | |
| 928 #if defined(OS_WIN) | |
| 929 return UTF16ToUTF8(path); | |
| 930 #else | |
| 931 return path; | |
| 932 #endif | |
| 933 } | |
| 934 | |
| 935 TEST_F(AboutFlagsTest, CheckHistograms) { | |
| 936 base::FilePath histograms_xml_file_path; | |
| 937 ASSERT_TRUE( | |
| 938 PathService::Get(base::DIR_SOURCE_ROOT, &histograms_xml_file_path)); | |
| 939 histograms_xml_file_path = histograms_xml_file_path.AppendASCII("tools") | |
| 940 .AppendASCII("metrics") | |
| 941 .AppendASCII("histograms") | |
| 942 .AppendASCII("histograms.xml"); | |
|
Ilya Sherman
2014/07/29 07:16:45
nit: I don't think this formatting is quite right
Alexander Alekseev
2014/07/31 00:18:07
This is really strange, but it is a result of clan
| |
| 943 | |
| 944 XmlReader histograms_xml; | |
| 945 ASSERT_TRUE(histograms_xml.LoadFile( | |
| 946 FilePathStringTypeToString(histograms_xml_file_path.value()))); | |
| 947 // Check that order and labels of <enum name="LoginCustomFlags" type="int"> | |
| 948 // match HistogramSwitchesOrdered. | |
| 949 std::map<int, std::string> login_custom_flags = | |
| 950 ReadEnumFromHistogramsXml("LoginCustomFlags", histograms_xml); | |
| 951 | |
| 952 for (size_t i = 5; i < arraysize(HistogramSwitchesOrdered); ++i) { | |
| 953 EXPECT_TRUE(login_custom_flags.count(i)) | |
| 954 << "histograms.xml enum LoginCustomFlags doesn't contain switch '" | |
| 955 << HistogramSwitchesOrdered[i] << "'"; | |
| 956 | |
| 957 if (login_custom_flags.count(i)) { | |
| 958 EXPECT_STREQ(HistogramSwitchesOrdered[i], login_custom_flags[i].c_str()) | |
| 959 << "Bad histograms.xml enum LoginCustomFlags entry with value='" << i | |
| 960 << "'."; | |
| 961 } | |
| 962 } | |
| 963 | |
| 964 // If maximum index in histograms.xml is greater than in test, | |
| 965 // report all extra items. | |
| 966 if (static_cast<size_t>(login_custom_flags.rbegin()->first) >= | |
| 967 arraysize(HistogramSwitchesOrdered)) { | |
| 968 for (std::map<int, std::string>::reverse_iterator ri = | |
|
Ilya Sherman
2014/07/29 07:16:45
Again, please use "it" or "iter" for the iterator
Alexander Alekseev
2014/07/31 00:18:07
Done.
| |
| 969 login_custom_flags.rbegin(); | |
| 970 ri != login_custom_flags.rend(); | |
| 971 ++ri) { | |
| 972 if (static_cast<size_t>(ri->first) < arraysize(HistogramSwitchesOrdered)) | |
| 973 break; | |
| 974 EXPECT_LT(static_cast<size_t>(ri->first), | |
| 975 arraysize(HistogramSwitchesOrdered)) | |
| 976 << "Test has no data for histograms.xml enum LoginCustomFlags entry " | |
| 977 "with value='" << ri->first << "' label='" << ri->second << "'"; | |
| 978 } | |
| 979 } | |
| 980 } | |
| 981 | |
| 467 } // namespace about_flags | 982 } // namespace about_flags |
| OLD | NEW |