page_runner.py revision 0529e5d033099cbfc42635f6f6183833b09dff6e
10511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com# Copyright (c) 2012 The Chromium Authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org# Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org# found in the LICENSE file.
40511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
50511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comimport collections
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgimport copy
70511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comimport glob
85de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgimport logging
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgimport optparse
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgimport os
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgimport random
124b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.orgimport sys
134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.orgimport tempfile
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgimport time
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgfrom telemetry import decorators
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgfrom telemetry.core import browser_finder
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgfrom telemetry.core import exceptions
190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comfrom telemetry.core import util
200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comfrom telemetry.core import wpr_modes
210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comfrom telemetry.core.platform.profiler import profiler_finder
220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comfrom telemetry.page import cloud_storage
234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.page import page_filter
244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.page import page_runner_repeat
254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.page import page_test
264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.page import results_options
274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.page.actions import navigate
284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.page.actions import page_action
294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgfrom telemetry.util import exception_formatter
304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass _RunState(object):
334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  def __init__(self):
344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    self.browser = None
354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self._append_to_existing_wpr = False
370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self._last_archive_path = None
380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self._first_browser = True
394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    self.first_page = collections.defaultdict(lambda: True)
404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    self.profiler_dir = None
410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self.repeat_state = None
420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def StartBrowserIfNeeded(self, test, page_set, page, possible_browser,
440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                           credentials_path, archive_path):
450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    started_browser = not self.browser
460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    # Create a browser.
470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if not self.browser:
480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      test.CustomizeBrowserOptionsForSinglePage(page,
490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                                                possible_browser.finder_options)
500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser = possible_browser.Create()
510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser.credentials.credentials_path = credentials_path
520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # Set up WPR path on the new browser.
540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser.SetReplayArchivePath(archive_path,
550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                                        self._append_to_existing_wpr,
560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                                        page_set.make_javascript_deterministic)
570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self._last_archive_path = page.archive_path
580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      test.WillStartBrowser(self.browser)
600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser.Start()
610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      test.DidStartBrowser(self.browser)
620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if self._first_browser:
640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self._first_browser = False
650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self.browser.credentials.WarnIfMissingCredentials(page_set)
660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        logging.info('OS: %s %s',
670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                     self.browser.platform.GetOSName(),
680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                     self.browser.platform.GetOSVersionName())
690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        if self.browser.supports_system_info:
700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          system_info = self.browser.GetSystemInfo()
710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          if system_info.model_name:
720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            logging.info('Model: %s' % system_info.model_name)
730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          if system_info.gpu:
740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            for i, device in enumerate(system_info.gpu.devices):
750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              logging.info('GPU device %d: %s', i, device)
760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            if system_info.gpu.aux_attributes:
770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              logging.info('GPU Attributes:')
780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              for k, v in sorted(system_info.gpu.aux_attributes.iteritems()):
790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                logging.info('  %-20s: %s', k, v)
800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            if system_info.gpu.feature_status:
810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              logging.info('Feature Status:')
820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              for k, v in sorted(system_info.gpu.feature_status.iteritems()):
830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                logging.info('  %-20s: %s', k, v)
840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            if system_info.gpu.driver_bug_workarounds:
850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              logging.info('Driver Bug Workarounds:')
860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              for workaround in system_info.gpu.driver_bug_workarounds:
870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                logging.info('  %s', workaround)
880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          else:
890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            logging.info('No GPU devices')
900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    else:
910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # Set up WPR path if it changed.
920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if page.archive_path and self._last_archive_path != page.archive_path:
930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self.browser.SetReplayArchivePath(
940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            page.archive_path,
950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            self._append_to_existing_wpr,
960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            page_set.make_javascript_deterministic)
970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self._last_archive_path = page.archive_path
980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if self.browser.supports_tab_control and test.close_tabs_before_run:
1000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # Create a tab if there's none.
1010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if len(self.browser.tabs) == 0:
1020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        # TODO(nduca/tonyg): Remove this line. Added as part of crbug.com/348337
1030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        # chasing.
1040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        logging.warning('Making a new tab\n')
1050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self.browser.tabs.New()
1060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # Ensure only one tab is open, unless the test is a multi-tab test.
1080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if not test.is_multi_tab_test:
1094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        while len(self.browser.tabs) > 1:
1100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          self.browser.tabs[-1].Close()
1110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # Must wait for tab to commit otherwise it can commit after the next
1130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # navigation has begun and RenderFrameHostManager::DidNavigateMainFrame()
1140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # will cancel the next navigation because it's pending. This manifests as
1150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # the first navigation in a PageSet freezing indefinitly because the
1160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # navigation was silently cancelled when |self.browser.tabs[0]| was
1170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # committed. Only do this when we just started the browser, otherwise
1180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # there are cases where previous pages in a PageSet never complete
1190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # loading so we'll wait forever.
1200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if started_browser:
1210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self.browser.tabs[0].WaitForDocumentReadyStateToBeComplete()
1220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def StopBrowser(self):
1240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if self.browser:
1250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser.Close()
1260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser = None
1270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # Restarting the state will also restart the wpr server. If we're
1290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # recording, we need to continue adding into the same wpr archive,
1300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      # not overwrite it.
1310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self._append_to_existing_wpr = True
1320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def StartProfiling(self, page, finder_options):
1340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if not self.profiler_dir:
1350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.profiler_dir = tempfile.mkdtemp()
1360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    output_file = os.path.join(self.profiler_dir, page.file_safe_name)
1370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    is_repeating = (finder_options.page_repeat != 1 or
1380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                    finder_options.pageset_repeat != 1)
1390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if is_repeating:
1400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      output_file = _GetSequentialFileName(output_file)
1410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self.browser.StartProfiling(finder_options.profiler, output_file)
1420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def StopProfiling(self):
1440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if self.browser:
1450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self.browser.StopProfiling()
1460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass PageState(object):
1490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def __init__(self, page, tab):
1500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self.page = page
1510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self.tab = tab
1520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    self._did_login = False
1540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def PreparePage(self, test=None):
1560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if self.page.is_file:
1570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      server_started = self.tab.browser.SetHTTPServerDirectories(
1580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        self.page.page_set.serving_dirs | set([self.page.serving_dir]))
1590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if server_started and test:
1600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        test.DidStartHTTPServer(self.tab)
1610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if self.page.credentials:
1630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if not self.tab.browser.credentials.LoginNeeded(
1640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          self.tab, self.page.credentials):
1650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        raise page_test.Failure('Login as ' + self.page.credentials + ' failed')
1660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      self._did_login = True
1670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1687bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    if test:
1690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if test.clear_cache_before_each_run:
1704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        self.tab.ClearCache(force=True)
1714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  def ImplicitPageNavigation(self, test=None):
1734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    """Executes the implicit navigation that occurs for every page iteration.
1744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    This function will be called once per page before any actions are executed.
1764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    """
17733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if test:
1784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      test.WillNavigateToPage(self.page, self.tab)
1794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      test.RunNavigateSteps(self.page, self.tab)
1804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      test.DidNavigateToPage(self.page, self.tab)
1814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    else:
1824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      i = navigate.NavigateAction()
1834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      i.RunAction(self.page, self.tab, None)
1844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  def CleanUpPage(self, test):
1864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    test.CleanUpAfterPage(self.page, self.tab)
18733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if self.page.credentials and self._did_login:
1884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      self.tab.browser.credentials.LoginNoLongerNeeded(
1894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          self.tab, self.page.credentials)
1904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef AddCommandLineArgs(parser):
1934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  page_filter.PageFilter.AddCommandLineArgs(parser)
1944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  results_options.AddResultsOptions(parser)
1954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  # Page set options
1974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  group = optparse.OptionGroup(parser, 'Page set ordering and repeat options')
198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  group.add_option('--pageset-shuffle', action='store_true',
1994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      dest='pageset_shuffle',
2004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      help='Shuffle the order of pages within a pageset.')
2014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  group.add_option('--pageset-shuffle-order-file',
2024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      dest='pageset_shuffle_order_file', default=None,
2034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      help='Filename of an output of a previously run test on the current '
2044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      'pageset. The tests will run in the same order again, overriding '
2054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      'what is specified by --page-repeat and --pageset-repeat.')
2064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  group.add_option('--page-repeat', default=1, type='int',
2074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                   help='Number of times to repeat each individual page '
2084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                   'before proceeding with the next page in the pageset.')
2094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  group.add_option('--pageset-repeat', default=1, type='int',
2104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                   help='Number of times to repeat the entire pageset.')
2114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  parser.add_option_group(group)
2124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  # WPR options
2144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  group = optparse.OptionGroup(parser, 'Web Page Replay options')
2154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  group.add_option('--use-live-sites',
2164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      dest='use_live_sites', action='store_true',
2174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      help='Run against live sites and ignore the Web Page Replay archives.')
2184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  parser.add_option_group(group)
2194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef ProcessCommandLineArgs(parser, args):
2224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  page_filter.PageFilter.ProcessCommandLineArgs(parser, args)
2230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
2240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # Page set options
2254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if args.pageset_shuffle_order_file and not args.pageset_shuffle:
2264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    parser.error('--pageset-shuffle-order-file requires --pageset-shuffle.')
2274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if args.page_repeat < 1:
2294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    parser.error('--page-repeat must be a positive integer.')
2304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if args.pageset_repeat < 1:
2314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    parser.error('--pageset-repeat must be a positive integer.')
2324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
234ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.orgdef _LogStackTrace(title, browser):
2354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if browser:
2364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    stack_trace = browser.GetStackTrace()
2374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  else:
2384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    stack_trace = 'Browser object is empty, no stack trace.'
2394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  stack_trace = (('\nStack Trace:\n') +
2404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org            ('*' * 80) +
2414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org            '\n\t' + stack_trace.replace('\n', '\n\t') + '\n' +
2424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org            ('*' * 80))
2434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  logging.warning('%s%s', title, stack_trace)
2444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef _PrepareAndRunPage(test, page_set, expectations, finder_options,
2474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                       browser_options, page, credentials_path,
2484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                       possible_browser, results, state):
2494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if browser_options.wpr_mode != wpr_modes.WPR_RECORD:
2504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    possible_browser.finder_options.browser_options.wpr_mode = (
2514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        wpr_modes.WPR_REPLAY
2524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        if page.archive_path and os.path.isfile(page.archive_path)
2534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        else wpr_modes.WPR_OFF)
2544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  tries = test.attempts
2564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  while tries:
2574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    tries -= 1
2584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    try:
2594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      results_for_current_run = copy.copy(results)
2604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      results_for_current_run.StartTest(page)
2614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      if test.RestartBrowserBeforeEachPage() or page.startup_url:
2624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        state.StopBrowser()
2634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        # If we are restarting the browser for each page customize the per page
2644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        # options for just the current page before starting the browser.
2654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      state.StartBrowserIfNeeded(test, page_set, page, possible_browser,
2664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                 credentials_path, page.archive_path)
2674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      expectation = expectations.GetExpectationForPage(state.browser, page)
2694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      _WaitForThermalThrottlingIfNeeded(state.browser.platform)
2714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      if finder_options.profiler:
2734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        state.StartProfiling(page, finder_options)
2744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      try:
2764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        _RunPage(test, page, state, expectation,
2774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                 results_for_current_run, finder_options)
2784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        _CheckThermalThrottling(state.browser.platform)
2794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      except exceptions.TabCrashException:
2804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        _LogStackTrace('Tab crashed: %s' % page.url, state.browser)
2814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        if test.is_multi_tab_test:
2824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          logging.error('Stopping multi-tab test after tab %s crashed'
2834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                        % page.url)
2840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          raise
2850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        else:
2860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          state.StopBrowser()
2870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
2880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if finder_options.profiler:
2890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        state.StopProfiling()
2900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
2910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if (test.StopBrowserAfterPage(state.browser, page)):
2920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        state.StopBrowser()
2930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
2940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      results_for_current_run.StopTest(page)
2950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
2960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if state.first_page[page]:
2970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        state.first_page[page] = False
29831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org        if test.discard_first_result:
2990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          return results
3000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      return results_for_current_run
3010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    except exceptions.BrowserGoneException:
3020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      _LogStackTrace('Browser crashed', state.browser)
3030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      logging.warning('Lost connection to browser. Retrying.')
3040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      state.StopBrowser()
3050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if not tries:
3060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        logging.error('Lost connection to browser 3 times. Failing.')
3070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        raise
3080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if test.is_multi_tab_test:
3090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        logging.error(
3100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          'Lost connection to browser during multi-tab test. Failing.')
3110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        raise
3120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comdef _UpdatePageSetArchivesIfChanged(page_set):
3150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # Attempt to download the credentials file.
3160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if page_set.credentials_path:
3170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    try:
3180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      cloud_storage.GetIfChanged(
3197bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org          os.path.join(page_set.base_dir, page_set.credentials_path))
3200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    except (cloud_storage.CredentialsError, cloud_storage.PermissionError):
3210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      logging.warning('Cannot retrieve credential file: %s',
3220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                      page_set.credentials_path)
32333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  # Scan every serving directory for .sha1 files
3240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # and download them from Cloud Storage. Assume all data is public.
3250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  all_serving_dirs = page_set.serving_dirs.copy()
3260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # Add individual page dirs to all serving dirs.
3270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  for page in page_set:
3280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if page.is_file:
3290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      all_serving_dirs.add(page.serving_dir)
33033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  # Scan all serving dirs.
3310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  for serving_dir in all_serving_dirs:
3320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if os.path.splitdrive(serving_dir)[1] == '/':
3330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      raise ValueError('Trying to serve root directory from HTTP server.')
3340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    for dirpath, _, filenames in os.walk(serving_dir):
3350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      for filename in filenames:
3360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        path, extension = os.path.splitext(
3370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            os.path.join(dirpath, filename))
3380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        if extension != '.sha1':
3390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          continue
3400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        cloud_storage.GetIfChanged(path)
3410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comdef Run(test, page_set, expectations, finder_options):
3440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  """Runs a given test against a given page_set with the given options."""
3450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  results = results_options.PrepareResults(test, finder_options)
3460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  browser_options = finder_options.browser_options
3470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  test.ValidatePageSet(page_set)
3490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # Create a possible_browser with the given options.
3510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  test.CustomizeBrowserOptions(finder_options)
3520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  try:
3530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    possible_browser = browser_finder.FindBrowser(finder_options)
3544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except browser_finder.BrowserTypeRequiredException, e:
3554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    sys.stderr.write(str(e) + '\n')
3564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    sys.exit(-1)
3574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if not possible_browser:
3584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    sys.stderr.write(
3594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        'No browser found. Available browsers:\n' +
3604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)) +
3614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        '\n')
3624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    sys.exit(-1)
3634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  browser_options.browser_type = possible_browser.browser_type
3654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if not decorators.IsEnabled(
3674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      test, browser_options.browser_type, possible_browser.platform):
3684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return results
3694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  # Reorder page set based on options.
3710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  pages = _ShuffleAndFilterPageSet(page_set, finder_options)
3724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (not finder_options.use_live_sites and
3744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      browser_options.wpr_mode != wpr_modes.WPR_RECORD):
3754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    _UpdatePageSetArchivesIfChanged(page_set)
3764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    pages = _CheckArchives(page_set, pages, results)
3774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # Verify credentials path.
3794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  credentials_path = None
3804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if page_set.credentials_path:
3814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    credentials_path = os.path.join(os.path.dirname(page_set.file_path),
3824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                    page_set.credentials_path)
3834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if not os.path.exists(credentials_path):
3844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      credentials_path = None
3854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  # Set up user agent.
3870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if page_set.user_agent_type:
3880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    browser_options.browser_user_agent_type = page_set.user_agent_type
3890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if finder_options.profiler:
3910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    profiler_class = profiler_finder.FindProfiler(finder_options.profiler)
3920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    profiler_class.CustomizeBrowserOptions(possible_browser.browser_type,
3930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                                           possible_browser.finder_options)
3940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
3950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  for page in list(pages):
3960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if not test.CanRunForPage(page):
3970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      logging.debug('Skipping test: it cannot run for %s', page.url)
3980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      results.AddSkip(page, 'Test cannot run')
3990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      pages.remove(page)
4000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if not pages:
4020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    return results
4030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  state = _RunState()
4050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # TODO(dtu): Move results creation and results_for_current_run into RunState.
4060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  try:
4080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    test.WillRunTest(finder_options)
4090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    state.repeat_state = page_runner_repeat.PageRunnerRepeatState(
4100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        finder_options)
4110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    state.repeat_state.WillRunPageSet()
4130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    while state.repeat_state.ShouldRepeatPageSet() and not test.IsExiting():
4140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      for page in pages:
4150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        state.repeat_state.WillRunPage()
4160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        test.WillRunPageRepeats(page)
4170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        while state.repeat_state.ShouldRepeatPage():
4180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          results = _PrepareAndRunPage(
4197bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org              test, page_set, expectations, finder_options, browser_options,
4200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com              page, credentials_path, possible_browser, results, state)
4217bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org          state.repeat_state.DidRunPage()
4220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        test.DidRunPageRepeats(page)
4230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        if (not test.max_failures is None and
4240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            len(results.failures) > test.max_failures):
4250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          logging.error('Too many failures. Aborting.')
4260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          test.RequestExit()
4270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        if (not test.max_errors is None and
4280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com            len(results.errors) > test.max_errors):
4290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          logging.error('Too many errors. Aborting.')
4300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          test.RequestExit()
4310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        if test.IsExiting():
4320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          break
4330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      state.repeat_state.DidRunPageSet()
4340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    test.DidRunTest(state.browser, results)
4360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  finally:
4370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    state.StopBrowser()
4380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  return results
4400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comdef _ShuffleAndFilterPageSet(page_set, finder_options):
4430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if finder_options.pageset_shuffle_order_file:
4440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    return page_set.ReorderPageSet(finder_options.pageset_shuffle_order_file)
4450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  pages = [page for page in page_set.pages[:]
4470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com           if not page.disabled and page_filter.PageFilter.IsSelected(page)]
4480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if finder_options.pageset_shuffle:
4500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    random.Random().shuffle(pages)
4510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  return pages
4530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comdef _CheckArchives(page_set, pages, results):
4560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  """Returns a subset of pages that are local or have WPR archives.
4570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Logs warnings if any are missing."""
4590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  page_set_has_live_sites = False
4600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  for page in pages:
4610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if not page.is_local:
4620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      page_set_has_live_sites = True
4630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      break
4640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  # Potential problems with the entire page set.
4660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if page_set_has_live_sites:
4670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if not page_set.archive_data_file:
4680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      logging.warning('The page set is missing an "archive_data_file" '
4697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                      'property. Skipping any live sites. To include them, '
4700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                      'pass the flag --use-live-sites.')
4710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if not page_set.wpr_archive_info:
4720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      logging.warning('The archive info file is missing. '
4730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                      'To fix this, either add svn-internal to your '
4740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                      '.gclient using http://goto/read-src-internal, '
4754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                      'or create a new archive using record_wpr.')
4764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
4774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  # Potential problems with individual pages.
4784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  pages_missing_archive_path = []
4794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  pages_missing_archive_data = []
4804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
481c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  for page in pages:
4824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if page.is_local:
4834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      continue
484c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
4854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if not page.archive_path:
4864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      pages_missing_archive_path.append(page)
4874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    elif not os.path.isfile(page.archive_path):
4884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      pages_missing_archive_data.append(page)
4894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
4904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if pages_missing_archive_path:
4914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.warning('The page set archives for some pages do not exist. '
4924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'Skipping those pages. To fix this, record those pages '
4934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'using record_wpr. To ignore this warning and run '
4944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'against live sites, pass the flag --use-live-sites.')
4954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if pages_missing_archive_data:
4964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.warning('The page set archives for some pages are missing. '
4974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'Someone forgot to check them in, or they were deleted. '
4984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'Skipping those pages. To fix this, record those pages '
4994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'using record_wpr. To ignore this warning and run '
5004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    'against live sites, pass the flag --use-live-sites.')
5014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  for page in pages_missing_archive_path + pages_missing_archive_data:
5034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.StartTest(page)
5044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.AddErrorMessage(page, 'Page set archive doesn\'t exist.')
5054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.StopTest(page)
50693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
5074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return [page for page in pages if page not in
5084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          pages_missing_archive_path + pages_missing_archive_data]
5094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef _RunPage(test, page, state, expectation, results, finder_options):
5124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if expectation == 'skip':
5134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.debug('Skipping test: Skip expectation for %s', page.url)
5144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.AddSkip(page, 'Skipped by test expectations')
515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return
5164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  logging.info('Running %s' % page.url)
5184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  page_state = PageState(page, test.TabForPage(page, state.browser))
5204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  def ProcessError():
5224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.error('%s:', page.url)
5234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    exception_formatter.PrintFormattedException()
5244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if expectation == 'fail':
5254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      logging.info('Error was expected\n')
5264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      results.AddSuccess(page)
5274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    else:
5284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      results.AddError(page, sys.exc_info())
5294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  try:
5314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    page_state.PreparePage(test)
5324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if state.repeat_state.ShouldNavigate(
5334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        finder_options.skip_navigate_on_repeat):
5344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      page_state.ImplicitPageNavigation(test)
5354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    test.RunPage(page, page_state.tab, results)
5364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    util.CloseConnections(page_state.tab)
5374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except page_test.TestNotSupportedOnPlatformFailure:
5384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    raise
5394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except page_test.Failure:
5404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if expectation == 'fail':
541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      logging.info('%s:', page.url)
5424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      exception_formatter.PrintFormattedException()
5434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      logging.info('Failure was expected\n')
5444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      results.AddSuccess(page)
54593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    else:
5464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      logging.warning('%s:', page.url)
5474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      exception_formatter.PrintFormattedException()
5484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      results.AddFailure(page, sys.exc_info())
5494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except (util.TimeoutException, exceptions.LoginException,
5504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          exceptions.ProfilingException):
5514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    ProcessError()
5524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except (exceptions.TabCrashException, exceptions.BrowserGoneException):
5534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    ProcessError()
5544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    # Run() catches these exceptions to relaunch the tab/browser, so re-raise.
5554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    raise
5564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except page_action.PageActionNotSupported as e:
5574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.AddSkip(page, 'Unsupported page action: %s' % e)
5584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  except Exception:
5594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.warning('While running %s', page.url)
5604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    exception_formatter.PrintFormattedException()
5614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.AddFailure(page, sys.exc_info())
5624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  else:
5634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if expectation == 'fail':
5644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      logging.warning('%s was expected to fail, but passed.\n', page.url)
5654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    results.AddSuccess(page)
566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  finally:
5674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    page_state.CleanUpPage(test)
5684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef _GetSequentialFileName(base_name):
5714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  """Returns the next sequential file name based on |base_name| and the
5724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  existing files."""
5734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  index = 0
5744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  while True:
5754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    output_name = '%s_%03d' % (base_name, index)
5764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if not glob.glob(output_name + '.*'):
5774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      break
5784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    index = index + 1
5794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return output_name
5804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef _WaitForThermalThrottlingIfNeeded(platform):
5834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if not platform.CanMonitorThermalThrottling():
5844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return
5854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  thermal_throttling_retry = 0
5864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  while (platform.IsThermallyThrottled() and
5874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org         thermal_throttling_retry < 3):
5884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.warning('Thermally throttled, waiting (%d)...',
5894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                    thermal_throttling_retry)
5904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    thermal_throttling_retry += 1
5914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    time.sleep(thermal_throttling_retry * 2)
5924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if thermal_throttling_retry and platform.IsThermallyThrottled():
5944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.error('Device is thermally throttled before running '
5954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                  'performance tests, results will vary.')
5964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
5984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgdef _CheckThermalThrottling(platform):
5994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if not platform.CanMonitorThermalThrottling():
6004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return
601c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if platform.HasBeenThermallyThrottled():
6024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    logging.error('Device has been thermally throttled during '
6034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                  'performance tests, results will vary.')
6044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org