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.
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(
35 'Startup.BrowserMainEntryTimeAbsoluteHighWord',
37 low_bytes
= histogram_util
.GetHistogramSum(
39 'Startup.BrowserMainEntryTimeAbsoluteLowWord',
41 if high_bytes
== 0 and low_bytes
== 0:
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. """
48 TabLoadTime
= collections
.namedtuple(
50 ['load_start_ms', 'load_duration_ms', 'request_start_ms'])
52 def RecordTabLoadTime(t
):
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."
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
)
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
:
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."
126 self
._RecordTabLoadTimes
(tab
, browser_main_entry_time_ms
, results
)