Change next_proto member type.
[chromium-blink-merge.git] / tools / perf / metrics / startup_metric.py
blobabf62da3bdb9234f614285f397d6264c795f647c
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 metrics import Metric
10 from telemetry.core import util
11 from telemetry.value import histogram_util
12 from telemetry.value import scalar
15 class StartupMetric(Metric):
16 "A metric for browser startup time."
18 HISTOGRAMS_TO_RECORD = {
19 'messageloop_start_time' :
20 'Startup.BrowserMessageLoopStartTimeFromMainEntry',
21 'window_display_time' : 'Startup.BrowserWindowDisplay',
22 'open_tabs_time' : 'Startup.BrowserOpenTabs'}
24 def Start(self, page, tab):
25 raise NotImplementedError()
27 def Stop(self, page, tab):
28 raise NotImplementedError()
30 def _GetBrowserMainEntryTime(self, tab):
31 """Returns the main entry time (in ms) of the browser."""
32 histogram_type = histogram_util.BROWSER_HISTOGRAM
33 high_bytes = histogram_util.GetHistogramSum(
34 histogram_type,
35 'Startup.BrowserMainEntryTimeAbsoluteHighWord',
36 tab)
37 low_bytes = histogram_util.GetHistogramSum(
38 histogram_type,
39 'Startup.BrowserMainEntryTimeAbsoluteLowWord',
40 tab)
41 if high_bytes == 0 and low_bytes == 0:
42 return None
43 return (int(high_bytes) << 32) | (int(low_bytes) << 1)
45 def _RecordTabLoadTimes(self, tab, browser_main_entry_time_ms, results):
46 """Records the tab load times for the browser. """
47 tab_load_times = []
48 TabLoadTime = collections.namedtuple(
49 'TabLoadTime',
50 ['load_start_ms', 'load_duration_ms', 'request_start_ms'])
52 def RecordTabLoadTime(t):
53 try:
54 t.WaitForDocumentReadyStateToBeComplete()
56 result = t.EvaluateJavaScript(
57 'statsCollectionController.tabLoadTiming()')
58 result = json.loads(result)
60 if 'load_start_ms' not in result or 'load_duration_ms' not in result:
61 raise Exception("Outdated Chrome version, "
62 "statsCollectionController.tabLoadTiming() not present")
63 if result['load_duration_ms'] is None:
64 tab_title = t.EvaluateJavaScript('document.title')
65 print "Page: ", tab_title, " didn't finish loading."
66 return
68 perf_timing = t.EvaluateJavaScript('window.performance.timing')
69 if 'requestStart' not in perf_timing:
70 perf_timing['requestStart'] = 0 # Exclude from benchmark results
71 print 'requestStart is not supported by this browser'
73 tab_load_times.append(TabLoadTime(
74 int(result['load_start_ms']),
75 int(result['load_duration_ms']),
76 int(perf_timing['requestStart'])))
77 except util.TimeoutException:
78 # Low memory Android devices may not be able to load more than
79 # one tab at a time, so may timeout when the test attempts to
80 # access a background tab. Ignore these tabs.
81 logging.error("Tab timed out on JavaScript access")
83 # Only measure the foreground tab. We can't measure all tabs on Android
84 # because on Android the data of the background tabs is loaded on demand,
85 # when the user switches to them, rather than during startup. In view of
86 # this, to get the same measures on all platform, we only measure the
87 # foreground tab on all platforms.
89 RecordTabLoadTime(tab.browser.foreground_tab)
91 foreground_tab_stats = tab_load_times[0]
92 foreground_tab_load_complete = ((foreground_tab_stats.load_start_ms +
93 foreground_tab_stats.load_duration_ms) - browser_main_entry_time_ms)
94 results.AddValue(scalar.ScalarValue(
95 results.current_page, 'foreground_tab_load_complete', 'ms',
96 foreground_tab_load_complete))
97 if (foreground_tab_stats.request_start_ms > 0):
98 results.AddValue(scalar.ScalarValue(
99 results.current_page, 'foreground_tab_request_start', 'ms',
100 foreground_tab_stats.request_start_ms - browser_main_entry_time_ms))
102 def AddResults(self, tab, results):
103 get_histogram_js = 'statsCollectionController.getBrowserHistogram("%s")'
105 for display_name, histogram_name in self.HISTOGRAMS_TO_RECORD.iteritems():
106 result = tab.EvaluateJavaScript(get_histogram_js % histogram_name)
107 result = json.loads(result)
108 measured_time = 0
110 if 'sum' in result:
111 # For all the histograms logged here, there's a single entry so sum
112 # is the exact value for that entry.
113 measured_time = result['sum']
114 elif 'buckets' in result:
115 measured_time = \
116 (result['buckets'][0]['high'] + result['buckets'][0]['low']) / 2
118 results.AddValue(scalar.ScalarValue(
119 results.current_page, display_name, 'ms', measured_time))
121 # Get tab load times.
122 browser_main_entry_time_ms = self._GetBrowserMainEntryTime(tab)
123 if (browser_main_entry_time_ms is None):
124 print "Outdated Chrome version, browser main entry time not supported."
125 return
126 self._RecordTabLoadTimes(tab, browser_main_entry_time_ms, results)