page_runner.py revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import codecs
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import glob
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import logging
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)import sys
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import time
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import traceback
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import urlparse
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
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.page import page_filter as page_filter_module
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.page import page_test
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class _RunState(object):
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def __init__(self):
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.browser = None
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.tab = None
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._append_to_existing_wpr = False
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._last_archive_path = None
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._is_tracing = False
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._first_browser = True
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self.first_page = True
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StartBrowser(self, test, page_set, page, possible_browser,
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   credentials_path, archive_path):
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    # Create a browser.
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self.browser:
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      assert not self.tab
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser = possible_browser.Create()
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser.credentials.credentials_path = credentials_path
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      test.SetUpBrowser(self.browser)
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if self._first_browser:
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self._first_browser = False
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.credentials.WarnIfMissingCredentials(page_set)
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Set up WPR path on the new browser.
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.browser.SetReplayArchivePath(archive_path,
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        self._append_to_existing_wpr,
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        page_set.make_javascript_deterministic)
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._last_archive_path = page.archive_path
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else:
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Set up WPR path if it changed.
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if page.archive_path and self._last_archive_path != page.archive_path:
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        self.browser.SetReplayArchivePath(
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            page.archive_path,
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            self._append_to_existing_wpr,
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            page_set.make_javascript_deterministic)
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self._last_archive_path = page.archive_path
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if self.browser.supports_tab_control:
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Create a tab if there's none.
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if len(self.browser.tabs) == 0:
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.tabs.New()
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Ensure only one tab is open.
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      while len(self.browser.tabs) > 1:
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        self.browser.tabs[-1].Close()
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self.tab:
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.tab = self.browser.tabs[0]
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if self.first_page:
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self.first_page = False
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      test.WillRunPageSet(self.tab)
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopBrowser(self):
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._is_tracing = False
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.tab:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.tab.Disconnect()
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.tab = None
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.browser:
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.browser.Close()
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.browser = None
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # Restarting the state will also restart the wpr server. If we're
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # recording, we need to continue adding into the same wpr archive,
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      # not overwrite it.
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._append_to_existing_wpr = True
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StartProfiling(self, page, options):
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    output_file = os.path.join(options.profiler_dir, page.url_as_file_safe_name)
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if options.page_repeat != 1 or options.pageset_repeat != 1:
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      output_file = _GetSequentialFileName(output_file)
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self.browser.StartProfiling(options, output_file)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopProfiling(self):
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self.browser.StopProfiling()
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StartTracing(self):
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self.browser.supports_tracing:
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._is_tracing = True
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self.browser.StartTracing()
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def StopTracing(self, page, options):
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not self._is_tracing:
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    assert self.browser
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._is_tracing = False
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self.browser.StopTracing()
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    trace_result = self.browser.GetTraceResultAndReset()
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.info('Processing trace...')
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    trace_file = os.path.join(options.trace_dir, page.url_as_file_safe_name)
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if options.page_repeat != 1 or options.pageset_repeat != 1:
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      trace_file = _GetSequentialFileName(trace_file)
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    trace_file += '.json'
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    with codecs.open(trace_file, 'w',
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     encoding='utf-8') as trace_file:
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      trace_result.Serialize(trace_file)
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.info('Trace saved.')
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class PageState(object):
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def __init__(self):
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    self._did_login = False
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  def PreparePage(self, page, tab, test=None):
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parsed_url = urlparse.urlparse(page.url)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if parsed_url[0] == 'file':
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      serving_dirs, filename = page.serving_dirs_and_file
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if tab.browser.SetHTTPServerDirectories(serving_dirs) and test:
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        test.DidStartHTTPServer(tab)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      target_side_url = tab.browser.http_server.UrlOf(filename)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else:
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      target_side_url = page.url
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if page.credentials:
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if not tab.browser.credentials.LoginNeeded(tab, page.credentials):
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        raise page_test.Failure('Login as ' + page.credentials + ' failed')
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      self._did_login = True
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if test:
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if test.clear_cache_before_each_run:
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        tab.ClearCache()
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      test.WillNavigateToPage(page, tab)
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    tab.Navigate(target_side_url, page.script_to_evaluate_on_commit)
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if test:
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      test.DidNavigateToPage(page, tab)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    page.WaitToLoad(tab, 60)
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def CleanUpPage(self, page, tab):
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if page.credentials and self._did_login:
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def AddCommandLineOptions(parser):
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_filter_module.PageFilter.AddCommandLineOptions(parser)
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def Run(test, page_set, options):
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Runs a given test against a given page_set with the given options."""
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  results = test.PrepareResults(options)
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Create a possible_browser with the given options.
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  test.CustomizeBrowserOptions(options)
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  possible_browser = browser_finder.FindBrowser(options)
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not possible_browser:
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise Exception('No browser found.\n'
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        'Use --browser=list to figure out which are available.')
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Reorder page set based on options.
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages = _ShuffleAndFilterPageSet(page_set, options)
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (not options.allow_live_sites and
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      options.wpr_mode != wpr_modes.WPR_RECORD):
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pages = _CheckArchives(page_set, pages, results)
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Verify credentials path.
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  credentials_path = None
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set.credentials_path:
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    credentials_path = os.path.join(os.path.dirname(page_set.file_path),
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    page_set.credentials_path)
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not os.path.exists(credentials_path):
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      credentials_path = None
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Set up user agent.
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set.user_agent_type:
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    options.browser_user_agent_type = page_set.user_agent_type
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    test.CustomizeBrowserOptionsForPage(page, possible_browser.options)
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  _ValidateOrCreateEmptyDirectory('--trace-dir', options.trace_dir)
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  _ValidateOrCreateEmptyDirectory('--profiler-dir', options.profiler_dir)
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  state = _RunState()
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # TODO(dtu): Move results creation and results_for_current_run into RunState.
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  results_for_current_run = results
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  try:
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for page in pages:
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if options.wpr_mode != wpr_modes.WPR_RECORD:
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if page.archive_path and os.path.isfile(page.archive_path):
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          possible_browser.options.wpr_mode = wpr_modes.WPR_REPLAY
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        else:
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          possible_browser.options.wpr_mode = wpr_modes.WPR_OFF
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      results_for_current_run = results
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if state.first_page and test.discard_first_result:
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        # If discarding results, substitute a dummy object.
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        results_for_current_run = type(results)()
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      results_for_current_run.StartTest(page)
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      tries = 3
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      while tries:
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        try:
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          state.StartBrowser(test, page_set, page, possible_browser,
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             credentials_path, page.archive_path)
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          _WaitForThermalThrottlingIfNeeded(state.browser.platform)
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if options.trace_dir:
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            state.StartTracing()
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if options.profiler_dir:
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            state.StartProfiling(page, options)
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          try:
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            _RunPage(test, page, state.tab, results_for_current_run, options)
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            _CheckThermalThrottling(state.browser.platform)
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          except exceptions.TabCrashException:
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            stack_trace = state.browser.GetStackTrace()
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            stack_trace = (('\nStack Trace:\n') +
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      ('*' * 80) +
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      '\n\t' + stack_trace.replace('\n', '\n\t') + '\n' +
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      ('*' * 80))
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            logging.warning('Tab crashed: %s%s', page.url, stack_trace)
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            state.StopBrowser()
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if options.trace_dir:
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            state.StopTracing(page, options)
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if options.profiler_dir:
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            state.StopProfiling()
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if test.NeedsBrowserRestartAfterEachRun(state.tab):
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            state.StopBrowser()
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        except exceptions.BrowserGoneException:
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          logging.warning('Lost connection to browser. Retrying.')
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          state.StopBrowser()
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          tries -= 1
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if not tries:
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            logging.error('Lost connection to browser 3 times. Failing.')
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            raise
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      results_for_current_run.StopTest(page)
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    test.DidRunPageSet(state.tab, results_for_current_run)
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  finally:
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    state.StopBrowser()
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return results
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _ShuffleAndFilterPageSet(page_set, options):
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if options.pageset_shuffle_order_file and not options.pageset_shuffle:
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.')
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if options.pageset_shuffle_order_file:
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return page_set.ReorderPageSet(options.pageset_shuffle_order_file)
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_filter = page_filter_module.PageFilter(options)
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages = [page for page in page_set.pages[:]
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)           if not page.disabled and page_filter.IsSelected(page)]
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if options.pageset_shuffle:
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    random.Random().shuffle(pages)
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return [page
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      for _ in xrange(int(options.pageset_repeat))
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      for page in pages
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      for _ in xrange(int(options.page_repeat))]
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _CheckArchives(page_set, pages, results):
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Returns a subset of pages that are local or have WPR archives.
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Logs warnings if any are missing."""
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_set_has_live_sites = False
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    parsed_url = urlparse.urlparse(page.url)
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if parsed_url.scheme != 'chrome' and parsed_url.scheme != 'file':
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      page_set_has_live_sites = True
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Potential problems with the entire page set.
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if page_set_has_live_sites:
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page_set.archive_data_file:
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      logging.warning('The page set is missing an "archive_data_file" '
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'property. Skipping any live sites. To include them, '
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'pass the flag --allow-live-sites.')
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page_set.wpr_archive_info:
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      logging.warning('The archive info file is missing. '
3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'To fix this, either add svn-internal to your '
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      '.gclient using http://goto/read-src-internal, '
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      'or create a new archive using record_wpr.')
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Potential problems with individual pages.
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages_missing_archive_path = []
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pages_missing_archive_data = []
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages:
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    parsed_url = urlparse.urlparse(page.url)
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if parsed_url.scheme == 'chrome' or parsed_url.scheme == 'file':
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not page.archive_path:
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pages_missing_archive_path.append(page)
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    elif not os.path.isfile(page.archive_path):
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pages_missing_archive_data.append(page)
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if pages_missing_archive_path:
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('The page set archives for some pages do not exist. '
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Skipping those pages. To fix this, record those pages '
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'using record_wpr. To ignore this warning and run '
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'against live sites, pass the flag --allow-live-sites.')
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if pages_missing_archive_data:
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('The page set archives for some pages are missing. '
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Someone forgot to check them in, or they were deleted. '
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'Skipping those pages. To fix this, record those pages '
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'using record_wpr. To ignore this warning and run '
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    'against live sites, pass the flag --allow-live-sites.')
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for page in pages_missing_archive_path + pages_missing_archive_data:
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.StartTest(page)
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddErrorMessage(page, 'Page set archive doesn\'t exist.')
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.StopTest(page)
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return [page for page in pages if page not in
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          pages_missing_archive_path + pages_missing_archive_data]
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _RunPage(test, page, tab, results, options):
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not test.CanRunForPage(page):
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('Skipping test: it cannot run for %s', page.url)
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddSkip(page, 'Test cannot run')
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  logging.info('Running %s' % page.url)
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  page_state = PageState()
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  try:
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    page_state.PreparePage(page, tab, test)
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    test.Run(options, page, tab, results)
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    util.CloseConnections(tab)
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except page_test.Failure:
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('%s:\n%s', page.url, traceback.format_exc())
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddFailure(page, sys.exc_info())
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except (util.TimeoutException, exceptions.LoginException):
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('%s:\n%s', page.url, traceback.format_exc())
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddError(page, sys.exc_info())
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except (exceptions.TabCrashException, exceptions.BrowserGoneException):
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('%s:\n%s', page.url, traceback.format_exc())
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddError(page, sys.exc_info())
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    # Run() catches these exceptions to relaunch the tab/browser, so re-raise.
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  except Exception:
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else:
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    results.AddSuccess(page)
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  finally:
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    page_state.CleanUpPage(page, tab)
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _GetSequentialFileName(base_name):
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  """Returns the next sequential file name based on |base_name| and the
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  existing files."""
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  index = 0
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  while True:
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    output_name = '%s_%03d' % (base_name, index)
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if not glob.glob(output_name + '.*'):
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    index = index + 1
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return output_name
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _ValidateOrCreateEmptyDirectory(name, path):
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not path:
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not os.path.exists(path):
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    os.mkdir(path)
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not os.path.isdir(path):
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise Exception('%s isn\'t a directory: %s' % (name, path))
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  elif os.listdir(path):
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    raise Exception('%s isn\'t empty: %s' % (name, path))
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _WaitForThermalThrottlingIfNeeded(platform):
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not platform.CanMonitorThermalThrottling():
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  thermal_throttling_retry = 0
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  while (platform.IsThermallyThrottled() and
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         thermal_throttling_retry < 3):
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.warning('Thermally throttled, waiting (%d)...',
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    thermal_throttling_retry)
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    thermal_throttling_retry += 1
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    time.sleep(thermal_throttling_retry * 2)
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if thermal_throttling_retry and platform.IsThermallyThrottled():
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('Device is thermally throttled before running '
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  'performance tests, results will vary.')
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)def _CheckThermalThrottling(platform):
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if not platform.CanMonitorThermalThrottling():
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if platform.HasBeenThermallyThrottled():
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    logging.error('Device has been thermally throttled during '
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  'performance tests, results will vary.')
424