Home | History | Annotate | Download | only in metrics
      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 
      5 import json
      6 import logging
      7 
      8 from metrics import histogram_util
      9 from metrics import Metric
     10 from telemetry.core import util
     11 
     12 
     13 class StartupMetric(Metric):
     14   """A metric for browser startup time.
     15 
     16   User visible metrics:
     17     process_creation_to_window_display: Time from browser process creation to
     18         the time that the browser window initially becomes visible.
     19     process_creation_to_foreground_tab_loaded: Time from browser process
     20         creation to the time that the foreground tab is fully loaded.
     21     process_creation_to_all_tabs_loaded: Time from the browser process creation
     22         to the time that all tabs have fully loaded.
     23 
     24   Critical code progression:
     25     process_creation_to_main: Time from process creation to the execution of the
     26         browser's main() entry.
     27     main_to_messageloop_start: Time from main() entry to the start of the UI
     28         thread's message loop.
     29   """
     30 
     31   def Start(self, page, tab):
     32     raise NotImplementedError()
     33 
     34   def Stop(self, page, tab):
     35     raise NotImplementedError()
     36 
     37   def _GetBrowserMainEntryTime(self, tab):
     38     """Returns the main entry time (in ms) of the browser."""
     39     high_bytes = histogram_util.GetHistogramSum(
     40         histogram_util.BROWSER_HISTOGRAM,
     41         'Startup.BrowserMainEntryTimeAbsoluteHighWord',
     42         tab)
     43     low_bytes = histogram_util.GetHistogramSum(
     44         histogram_util.BROWSER_HISTOGRAM,
     45         'Startup.BrowserMainEntryTimeAbsoluteLowWord',
     46         tab)
     47     if high_bytes == 0 and low_bytes == 0:
     48       return None
     49     return (int(high_bytes) << 32) | (int(low_bytes) << 1)
     50 
     51   def _GetTabLoadTimes(self, browser):
     52     """Returns a tuple of (foreground_tab_load_time, all_tabs_load_time)."""
     53     foreground_tab_load_time = 0
     54     all_tabs_load_time = 0
     55     for i in xrange(len(browser.tabs)):
     56       try:
     57         tab = browser.tabs[i]
     58         tab_load_timing_js = 'statsCollectionController.tabLoadTiming()'
     59         def HasLoaded():
     60           result = json.loads(tab.EvaluateJavaScript(tab_load_timing_js))
     61           return 'load_duration_ms' in result and result['load_duration_ms']
     62         util.WaitFor(HasLoaded, 60)
     63         result = json.loads(tab.EvaluateJavaScript(tab_load_timing_js))
     64         load_time = result['load_start_ms'] + result['load_duration_ms']
     65         all_tabs_load_time = max(all_tabs_load_time, load_time)
     66         if tab == browser.foreground_tab:
     67           foreground_tab_load_time = load_time
     68       except util.TimeoutException:
     69         # Low memory Android devices may not be able to load more than
     70         # one tab at a time, so may timeout when the test attempts to
     71         # access a background tab. Ignore these tabs.
     72         logging.error('Tab timed out on JavaScript access')
     73     return foreground_tab_load_time, all_tabs_load_time
     74 
     75   def AddResults(self, tab, results):
     76     absolute_browser_main_entry_ms = self._GetBrowserMainEntryTime(tab)
     77 
     78     process_creation_to_window_display_ms = histogram_util.GetHistogramSum(
     79         histogram_util.BROWSER_HISTOGRAM, 'Startup.BrowserWindowDisplay', tab)
     80     absolute_foreground_tab_loaded_ms, absolute_all_tabs_loaded_ms = \
     81         self._GetTabLoadTimes(tab.browser)
     82     process_creation_to_messageloop_start_ms = histogram_util.GetHistogramSum(
     83         histogram_util.BROWSER_HISTOGRAM, 'Startup.BrowserMessageLoopStartTime',
     84         tab)
     85     main_to_messageloop_start_ms = histogram_util.GetHistogramSum(
     86         histogram_util.BROWSER_HISTOGRAM,
     87         'Startup.BrowserMessageLoopStartTimeFromMainEntry',
     88         tab)
     89     process_creation_to_main = (process_creation_to_messageloop_start_ms -
     90                                 main_to_messageloop_start_ms)
     91 
     92     # User visible.
     93     results.Add('process_creation_to_window_display', 'ms',
     94                 process_creation_to_window_display_ms)
     95     results.Add('process_creation_to_foreground_tab_loaded', 'ms',
     96                 absolute_foreground_tab_loaded_ms -
     97                 absolute_browser_main_entry_ms + process_creation_to_main)
     98     results.Add('process_creation_to_all_tabs_loaded', 'ms',
     99                 absolute_all_tabs_loaded_ms -
    100                 absolute_browser_main_entry_ms + process_creation_to_main)
    101 
    102     # Critical code progression.
    103     results.Add('process_creation_to_main', 'ms',
    104                 process_creation_to_main)
    105     results.Add('main_to_messageloop_start', 'ms',
    106                 main_to_messageloop_start_ms)
    107