test_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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import logging
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport re
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from pylib import android_commands
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from pylib import constants
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfrom pylib import pexpect
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from pylib.base import base_test_result
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from pylib.base import base_test_runner
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from pylib.utils import run_tests_helper
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import test_package_apk
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport test_package_exe
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def _TestSuiteRequiresMockTestServer(test_suite_basename):
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  """Returns True if the test suite requires mock test server."""
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tests_require_net_test_server = ['unit_tests', 'net_unittests',
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   'content_unittests',
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   'content_browsertests']
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (test_suite_basename in
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          tests_require_net_test_server)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestRunner(base_test_runner.BaseTestRunner):
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def __init__(self, device, test_suite, test_arguments, timeout,
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               cleanup_test_files, tool_name, build_type,
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               in_webkit_checkout, push_deps, test_apk_package_name=None,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               test_activity_name=None, command_line_file=None):
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    """Single test suite attached to a single device.
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Args:
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      device: Device to run the tests.
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      test_suite: A specific test suite to run, empty to run all.
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      test_arguments: Additional arguments to pass to the test binary.
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      timeout: Timeout for each test.
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cleanup_test_files: Whether or not to cleanup test files on device.
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tool_name: Name of the Valgrind tool.
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      build_type: 'Release' or 'Debug'.
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      in_webkit_checkout: Whether the suite is being run from a WebKit checkout.
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      push_deps: If True, push all dependencies to the device.
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      test_apk_package_name: Apk package name for tests running in APKs.
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      test_activity_name: Test activity to invoke for APK tests.
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      command_line_file: Filename to use to pass arguments to tests.
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    """
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    super(TestRunner, self).__init__(device, tool_name, build_type, push_deps,
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     cleanup_test_files)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._running_on_emulator = self.device.startswith('emulator')
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._test_arguments = test_arguments
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.in_webkit_checkout = in_webkit_checkout
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if timeout == 0:
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      timeout = 60
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # On a VM (e.g. chromium buildbots), this timeout is way too small.
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if os.environ.get('BUILDBOT_SLAVENAME'):
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      timeout = timeout * 2
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    self.timeout = timeout * self.tool.GetTimeoutScale()
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    logging.warning('Test suite: ' + test_suite)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if os.path.splitext(test_suite)[1] == '.apk':
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.test_package = test_package_apk.TestPackageApk(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          self.adb,
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          device,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          test_suite,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          self.tool,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          test_apk_package_name,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          test_activity_name,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          command_line_file)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else:
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # Put a copy into the android out/target directory, to allow stack trace
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # generation.
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      symbols_dir = os.path.join(constants.DIR_SOURCE_ROOT, 'out', build_type,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 'lib.target')
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      self.test_package = test_package_exe.TestPackageExecutable(
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          self.adb,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          device,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          test_suite,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          self.tool,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          symbols_dir)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  #override
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def InstallTestPackage(self):
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    self.test_package.Install()
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  #override
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  def PushDataDeps(self):
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    self.adb.WaitForSdCardReady(20)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.tool.CopyFiles()
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.test_package.test_suite_basename == 'webkit_unit_tests':
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.PushWebKitUnitTestsData()
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if os.path.exists(constants.ISOLATE_DEPS_DIR):
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      device_dir = self.adb.GetExternalStorage()
987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      # TODO(frankf): linux_dumper_unittest_helper needs to be in the same dir
997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      # as breakpad_unittests exe. Find a better way to do this.
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if self.test_package.test_suite_basename == 'breakpad_unittests':
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        device_dir = constants.TEST_EXECUTABLE_DIR
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      for p in os.listdir(constants.ISOLATE_DEPS_DIR):
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        self.adb.PushIfNeeded(
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            os.path.join(constants.ISOLATE_DEPS_DIR, p),
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            os.path.join(device_dir, p))
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def PushWebKitUnitTestsData(self):
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Pushes the webkit_unit_tests data files to the device.
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    The path of this directory is different when the suite is being run as
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    part of a WebKit check-out.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    webkit_src = os.path.join(constants.DIR_SOURCE_ROOT, 'third_party',
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              'WebKit')
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.in_webkit_checkout:
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      webkit_src = os.path.join(constants.DIR_SOURCE_ROOT, '..', '..', '..')
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.adb.PushIfNeeded(
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        os.path.join(webkit_src, 'Source/WebKit/chromium/tests/data'),
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        os.path.join(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            self.adb.GetExternalStorage(),
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            'third_party/WebKit/Source/WebKit/chromium/tests/data'))
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    self.adb.PushIfNeeded(
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        os.path.join(constants.DIR_SOURCE_ROOT,
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     'third_party/hyphen/hyph_en_US.dic'),
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        os.path.join(self.adb.GetExternalStorage(),
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     'third_party/hyphen/hyph_en_US.dic'))
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # TODO(craigdh): There is no reason for this to be part of TestRunner.
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def GetDisabledTests(self):
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Returns a list of disabled tests.
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Returns:
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      A list of disabled tests obtained from 'filter' subdirectory.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gtest_filter_base_path = os.path.join(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        os.path.abspath(os.path.dirname(__file__)),
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'filter',
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        self.test_package.test_suite_basename)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    disabled_tests = run_tests_helper.GetExpectations(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gtest_filter_base_path + '_disabled')
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self._running_on_emulator:
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # Append emulator's filter file.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disabled_tests.extend(run_tests_helper.GetExpectations(
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gtest_filter_base_path + '_emulator_additional_disabled'))
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return disabled_tests
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  def _ParseTestOutput(self, p):
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    """Process the test output.
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Args:
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      p: An instance of pexpect spawn class.
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Returns:
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      A TestRunResults object.
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    """
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    results = base_test_result.TestRunResults()
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # Test case statuses.
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    re_run = re.compile('\[ RUN      \] ?(.*)\r\n')
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    re_fail = re.compile('\[  FAILED  \] ?(.*)\r\n')
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    re_ok = re.compile('\[       OK \] ?(.*?) .*\r\n')
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # Test run statuses.
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    re_passed = re.compile('\[  PASSED  \] ?(.*)\r\n')
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    re_runner_fail = re.compile('\[ RUNNER_FAILED \] ?(.*)\r\n')
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # Signal handlers are installed before starting tests
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # to output the CRASHED marker when a crash happens.
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    re_crash = re.compile('\[ CRASHED      \](.*)\r\n')
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    log = ''
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    try:
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      while True:
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        full_test_name = None
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        found = p.expect([re_run, re_passed, re_runner_fail],
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         timeout=self.timeout)
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if found == 1:  # re_passed
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          break
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        elif found == 2:  # re_runner_fail
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          break
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        else:  # re_run
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          full_test_name = p.match.group(1).replace('\r', '')
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          found = p.expect([re_ok, re_fail, re_crash], timeout=self.timeout)
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          log = p.before.replace('\r', '')
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if found == 0:  # re_ok
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            if full_test_name == p.match.group(1).replace('\r', ''):
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              results.AddResult(base_test_result.BaseTestResult(
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  full_test_name, base_test_result.ResultType.PASS,
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  log=log))
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          elif found == 2:  # re_crash
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            results.AddResult(base_test_result.BaseTestResult(
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                full_test_name, base_test_result.ResultType.CRASH,
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                log=log))
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            break
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          else:  # re_fail
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            results.AddResult(base_test_result.BaseTestResult(
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                full_test_name, base_test_result.ResultType.FAIL, log=log))
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    except pexpect.EOF:
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      logging.error('Test terminated - EOF')
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      # We're here because either the device went offline, or the test harness
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      # crashed without outputting the CRASHED marker (crbug.com/175538).
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if not self.adb.IsOnline():
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        raise android_commands.errors.DeviceUnresponsiveError(
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            'Device %s went offline.' % self.device)
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if full_test_name:
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        results.AddResult(base_test_result.BaseTestResult(
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            full_test_name, base_test_result.ResultType.CRASH,
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            log=p.before.replace('\r', '')))
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    except pexpect.TIMEOUT:
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      logging.error('Test terminated after %d second timeout.',
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    self.timeout)
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if full_test_name:
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        results.AddResult(base_test_result.BaseTestResult(
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            full_test_name, base_test_result.ResultType.TIMEOUT,
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            log=p.before.replace('\r', '')))
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    finally:
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      p.close()
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ret_code = self.test_package.GetGTestReturnCode()
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if ret_code:
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      logging.critical(
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          'gtest exit code: %d\npexpect.before: %s\npexpect.after: %s',
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          ret_code, p.before, p.after)
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return results
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #override
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def RunTest(self, test):
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_results = base_test_result.TestRunResults()
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if not test:
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return test_results, None
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    try:
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.test_package.ClearApplicationState()
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      self.test_package.CreateCommandLineFileOnDevice(
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          test, self._test_arguments)
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      test_results = self._ParseTestOutput(self.test_package.SpawnTestProcess())
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    finally:
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.CleanupSpawningServerState()
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    # Calculate unknown test results.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    all_tests = set(test.split(':'))
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    all_tests_ran = set([t.GetName() for t in test_results.GetAll()])
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unknown_tests = all_tests - all_tests_ran
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_results.AddResults(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        [base_test_result.BaseTestResult(t, base_test_result.ResultType.UNKNOWN)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         for t in unknown_tests])
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    retry = ':'.join([t.GetName() for t in test_results.GetNotPass()])
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return test_results, retry
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #override
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def SetUp(self):
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Sets up necessary test enviroment for the test suite."""
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    super(TestRunner, self).SetUp()
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if _TestSuiteRequiresMockTestServer(self.test_package.test_suite_basename):
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.LaunchChromeTestServerSpawner()
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.tool.SetupEnvironment()
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  #override
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def TearDown(self):
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Cleans up the test enviroment for the test suite."""
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.tool.CleanUpEnvironment()
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    super(TestRunner, self).TearDown()
263