page_runner.py revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
4a3f7b4e666c476898878fa745f637129375cd889Ben Murdochimport collections
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import glob
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import logging
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)import sys
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochimport tempfile
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import time
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import traceback
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import random
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)from telemetry.core import browser_finder
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)from telemetry.core import exceptions
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import util
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_modes
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core.platform.profiler import profiler_finder
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.page import page_filter as page_filter_module
20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochfrom telemetry.page import page_measurement_results
21a3f7b4e666c476898878fa745f637129375cd889Ben Murdochfrom telemetry.page import page_runner_repeat
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.page import page_test
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)from telemetry.page import results_options
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)from telemetry.page.actions import navigate
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class _RunState(object):
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def __init__(self):
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.browser = None
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.tab = None
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._append_to_existing_wpr = False
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._last_archive_path = None
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._first_browser = True
35a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    self.first_page = collections.defaultdict(lambda: True)
36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.profiler_dir = None
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    self.repeat_state = None
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StartBrowser(self, test, page_set, page, possible_browser,
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   credentials_path, archive_path):
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    # Create a browser.
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self.browser:
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      assert not self.tab
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser = possible_browser.Create()
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser.credentials.credentials_path = credentials_path
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      test.WillStartBrowser(self.browser)
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      self.browser.Start()
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      test.DidStartBrowser(self.browser)
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if self._first_browser:
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self._first_browser = False
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.credentials.WarnIfMissingCredentials(page_set)
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        if self.browser.supports_system_info:
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          system_info = self.browser.GetSystemInfo()
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if system_info.model_name:
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            logging.info('Model: %s' % system_info.model_name)
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if system_info.gpu:
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            for i, device in enumerate(system_info.gpu.devices):
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              logging.info('GPU device %d: %s' % (i, device))
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            logging.info('GPU Attributes:')
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            for k, v in system_info.gpu.aux_attributes.iteritems():
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              logging.info('\t%s: %s' % (k, v))
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          else:
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            logging.info('No GPU devices')
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Set up WPR path on the new browser.
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser.SetReplayArchivePath(archive_path,
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        self._append_to_existing_wpr,
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        page_set.make_javascript_deterministic)
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._last_archive_path = page.archive_path
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else:
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Set up WPR path if it changed.
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if page.archive_path and self._last_archive_path != page.archive_path:
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        self.browser.SetReplayArchivePath(
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            page.archive_path,
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            self._append_to_existing_wpr,
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            page_set.make_javascript_deterministic)
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self._last_archive_path = page.archive_path
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if self.browser.supports_tab_control:
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Create a tab if there's none.
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if len(self.browser.tabs) == 0:
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.tabs.New()
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Ensure only one tab is open.
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      while len(self.browser.tabs) > 1:
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.tabs[-1].Close()
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self.tab:
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.tab = self.browser.tabs[0]
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
93a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if self.first_page[page]:
94a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      self.first_page[page] = False
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopBrowser(self):
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.tab:
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.tab.Disconnect()
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.tab = None
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.browser:
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.browser.Close()
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.browser = None
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Restarting the state will also restart the wpr server. If we're
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # recording, we need to continue adding into the same wpr archive,
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # not overwrite it.
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._append_to_existing_wpr = True
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  def StartProfiling(self, page, finder_options):
111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if not self.profiler_dir:
112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      self.profiler_dir = tempfile.mkdtemp()
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    output_file = os.path.join(self.profiler_dir, page.file_safe_name)
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if finder_options.repeat_options.IsRepeating():
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      output_file = _GetSequentialFileName(output_file)
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    self.browser.StartProfiling(finder_options.profiler, output_file)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopProfiling(self):
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self.browser.StopProfiling()
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class PageState(object):
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def __init__(self):
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._did_login = False
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  def PreparePage(self, page, tab, test=None):
127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if page.is_file:
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      serving_dirs = page.serving_dirs_and_file[0]
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if tab.browser.SetHTTPServerDirectories(serving_dirs) and test:
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        test.DidStartHTTPServer(tab)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if page.credentials:
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if not tab.browser.credentials.LoginNeeded(tab, page.credentials):
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        raise page_test.Failure('Login as ' + page.credentials + ' failed')
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._did_login = True
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if test:
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if test.clear_cache_before_each_run:
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        tab.ClearCache()
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def ImplicitPageNavigation(self, page, tab, test=None):
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    """Executes the implicit navigation that occurs for every page iteration.
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    This function will be called once per page before any actions are executed.
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    """
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if test:
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      test.WillNavigateToPage(page, tab)
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      test.RunNavigateSteps(page, tab)
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      test.DidNavigateToPage(page, tab)
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else:
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      i = navigate.NavigateAction()
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      i.RunAction(page, tab, None)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def CleanUpPage(self, page, tab):
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if page.credentials and self._did_login:
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def AddCommandLineOptions(parser):
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_filter_module.PageFilter.AddCommandLineOptions(parser)
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  results_options.AddResultsOptions(parser)
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochdef _LogStackTrace(title, browser):
165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if browser:
166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stack_trace = browser.GetStackTrace()
167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  else:
168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stack_trace = 'Browser object is empty, no stack trace.'
169ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  stack_trace = (('\nStack Trace:\n') +
170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            ('*' * 80) +
171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            '\n\t' + stack_trace.replace('\n', '\n\t') + '\n' +
172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            ('*' * 80))
173ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  logging.warning('%s%s', title, stack_trace)
174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)def _PrepareAndRunPage(test, page_set, expectations, finder_options,
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       browser_options, page, credentials_path,
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       possible_browser, results, state):
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if browser_options.wpr_mode != wpr_modes.WPR_RECORD:
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    possible_browser.finder_options.browser_options.wpr_mode = (
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        wpr_modes.WPR_REPLAY
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if page.archive_path and os.path.isfile(page.archive_path)
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        else wpr_modes.WPR_OFF)
184a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  results_for_current_run = results
185a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if state.first_page[page] and test.discard_first_result:
186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    # If discarding results, substitute a dummy object.
187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    results_for_current_run = page_measurement_results.PageMeasurementResults()
188a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  results_for_current_run.StartTest(page)
189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  tries = 3
190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  while tries:
191a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    try:
192a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      state.StartBrowser(test, page_set, page, possible_browser,
193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                         credentials_path, page.archive_path)
194a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      expectation = expectations.GetExpectationForPage(state.browser, page)
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
197a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      _WaitForThermalThrottlingIfNeeded(state.browser.platform)
198a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if finder_options.profiler:
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        state.StartProfiling(page, finder_options)
201a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
202a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      try:
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        _RunPage(test, page, state, expectation,
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 results_for_current_run, finder_options)
205a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        _CheckThermalThrottling(state.browser.platform)
206a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      except exceptions.TabCrashException:
207a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        _LogStackTrace('Tab crashed: %s' % page.url, state.browser)
208a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        state.StopBrowser()
209a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if finder_options.profiler:
211a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        state.StopProfiling()
212a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
213a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      if test.NeedsBrowserRestartAfterEachRun(state.tab):
214a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        state.StopBrowser()
215a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
216a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      break
217a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    except exceptions.BrowserGoneException:
218a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      _LogStackTrace('Browser crashed', state.browser)
219a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      logging.warning('Lost connection to browser. Retrying.')
220a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      state.StopBrowser()
221a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      tries -= 1
222a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      if not tries:
223a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        logging.error('Lost connection to browser 3 times. Failing.')
224a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        raise
225a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  results_for_current_run.StopTest(page)
226a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
227a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)def Run(test, page_set, expectations, finder_options):
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Runs a given test against a given page_set with the given options."""
230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  results = results_options.PrepareResults(test, finder_options)
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  browser_options = finder_options.browser_options
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Create a possible_browser with the given options.
234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  test.CustomizeBrowserOptions(finder_options)
235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if finder_options.profiler:
236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    profiler_class = profiler_finder.FindProfiler(finder_options.profiler)
237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    profiler_class.CustomizeBrowserOptions(finder_options)
238bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  try:
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    possible_browser = browser_finder.FindBrowser(finder_options)
240bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  except browser_finder.BrowserTypeRequiredException, e:
241bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.stderr.write(str(e) + '\n')
242bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.exit(1)
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not possible_browser:
244bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.stderr.write(
245bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        'No browser found. Available browsers:\n' +
246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)) +
247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        '\n')
248bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.exit(1)
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Reorder page set based on options.
251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pages = _ShuffleAndFilterPageSet(page_set, finder_options)
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (not finder_options.allow_live_sites and
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      browser_options.wpr_mode != wpr_modes.WPR_RECORD):
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pages = _CheckArchives(page_set, pages, results)
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Verify credentials path.
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  credentials_path = None
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set.credentials_path:
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    credentials_path = os.path.join(os.path.dirname(page_set.file_path),
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    page_set.credentials_path)
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not os.path.exists(credentials_path):
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      credentials_path = None
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Set up user agent.
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set.user_agent_type:
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    browser_options.browser_user_agent_type = page_set.user_agent_type
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    test.CustomizeBrowserOptionsForPage(page, possible_browser.finder_options)
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
272a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  for page in list(pages):
273a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if not test.CanRunForPage(page):
274a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      logging.warning('Skipping test: it cannot run for %s', page.url)
275a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      results.AddSkip(page, 'Test cannot run')
276a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      pages.remove(page)
277a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
278a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if not pages:
279a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return results
280a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  state = _RunState()
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # TODO(dtu): Move results creation and results_for_current_run into RunState.
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  try:
285a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    test.WillRunTest(state.tab)
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    state.repeat_state = page_runner_repeat.PageRunnerRepeatState(
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                             finder_options.repeat_options)
288a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    state.repeat_state.WillRunPageSet()
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    while state.repeat_state.ShouldRepeatPageSet():
291a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      for page in pages:
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        state.repeat_state.WillRunPage()
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        test.WillRunPageRepeats(page, state.tab)
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        while state.repeat_state.ShouldRepeatPage():
295a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          # execute test on page
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          _PrepareAndRunPage(test, page_set, expectations, finder_options,
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                             browser_options, page, credentials_path,
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                             possible_browser, results, state)
2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          state.repeat_state.DidRunPage()
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        test.DidRunPageRepeats(page, state.tab)
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      state.repeat_state.DidRunPageSet()
302a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
303a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    test.DidRunTest(state.tab, results)
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  finally:
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    state.StopBrowser()
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return results
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)def _ShuffleAndFilterPageSet(page_set, finder_options):
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (finder_options.pageset_shuffle_order_file and
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      not finder_options.pageset_shuffle):
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.')
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if finder_options.pageset_shuffle_order_file:
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return page_set.ReorderPageSet(finder_options.pageset_shuffle_order_file)
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  page_filter = page_filter_module.PageFilter(finder_options)
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages = [page for page in page_set.pages[:]
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)           if not page.disabled and page_filter.IsSelected(page)]
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if finder_options.pageset_shuffle:
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    random.Random().shuffle(pages)
324a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
325a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return pages
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _CheckArchives(page_set, pages, results):
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Returns a subset of pages that are local or have WPR archives.
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Logs warnings if any are missing."""
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_set_has_live_sites = False
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if not page.is_local:
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      page_set_has_live_sites = True
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Potential problems with the entire page set.
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set_has_live_sites:
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page_set.archive_data_file:
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      logging.warning('The page set is missing an "archive_data_file" '
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'property. Skipping any live sites. To include them, '
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'pass the flag --allow-live-sites.')
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page_set.wpr_archive_info:
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      logging.warning('The archive info file is missing. '
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'To fix this, either add svn-internal to your '
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      '.gclient using http://goto/read-src-internal, '
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'or create a new archive using record_wpr.')
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Potential problems with individual pages.
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages_missing_archive_path = []
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages_missing_archive_data = []
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
355ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if page.is_local:
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page.archive_path:
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pages_missing_archive_path.append(page)
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    elif not os.path.isfile(page.archive_path):
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pages_missing_archive_data.append(page)
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if pages_missing_archive_path:
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('The page set archives for some pages do not exist. '
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Skipping those pages. To fix this, record those pages '
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'using record_wpr. To ignore this warning and run '
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'against live sites, pass the flag --allow-live-sites.')
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if pages_missing_archive_data:
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('The page set archives for some pages are missing. '
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Someone forgot to check them in, or they were deleted. '
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Skipping those pages. To fix this, record those pages '
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'using record_wpr. To ignore this warning and run '
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'against live sites, pass the flag --allow-live-sites.')
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages_missing_archive_path + pages_missing_archive_data:
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.StartTest(page)
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddErrorMessage(page, 'Page set archive doesn\'t exist.')
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.StopTest(page)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return [page for page in pages if page not in
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          pages_missing_archive_path + pages_missing_archive_data]
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)def _RunPage(test, page, state, expectation, results, finder_options):
385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if expectation == 'skip':
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    logging.warning('Skipped %s' % page.url)
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return
388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  logging.info('Running %s' % page.url)
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_state = PageState()
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  tab = state.tab
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def ProcessError():
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    logging.error('%s:\n%s', page.url, traceback.format_exc())
3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if expectation == 'fail':
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      logging.info('Error was expected\n')
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      results.AddSuccess(page)
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else:
4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      results.AddError(page, sys.exc_info())
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  try:
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    page_state.PreparePage(page, tab, test)
404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if state.repeat_state.ShouldNavigate(
405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        finder_options.skip_navigate_on_repeat):
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      page_state.ImplicitPageNavigation(page, tab, test)
407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    test.Run(finder_options, page, tab, results)
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    util.CloseConnections(tab)
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except page_test.Failure:
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('%s:\n%s', page.url, traceback.format_exc())
411ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if expectation == 'fail':
412ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      logging.info('Failure was expected\n')
413ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      results.AddSuccess(page)
414ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    else:
415ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      results.AddFailure(page, sys.exc_info())
416558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  except (util.TimeoutException, exceptions.LoginException,
417558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          exceptions.ProfilingException):
4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ProcessError()
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except (exceptions.TabCrashException, exceptions.BrowserGoneException):
4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ProcessError()
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    # Run() catches these exceptions to relaunch the tab/browser, so re-raise.
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except Exception:
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else:
426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if expectation == 'fail':
427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      logging.warning('%s was expected to fail, but passed.\n', page.url)
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddSuccess(page)
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  finally:
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    page_state.CleanUpPage(page, tab)
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _GetSequentialFileName(base_name):
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Returns the next sequential file name based on |base_name| and the
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  existing files."""
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  index = 0
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  while True:
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    output_name = '%s_%03d' % (base_name, index)
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not glob.glob(output_name + '.*'):
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    index = index + 1
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return output_name
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _WaitForThermalThrottlingIfNeeded(platform):
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not platform.CanMonitorThermalThrottling():
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  thermal_throttling_retry = 0
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  while (platform.IsThermallyThrottled() and
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         thermal_throttling_retry < 3):
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('Thermally throttled, waiting (%d)...',
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    thermal_throttling_retry)
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    thermal_throttling_retry += 1
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    time.sleep(thermal_throttling_retry * 2)
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if thermal_throttling_retry and platform.IsThermallyThrottled():
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('Device is thermally throttled before running '
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  'performance tests, results will vary.')
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _CheckThermalThrottling(platform):
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not platform.CanMonitorThermalThrottling():
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if platform.HasBeenThermallyThrottled():
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('Device has been thermally throttled during '
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  'performance tests, results will vary.')
467