page_runner.py revision effb81e5f8246d0db0270817048dc992db66e9fb
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.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5a3f7b4e666c476898878fa745f637129375cd889Ben Murdochimport collections
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import copy
7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import glob
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import logging
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import random
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)import sys
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochimport tempfile
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import time
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import traceback
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry import decorators
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)from telemetry.core import browser_finder
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)from telemetry.core import exceptions
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import util
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_modes
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from telemetry.core.platform.profiler import profiler_finder
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from telemetry.page import page_filter
23a3f7b4e666c476898878fa745f637129375cd889Ben Murdochfrom telemetry.page import page_runner_repeat
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.page import page_test
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)from telemetry.page import results_options
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)from telemetry.page.actions import navigate
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from telemetry.page.actions import page_action
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochfrom telemetry.util import exception_formatter
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class _RunState(object):
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def __init__(self):
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.browser = None
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._append_to_existing_wpr = False
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._last_archive_path = None
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._first_browser = True
38a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    self.first_page = collections.defaultdict(lambda: True)
39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.profiler_dir = None
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    self.repeat_state = None
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def StartBrowserIfNeeded(self, test, page_set, page, possible_browser,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           credentials_path, archive_path):
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    started_browser = not self.browser
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    # Create a browser.
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self.browser:
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test.CustomizeBrowserOptionsForSinglePage(page,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                possible_browser.finder_options)
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser = possible_browser.Create()
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser.credentials.credentials_path = credentials_path
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      # Set up WPR path on the new browser.
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      self.browser.SetReplayArchivePath(archive_path,
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        self._append_to_existing_wpr,
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        page_set.make_javascript_deterministic)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      self._last_archive_path = page.archive_path
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      test.WillStartBrowser(self.browser)
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      self.browser.Start()
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      test.DidStartBrowser(self.browser)
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if self._first_browser:
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self._first_browser = False
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.credentials.WarnIfMissingCredentials(page_set)
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        logging.info('OS: %s %s',
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     self.browser.platform.GetOSName(),
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     self.browser.platform.GetOSVersionName())
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        if self.browser.supports_system_info:
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          system_info = self.browser.GetSystemInfo()
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if system_info.model_name:
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            logging.info('Model: %s' % system_info.model_name)
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if system_info.gpu:
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            for i, device in enumerate(system_info.gpu.devices):
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              logging.info('GPU device %d: %s', i, device)
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            if system_info.gpu.aux_attributes:
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              logging.info('GPU Attributes:')
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              for k, v in sorted(system_info.gpu.aux_attributes.iteritems()):
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                logging.info('  %-20s: %s', k, v)
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            if system_info.gpu.feature_status:
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              logging.info('Feature Status:')
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              for k, v in sorted(system_info.gpu.feature_status.iteritems()):
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                logging.info('  %-20s: %s', k, v)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if system_info.gpu.driver_bug_workarounds:
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              logging.info('Driver Bug Workarounds:')
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              for workaround in system_info.gpu.driver_bug_workarounds:
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                logging.info('  %s', workaround)
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          else:
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            logging.info('No GPU devices')
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else:
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Set up WPR path if it changed.
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if page.archive_path and self._last_archive_path != page.archive_path:
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        self.browser.SetReplayArchivePath(
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            page.archive_path,
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            self._append_to_existing_wpr,
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            page_set.make_javascript_deterministic)
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self._last_archive_path = page.archive_path
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if self.browser.supports_tab_control and test.close_tabs_before_run:
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Create a tab if there's none.
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if len(self.browser.tabs) == 0:
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        # TODO(nduca/tonyg): Remove this line. Added as part of crbug.com/348337
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        # chasing.
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        logging.warning('Making a new tab\n')
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.tabs.New()
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      # Ensure only one tab is open, unless the test is a multi-tab test.
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if not test.is_multi_tab_test:
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        while len(self.browser.tabs) > 1:
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          self.browser.tabs[-1].Close()
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      # Must wait for tab to commit otherwise it can commit after the next
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      # navigation has begun and RenderFrameHostManager::DidNavigateMainFrame()
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      # will cancel the next navigation because it's pending. This manifests as
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      # the first navigation in a PageSet freezing indefinitly because the
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      # navigation was silently cancelled when |self.browser.tabs[0]| was
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      # committed. Only do this when we just started the browser, otherwise
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      # there are cases where previous pages in a PageSet never complete
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      # loading so we'll wait forever.
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if started_browser:
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        self.browser.tabs[0].WaitForDocumentReadyStateToBeComplete()
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopBrowser(self):
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.browser:
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.browser.Close()
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.browser = None
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Restarting the state will also restart the wpr server. If we're
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # recording, we need to continue adding into the same wpr archive,
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # not overwrite it.
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._append_to_existing_wpr = True
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  def StartProfiling(self, page, finder_options):
133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if not self.profiler_dir:
134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      self.profiler_dir = tempfile.mkdtemp()
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    output_file = os.path.join(self.profiler_dir, page.file_safe_name)
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if finder_options.repeat_options.IsRepeating():
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      output_file = _GetSequentialFileName(output_file)
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    self.browser.StartProfiling(finder_options.profiler, output_file)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopProfiling(self):
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if self.browser:
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      self.browser.StopProfiling()
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class PageState(object):
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def __init__(self, page, tab):
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self.page = page
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    self.tab = tab
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._did_login = False
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def PreparePage(self, test=None):
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if self.page.is_file:
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      server_started = self.tab.browser.SetHTTPServerDirectories(
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        self.page.page_set.serving_dirs | set([self.page.serving_dir]))
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if server_started and test:
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test.DidStartHTTPServer(self.tab)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if self.page.credentials:
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if not self.tab.browser.credentials.LoginNeeded(
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          self.tab, self.page.credentials):
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        raise page_test.Failure('Login as ' + self.page.credentials + ' failed')
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._did_login = True
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if test:
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if test.clear_cache_before_each_run:
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        self.tab.ClearCache(force=True)
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  def ImplicitPageNavigation(self, test=None):
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    """Executes the implicit navigation that occurs for every page iteration.
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    This function will be called once per page before any actions are executed.
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    """
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if test:
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      test.WillNavigateToPage(self.page, self.tab)
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      test.RunNavigateSteps(self.page, self.tab)
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      test.DidNavigateToPage(self.page, self.tab)
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else:
1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      i = navigate.NavigateAction()
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      i.RunAction(self.page, self.tab, None)
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def CleanUpPage(self, test):
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    try:
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      test.CleanUpAfterPage(self.page, self.tab)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    except Exception:
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      logging.error('While cleaning up %s:\n%s', self.page.url,
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    traceback.format_exc())
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if self.page.credentials and self._did_login:
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      self.tab.browser.credentials.LoginNoLongerNeeded(
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          self.tab, self.page.credentials)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)def AddCommandLineArgs(parser):
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  page_filter.PageFilter.AddCommandLineArgs(parser)
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  results_options.AddResultsOptions(parser)
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)def ProcessCommandLineArgs(parser, args):
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  page_filter.PageFilter.ProcessCommandLineArgs(parser, args)
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochdef _LogStackTrace(title, browser):
204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if browser:
205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stack_trace = browser.GetStackTrace()
206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  else:
207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    stack_trace = 'Browser object is empty, no stack trace.'
208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  stack_trace = (('\nStack Trace:\n') +
209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            ('*' * 80) +
210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            '\n\t' + stack_trace.replace('\n', '\n\t') + '\n' +
211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            ('*' * 80))
212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  logging.warning('%s%s', title, stack_trace)
213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)def _PrepareAndRunPage(test, page_set, expectations, finder_options,
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       browser_options, page, credentials_path,
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       possible_browser, results, state):
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if browser_options.wpr_mode != wpr_modes.WPR_RECORD:
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    possible_browser.finder_options.browser_options.wpr_mode = (
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        wpr_modes.WPR_REPLAY
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if page.archive_path and os.path.isfile(page.archive_path)
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        else wpr_modes.WPR_OFF)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  tries = test.attempts
225a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  while tries:
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tries -= 1
227a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    try:
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      results_for_current_run = copy.copy(results)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      results_for_current_run.StartTest(page)
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if test.RestartBrowserBeforeEachPage() or page.startup_url:
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        state.StopBrowser()
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        # If we are restarting the browser for each page customize the per page
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        # options for just the current page before starting the browser.
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      state.StartBrowserIfNeeded(test, page_set, page, possible_browser,
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 credentials_path, page.archive_path)
236a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      expectation = expectations.GetExpectationForPage(state.browser, page)
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
239a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      _WaitForThermalThrottlingIfNeeded(state.browser.platform)
240a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if finder_options.profiler:
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        state.StartProfiling(page, finder_options)
243a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
244a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      try:
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        _RunPage(test, page, state, expectation,
246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 results_for_current_run, finder_options)
247a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        _CheckThermalThrottling(state.browser.platform)
248a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      except exceptions.TabCrashException:
249a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        _LogStackTrace('Tab crashed: %s' % page.url, state.browser)
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        if test.is_multi_tab_test:
2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          logging.error('Stopping multi-tab test after tab %s crashed'
2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                        % page.url)
2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          raise
2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        else:
2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          state.StopBrowser()
256a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if finder_options.profiler:
258a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        state.StopProfiling()
259a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (test.StopBrowserAfterPage(state.browser, page)):
261a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        state.StopBrowser()
262a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      results_for_current_run.StopTest(page)
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if state.first_page[page]:
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        state.first_page[page] = False
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if test.discard_first_result:
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return results
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return results_for_current_run
270a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    except exceptions.BrowserGoneException:
271a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      _LogStackTrace('Browser crashed', state.browser)
272a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      logging.warning('Lost connection to browser. Retrying.')
273a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      state.StopBrowser()
274a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      if not tries:
275a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        logging.error('Lost connection to browser 3 times. Failing.')
276a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        raise
2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if test.is_multi_tab_test:
2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        logging.error(
2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          'Lost connection to browser during multi-tab test. Failing.')
2808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        raise
281a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
282a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)def Run(test, page_set, expectations, finder_options):
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Runs a given test against a given page_set with the given options."""
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  results = results_options.PrepareResults(test, finder_options)
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  browser_options = finder_options.browser_options
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test.ValidatePageSet(page_set)
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Create a possible_browser with the given options.
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  test.CustomizeBrowserOptions(finder_options)
292bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  try:
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    possible_browser = browser_finder.FindBrowser(finder_options)
294bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  except browser_finder.BrowserTypeRequiredException, e:
295bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.stderr.write(str(e) + '\n')
296bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.exit(1)
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not possible_browser:
298bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.stderr.write(
299bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        'No browser found. Available browsers:\n' +
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)) +
301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        '\n')
302bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    sys.exit(1)
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  browser_options.browser_type = possible_browser.browser_type
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if not decorators.IsEnabled(
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test, browser_options.browser_type, possible_browser.platform):
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return results
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Reorder page set based on options.
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  pages = _ShuffleAndFilterPageSet(page_set, finder_options)
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (not finder_options.allow_live_sites and
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      browser_options.wpr_mode != wpr_modes.WPR_RECORD):
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pages = _CheckArchives(page_set, pages, results)
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Verify credentials path.
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  credentials_path = None
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set.credentials_path:
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    credentials_path = os.path.join(os.path.dirname(page_set.file_path),
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    page_set.credentials_path)
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not os.path.exists(credentials_path):
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      credentials_path = None
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Set up user agent.
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set.user_agent_type:
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    browser_options.browser_user_agent_type = page_set.user_agent_type
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if finder_options.profiler:
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    profiler_class = profiler_finder.FindProfiler(finder_options.profiler)
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    profiler_class.CustomizeBrowserOptions(possible_browser.browser_type,
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                           possible_browser.finder_options)
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
334a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  for page in list(pages):
335a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if not test.CanRunForPage(page):
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      logging.debug('Skipping test: it cannot run for %s', page.url)
337a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      results.AddSkip(page, 'Test cannot run')
338a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      pages.remove(page)
339a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
340a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if not pages:
341a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return results
342a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  state = _RunState()
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # TODO(dtu): Move results creation and results_for_current_run into RunState.
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  try:
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test.WillRunTest(finder_options)
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    state.repeat_state = page_runner_repeat.PageRunnerRepeatState(
349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                             finder_options.repeat_options)
350a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    state.repeat_state.WillRunPageSet()
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    while state.repeat_state.ShouldRepeatPageSet() and not test.IsExiting():
353a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      for page in pages:
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        state.repeat_state.WillRunPage()
3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test.WillRunPageRepeats(page)
3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        while state.repeat_state.ShouldRepeatPage():
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          results = _PrepareAndRunPage(
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              test, page_set, expectations, finder_options, browser_options,
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              page, credentials_path, possible_browser, results, state)
3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          state.repeat_state.DidRunPage()
3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test.DidRunPageRepeats(page)
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if (not test.max_failures is None and
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            len(results.failures) > test.max_failures):
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          logging.error('Too many failures. Aborting.')
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          test.RequestExit()
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if (not test.max_errors is None and
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            len(results.errors) > test.max_errors):
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          logging.error('Too many errors. Aborting.')
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          test.RequestExit()
3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        if test.IsExiting():
3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          break
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      state.repeat_state.DidRunPageSet()
373a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    test.DidRunTest(state.browser, results)
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  finally:
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    state.StopBrowser()
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return results
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)def _ShuffleAndFilterPageSet(page_set, finder_options):
382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (finder_options.pageset_shuffle_order_file and
383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      not finder_options.pageset_shuffle):
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.')
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if finder_options.pageset_shuffle_order_file:
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return page_set.ReorderPageSet(finder_options.pageset_shuffle_order_file)
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages = [page for page in page_set.pages[:]
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           if not page.disabled and page_filter.PageFilter.IsSelected(page)]
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if finder_options.pageset_shuffle:
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    random.Random().shuffle(pages)
394a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
395a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return pages
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _CheckArchives(page_set, pages, results):
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Returns a subset of pages that are local or have WPR archives.
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Logs warnings if any are missing."""
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_set_has_live_sites = False
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
404ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if not page.is_local:
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      page_set_has_live_sites = True
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Potential problems with the entire page set.
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set_has_live_sites:
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page_set.archive_data_file:
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      logging.warning('The page set is missing an "archive_data_file" '
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'property. Skipping any live sites. To include them, '
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'pass the flag --allow-live-sites.')
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page_set.wpr_archive_info:
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      logging.warning('The archive info file is missing. '
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'To fix this, either add svn-internal to your '
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      '.gclient using http://goto/read-src-internal, '
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'or create a new archive using record_wpr.')
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Potential problems with individual pages.
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages_missing_archive_path = []
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages_missing_archive_data = []
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
425ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if page.is_local:
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page.archive_path:
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pages_missing_archive_path.append(page)
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    elif not os.path.isfile(page.archive_path):
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pages_missing_archive_data.append(page)
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if pages_missing_archive_path:
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('The page set archives for some pages do not exist. '
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Skipping those pages. To fix this, record those pages '
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'using record_wpr. To ignore this warning and run '
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'against live sites, pass the flag --allow-live-sites.')
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if pages_missing_archive_data:
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('The page set archives for some pages are missing. '
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Someone forgot to check them in, or they were deleted. '
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Skipping those pages. To fix this, record those pages '
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'using record_wpr. To ignore this warning and run '
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'against live sites, pass the flag --allow-live-sites.')
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages_missing_archive_path + pages_missing_archive_data:
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.StartTest(page)
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddErrorMessage(page, 'Page set archive doesn\'t exist.')
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.StopTest(page)
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return [page for page in pages if page not in
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          pages_missing_archive_path + pages_missing_archive_data]
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)def _RunPage(test, page, state, expectation, results, finder_options):
455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if expectation == 'skip':
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logging.debug('Skipping test: Skip expectation for %s', page.url)
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    results.AddSkip(page, 'Skipped by test expectations')
458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return
459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  logging.info('Running %s' % page.url)
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  page_state = PageState(page, test.TabForPage(page, state.browser))
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  page_action.PageAction.ResetNextTimelineMarkerId()
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  def ProcessError():
4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    logging.error('%s:\n%s', page.url, traceback.format_exc())
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if expectation == 'fail':
4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      logging.info('Error was expected\n')
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      results.AddSuccess(page)
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else:
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      results.AddError(page, sys.exc_info())
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  try:
4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    page_state.PreparePage(test)
476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if state.repeat_state.ShouldNavigate(
477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        finder_options.skip_navigate_on_repeat):
4781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      page_state.ImplicitPageNavigation(test)
47923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    test.RunPage(page, page_state.tab, results)
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    util.CloseConnections(page_state.tab)
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except page_test.Failure:
482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if expectation == 'fail':
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      logging.info('%s:\n%s', page.url, traceback.format_exc())
484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      logging.info('Failure was expected\n')
485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      results.AddSuccess(page)
486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    else:
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      logging.warning('%s:\n%s', page.url, traceback.format_exc())
488ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      results.AddFailure(page, sys.exc_info())
489558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  except (util.TimeoutException, exceptions.LoginException,
490558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          exceptions.ProfilingException):
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ProcessError()
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except (exceptions.TabCrashException, exceptions.BrowserGoneException):
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ProcessError()
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    # Run() catches these exceptions to relaunch the tab/browser, so re-raise.
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except Exception:
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    logging.warning('While running %s', page.url)
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    exception_formatter.PrintFormattedException(*sys.exc_info())
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    results.AddFailure(page, sys.exc_info())
5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else:
501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if expectation == 'fail':
502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      logging.warning('%s was expected to fail, but passed.\n', page.url)
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddSuccess(page)
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  finally:
505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    page_state.CleanUpPage(test)
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _GetSequentialFileName(base_name):
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Returns the next sequential file name based on |base_name| and the
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  existing files."""
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  index = 0
5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  while True:
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    output_name = '%s_%03d' % (base_name, index)
5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not glob.glob(output_name + '.*'):
5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break
5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    index = index + 1
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return output_name
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _WaitForThermalThrottlingIfNeeded(platform):
5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not platform.CanMonitorThermalThrottling():
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  thermal_throttling_retry = 0
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  while (platform.IsThermallyThrottled() and
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         thermal_throttling_retry < 3):
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('Thermally throttled, waiting (%d)...',
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    thermal_throttling_retry)
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    thermal_throttling_retry += 1
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    time.sleep(thermal_throttling_retry * 2)
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if thermal_throttling_retry and platform.IsThermallyThrottled():
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('Device is thermally throttled before running '
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  'performance tests, results will vary.')
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _CheckThermalThrottling(platform):
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not platform.CanMonitorThermalThrottling():
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if platform.HasBeenThermallyThrottled():
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('Device has been thermally throttled during '
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  'performance tests, results will vary.')
542