class TestRunner(BaseTestRunner): """Single test suite attached to a single device. Args: device: Device to run the tests. test_suite: A specific test suite to run, empty to run all. gtest_filter: A gtest_filter flag. test_arguments: Additional arguments to pass to the test binary. timeout: Timeout for each test. cleanup_test_files: Whether or not to cleanup test files on device. tool: Name of the Valgrind tool. shard_index: index number of the shard on which the test suite will run. build_type: 'Release' or 'Debug'. in_webkit_checkout: Whether the suite is being run from a WebKit checkout. """ def __init__(self, device, test_suite, gtest_filter, test_arguments, timeout, cleanup_test_files, tool_name, shard_index, build_type, in_webkit_checkout): BaseTestRunner.__init__(self, device, tool_name, shard_index, build_type) self._running_on_emulator = self.device.startswith('emulator') self._gtest_filter = gtest_filter self._test_arguments = test_arguments self.test_results = TestResults() self.in_webkit_checkout = in_webkit_checkout logging.warning('Test suite: ' + test_suite) if os.path.splitext(test_suite)[1] == '.apk': self.test_package = TestPackageApk(self.adb, device, test_suite, timeout, cleanup_test_files, self.tool) else: # Put a copy into the android out/target directory, to allow stack trace # generation. symbols_dir = os.path.join(constants.CHROME_DIR, 'out', build_type, 'lib.target') self.test_package = TestPackageExecutable(self.adb, device, test_suite, timeout, cleanup_test_files, self.tool, symbols_dir) def _TestSuiteRequiresMockTestServer(self): """Returns True if the test suite requires mock test server.""" tests_require_net_test_server = [ 'unit_tests', 'net_unittests', 'content_unittests' ] return (self.test_package.test_suite_basename in tests_require_net_test_server) def GetDisabledTests(self): """Returns a list of disabled tests. Returns: A list of disabled tests obtained from 'filter' subdirectory. """ gtest_filter_base_path = os.path.join( CURFILE_PATH, 'filter', self.test_package.test_suite_basename) disabled_tests = run_tests_helper.GetExpectations( gtest_filter_base_path + '_disabled') if self._running_on_emulator: # Append emulator's filter file. disabled_tests.extend( run_tests_helper.GetExpectations( gtest_filter_base_path + '_emulator_additional_disabled')) return disabled_tests def LaunchHelperToolsForTestSuite(self): """Launches helper tools for the test suite. Sometimes one test may need to run some helper tools first in order to successfully complete the test. """ if self._TestSuiteRequiresMockTestServer(): self.LaunchChromeTestServerSpawner() def StripAndCopyFiles(self): """Strips and copies the required data files for the test suite.""" self.test_package.StripAndCopyExecutable() self.test_package.PushDataAndPakFiles() self.tool.CopyFiles() test_data = _GetDataFilesForTestSuite( self.test_package.test_suite_basename) if test_data: # Make sure SD card is ready. self.adb.WaitForSdCardReady(20) for data in test_data: self.CopyTestData([data], self.adb.GetExternalStorage()) if self.test_package.test_suite_basename == 'webkit_unit_tests': self.PushWebKitUnitTestsData() def PushWebKitUnitTestsData(self): """Pushes the webkit_unit_tests data files to the device. The path of this directory is different when the suite is being run as part of a WebKit check-out. """ webkit_src = os.path.join(constants.CHROME_DIR, 'third_party', 'WebKit') if self.in_webkit_checkout: webkit_src = os.path.join(constants.CHROME_DIR, '..', '..', '..') self.adb.PushIfNeeded( os.path.join(webkit_src, 'Source/WebKit/chromium/tests/data'), os.path.join( self.adb.GetExternalStorage(), 'third_party/WebKit/Source/WebKit/chromium/tests/data')) def RunTests(self): """Runs tests on a single device. Returns: A TestResults object. """ if self._gtest_filter: try: self.test_package.CreateTestRunnerScript( self._gtest_filter, self._test_arguments) self.test_results = self.test_package.RunTestsAndListResults() except errors.DeviceUnresponsiveError as e: # Make sure this device is not attached logging.warning(e) if android_commands.IsDeviceAttached(self.device): raise e self.test_results.device_exception = device_exception # Calculate unknown test results. finally: # TODO(frankf): Do not break TestResults encapsulation. all_tests = set(self._gtest_filter.split(':')) all_tests_ran = set( [t.name for t in self.test_results.GetAll()]) unknown_tests = all_tests - all_tests_ran self.test_results.unknown = [ BaseTestResult(t, '') for t in unknown_tests ] return self.test_results def SetUp(self): """Sets up necessary test enviroment for the test suite.""" super(TestRunner, self).SetUp() self.adb.ClearApplicationState(constants.CHROME_PACKAGE) self.StripAndCopyFiles() self.LaunchHelperToolsForTestSuite() self.tool.SetupEnvironment() def TearDown(self): """Cleans up the test enviroment for the test suite.""" self.tool.CleanUpEnvironment() if self.test_package.cleanup_test_files: self.adb.RemovePushedFiles() super(TestRunner, self).TearDown()