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

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: Use PathService to get DIR_SOURCE_ROOT in unit test. 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"
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698