11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport collections 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import json 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import logging 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)from metrics import Metric 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.core import util 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifrom telemetry.value import histogram_util 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry.value import scalar 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class StartupMetric(Metric): 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "A metric for browser startup time." 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch HISTOGRAMS_TO_RECORD = { 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'messageloop_start_time' : 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'Startup.BrowserMessageLoopStartTimeFromMainEntry', 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'window_display_time' : 'Startup.BrowserWindowDisplay', 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'open_tabs_time' : 'Startup.BrowserOpenTabs'} 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def Start(self, page, tab): 251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) raise NotImplementedError() 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def Stop(self, page, tab): 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) raise NotImplementedError() 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def _GetBrowserMainEntryTime(self, tab): 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Returns the main entry time (in ms) of the browser.""" 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch histogram_type = histogram_util.BROWSER_HISTOGRAM 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) high_bytes = histogram_util.GetHistogramSum( 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch histogram_type, 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'Startup.BrowserMainEntryTimeAbsoluteHighWord', 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) tab) 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) low_bytes = histogram_util.GetHistogramSum( 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch histogram_type, 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'Startup.BrowserMainEntryTimeAbsoluteLowWord', 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) tab) 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if high_bytes == 0 and low_bytes == 0: 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return None 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (int(high_bytes) << 32) | (int(low_bytes) << 1) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def _RecordTabLoadTimes(self, tab, browser_main_entry_time_ms, results): 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch """Records the tab load times for the browser. """ 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tab_load_times = [] 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TabLoadTime = collections.namedtuple( 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'TabLoadTime', 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ['load_start_ms', 'load_duration_ms']) 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def RecordTabLoadTime(t): 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch t.WaitForDocumentReadyStateToBeComplete() 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = t.EvaluateJavaScript( 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'statsCollectionController.tabLoadTiming()') 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = json.loads(result) 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if 'load_start_ms' not in result or 'load_duration_ms' not in result: 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise Exception("Outdated Chrome version, " 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "statsCollectionController.tabLoadTiming() not present") 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if result['load_duration_ms'] is None: 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tab_title = t.EvaluateJavaScript('document.title') 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch print "Page: ", tab_title, " didn't finish loading." 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tab_load_times.append(TabLoadTime( 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int(result['load_start_ms']), 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int(result['load_duration_ms']))) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except util.TimeoutException: 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Low memory Android devices may not be able to load more than 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # one tab at a time, so may timeout when the test attempts to 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # access a background tab. Ignore these tabs. 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch logging.error("Tab timed out on JavaScript access") 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # Only measure the foreground tab. We can't measure all tabs on Android 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # because on Android the data of the background tabs is loaded on demand, 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # when the user switches to them, rather than during startup. In view of 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # this, to get the same measures on all platform, we only measure the 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # foreground tab on all platforms. 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RecordTabLoadTime(tab.browser.foreground_tab) 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch foreground_tab_stats = tab_load_times[0] 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch foreground_tab_load_complete = ((foreground_tab_stats.load_start_ms + 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch foreground_tab_stats.load_duration_ms) - browser_main_entry_time_ms) 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch results.AddValue(scalar.ScalarValue( 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch results.current_page, 'foreground_tab_load_complete', 'ms', 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch foreground_tab_load_complete)) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def AddResults(self, tab, results): 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch get_histogram_js = 'statsCollectionController.getBrowserHistogram("%s")' 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for display_name, histogram_name in self.HISTOGRAMS_TO_RECORD.iteritems(): 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = tab.EvaluateJavaScript(get_histogram_js % histogram_name) 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = json.loads(result) 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch measured_time = 0 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if 'sum' in result: 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # For all the histograms logged here, there's a single entry so sum 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # is the exact value for that entry. 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch measured_time = result['sum'] 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch elif 'buckets' in result: 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch measured_time = \ 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (result['buckets'][0]['high'] + result['buckets'][0]['low']) / 2 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch results.AddValue(scalar.ScalarValue( 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch results.current_page, display_name, 'ms', measured_time)) 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # Get tab load times. 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser_main_entry_time_ms = self._GetBrowserMainEntryTime(tab) 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (browser_main_entry_time_ms is None): 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch print "Outdated Chrome version, browser main entry time not supported." 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._RecordTabLoadTimes(tab, browser_main_entry_time_ms, results) 117