Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / tools / perf / metrics / startup_metric.py
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
7
8 from metrics import Metric
9
10 from telemetry.core import util
11 from telemetry.value import histogram_util
12 from telemetry.value import scalar
13
14
15 class StartupMetric(Metric):
16   "A metric for browser startup time."
17
18   HISTOGRAMS_TO_RECORD = {
19     'messageloop_start_time' :
20         'Startup.BrowserMessageLoopStartTimeFromMainEntry',
21     'window_display_time' : 'Startup.BrowserWindowDisplay',
22     'open_tabs_time' : 'Startup.BrowserOpenTabs'}
23
24   def Start(self, page, tab):
25     raise NotImplementedError()
26
27   def Stop(self, page, tab):
28     raise NotImplementedError()
29
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)
44
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'])
51
52     def RecordTabLoadTime(t):
53       try:
54         t.WaitForDocumentReadyStateToBeComplete()
55
56         result = t.EvaluateJavaScript(
57             'statsCollectionController.tabLoadTiming()')
58         result = json.loads(result)
59
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
67
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'
72
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")
82
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.
88
89     RecordTabLoadTime(tab.browser.foreground_tab)
90
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))
101
102   def AddResults(self, tab, results):
103     get_histogram_js = 'statsCollectionController.getBrowserHistogram("%s")'
104
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
109
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
117
118       results.AddValue(scalar.ScalarValue(
119           results.current_page, display_name, 'ms', measured_time))
120
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)