Add long running gmail memory benchmark for background tab.
[chromium-blink-merge.git] / tools / perf / metrics / startup_metric.py
blob3c5b36f04a507546eb9c72981c3ff63c5917ede3
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 import collections
5 import json
6 import logging
8 from telemetry.core import exceptions
9 from telemetry.value import histogram_util
10 from telemetry.value import scalar
12 from metrics import Metric
15 class StartupMetric(Metric):
16 "A metric for browser startup time."
18 # Seconds to wait for page loading complete.
19 DEFAULT_LOADING_TIMEOUT = 90
21 HISTOGRAMS_TO_RECORD = {
22 'messageloop_start_time' :
23 'Startup.BrowserMessageLoopStartTimeFromMainEntry',
24 'window_display_time' : 'Startup.BrowserWindowDisplay',
25 'open_tabs_time' : 'Startup.BrowserOpenTabs',
26 'first_non_empty_paint_time' : 'Startup.FirstWebContents.NonEmptyPaint',
27 'first_main_frame_load_time' : 'Startup.FirstWebContents.MainFrameLoad'}
29 def Start(self, page, tab):
30 raise NotImplementedError()
32 def Stop(self, page, tab):
33 raise NotImplementedError()
35 def _GetBrowserMainEntryTime(self, tab):
36 """Returns the main entry time (in ms) of the browser."""
37 histogram_type = histogram_util.BROWSER_HISTOGRAM
38 high_bytes = histogram_util.GetHistogramSum(
39 histogram_type,
40 'Startup.BrowserMainEntryTimeAbsoluteHighWord',
41 tab)
42 low_bytes = histogram_util.GetHistogramSum(
43 histogram_type,
44 'Startup.BrowserMainEntryTimeAbsoluteLowWord',
45 tab)
46 if high_bytes == 0 and low_bytes == 0:
47 return None
48 return (int(high_bytes) << 32) | (int(low_bytes) << 1)
50 def _RecordTabLoadTimes(self, tab, browser_main_entry_time_ms, results):
51 """Records the tab load times for the browser. """
52 TabLoadTime = collections.namedtuple(
53 'TabLoadTime',
54 ['request_start_ms', 'load_end_ms'])
56 def RecordOneTab(t):
57 def EvaluateInt(exp):
58 val = t.EvaluateJavaScript(exp)
59 if not val:
60 logging.warn('%s undefined' % exp)
61 return 0
62 return int(val)
64 try:
65 t.WaitForJavaScriptExpression(
66 'window.performance.timing["loadEventEnd"] > 0',
67 self.DEFAULT_LOADING_TIMEOUT)
69 # EvaluateJavaScript(window.performance.timing) doesn't guarantee to
70 # return the desired javascript object (crbug/472603). It may return an
71 # empty object. However getting individual field works.
72 # The behavior depends on Webkit implementation on different platforms.
73 load_event_end = EvaluateInt(
74 'window.performance.timing["loadEventEnd"]')
75 request_start = EvaluateInt(
76 'window.performance.timing["requestStart"]')
78 return TabLoadTime(request_start, load_event_end)
80 except exceptions.TimeoutException:
81 # Low memory Android devices may not be able to load more than
82 # one tab at a time, so may timeout when the test attempts to
83 # access a background tab. Ignore these tabs.
84 logging.error("Tab timed out on JavaScript access")
86 # Only measure the foreground tab. We can't measure all tabs on Android
87 # because on Android the data of the background tabs is loaded on demand,
88 # when the user switches to them, rather than during startup. In view of
89 # this, to get the same measures on all platform, we only measure the
90 # foreground tab on all platforms.
91 foreground_tab_stats = RecordOneTab(tab.browser.foreground_tab)
93 if foreground_tab_stats:
94 foreground_tab_load_complete = (
95 foreground_tab_stats.load_end_ms - browser_main_entry_time_ms)
96 results.AddValue(scalar.ScalarValue(
97 results.current_page, 'foreground_tab_load_complete', 'ms',
98 foreground_tab_load_complete))
99 if foreground_tab_stats.request_start_ms > 0:
100 results.AddValue(scalar.ScalarValue(
101 results.current_page, 'foreground_tab_request_start', 'ms',
102 foreground_tab_stats.request_start_ms - browser_main_entry_time_ms))
104 def AddResults(self, tab, results):
105 get_histogram_js = 'statsCollectionController.getBrowserHistogram("%s")'
107 for display_name, histogram_name in self.HISTOGRAMS_TO_RECORD.iteritems():
108 result = tab.EvaluateJavaScript(get_histogram_js % histogram_name)
109 result = json.loads(result)
110 measured_time = 0
112 if 'sum' in result:
113 # For all the histograms logged here, there's a single entry so sum
114 # is the exact value for that entry.
115 measured_time = result['sum']
116 elif 'buckets' in result:
117 measured_time = \
118 (result['buckets'][0]['high'] + result['buckets'][0]['low']) / 2
120 results.AddValue(scalar.ScalarValue(
121 results.current_page, display_name, 'ms', measured_time))
123 # Get tab load times.
124 browser_main_entry_time_ms = self._GetBrowserMainEntryTime(tab)
125 if browser_main_entry_time_ms is None:
126 print "Outdated Chrome version, browser main entry time not supported."
127 return
128 self._RecordTabLoadTimes(tab, browser_main_entry_time_ms, results)