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.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport collections
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from measurements import startup
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from metrics import cpu
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from metrics import startup_metric
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)from telemetry.core import util
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifrom telemetry.value import histogram_util
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class SessionRestore(startup.Startup):
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  """Performs a measurement of Chromium's Session restore performance.
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  This test is meant to be run against a generated profile.
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  This test inherits support for the --warm or --cold command line options -
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  see startup.py for details.
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  """
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def __init__(self, action_name_to_run = ''):
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    super(SessionRestore, self).__init__(action_name_to_run=action_name_to_run)
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self.close_tabs_before_run = False
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self._cpu_metric = None
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def CustomizeBrowserOptions(self, options):
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    super(SessionRestore, self).CustomizeBrowserOptions(options)
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    histogram_util.CustomizeBrowserOptions(options)
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    options.AppendExtraBrowserArgs([
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        '--restore-last-session'
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ])
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  def TabForPage(self, page, browser):
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    # Detect that the session restore has completed.
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    util.WaitFor(lambda: browser.tabs and
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 histogram_util.GetHistogramCount(
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     histogram_util.BROWSER_HISTOGRAM,
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     'SessionRestore.AllTabsLoaded',
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     browser.foreground_tab),
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 60)
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return browser.foreground_tab
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def CanRunForPage(self, page):
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    # No matter how many pages in the pageset, just perform one test iteration.
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return page.page_set.pages.index(page) == 0
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def RunNavigateSteps(self, page, tab):
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    # Overriden so that no page navigation occurs.
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pass
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def ValidatePageSet(self, page_set):
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    wpr_archive_names_to_page_urls = collections.defaultdict(list)
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    # Construct the map from pages' wpr archive names to pages' urls.
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for page in page_set:
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if page.is_local:
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        continue
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      wpr_archive_name = page_set.WprFilePathForPage(page)
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      wpr_archive_names_to_page_urls[wpr_archive_name].append(page.url)
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    # Reject any pageset that contains more than one WPR archive.
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if len(wpr_archive_names_to_page_urls.keys()) > 1:
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      raise Exception("Invalid pageset: more than 1 WPR archive found.: " +
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          repr(wpr_archive_names_to_page_urls))
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  def DidStartBrowser(self, browser):
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self._cpu_metric = cpu.CpuMetric(browser)
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self._cpu_metric.Start(None, None)
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def ValidateAndMeasurePage(self, page, tab, results):
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    tab.WaitForDocumentReadyStateToBeComplete()
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    # Record CPU usage from browser start to when the foreground page is loaded.
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self._cpu_metric.Stop(None, None)
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self._cpu_metric.AddResults(tab, results, 'cpu_utilization')
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    startup_metric.StartupMetric().AddResults(tab, results)
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    # TODO(jeremy): Measure time to load - first, last and frontmost tab here.
80