| Index: build/android/pylib/gtest/dispatch.py
|
| diff --git a/build/android/pylib/gtest/dispatch.py b/build/android/pylib/gtest/dispatch.py
|
| index bf88bff29d6665e64c57375e23632c7af7160b5f..eea09a93b20db03b49f2329b7f4fa3d481ea2835 100644
|
| --- a/build/android/pylib/gtest/dispatch.py
|
| +++ b/build/android/pylib/gtest/dispatch.py
|
| @@ -10,6 +10,7 @@ import glob
|
| import logging
|
| import os
|
| import shutil
|
| +import sys
|
|
|
| from pylib import android_commands
|
| from pylib import cmd_helper
|
| @@ -24,9 +25,11 @@ from pylib.utils import xvfb
|
| import gtest_config
|
| import test_runner
|
|
|
| +sys.path.insert(0,
|
| + os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib'))
|
| +from common import unittest_util
|
| +
|
|
|
| -# TODO(frankf): Add more test targets here after making sure we don't
|
| -# blow up the dependency size (and the world).
|
| _ISOLATE_FILE_PATHS = {
|
| 'base_unittests': 'base/base_unittests.isolate',
|
| 'breakpad_unittests': 'breakpad/breakpad_unittests.isolate',
|
| @@ -71,7 +74,7 @@ def _GenerateDepsDirUsingIsolate(test_suite, build_type):
|
| """Generate the dependency dir for the test suite using isolate.
|
|
|
| Args:
|
| - test_suite: The test suite basename (e.g. base_unittests).
|
| + test_suite: Name of the test suite (e.g. base_unittests).
|
| build_type: Release/Debug
|
| """
|
| product_dir = os.path.join(cmd_helper.OutDirectory.get(), build_type)
|
| @@ -191,51 +194,115 @@ def _FullyQualifiedTestSuites(exe, option_test_suite, build_type):
|
| return qualified_test_suites
|
|
|
|
|
| -def GetTestsFromDevice(runner):
|
| - """Get a list of tests from a device, excluding disabled tests.
|
| +def _GetDisabledTestsFilterFromFile(test_suite):
|
| + """Returns a gtest filter based on the *_disabled file.
|
|
|
| Args:
|
| - runner: a TestRunner.
|
| + test_suite: Name of the test suite (e.g. base_unittests).
|
| +
|
| Returns:
|
| - All non-disabled tests on the device.
|
| + A gtest filter which excludes disabled tests.
|
| + Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc'
|
| """
|
| - # The executable/apk needs to be copied before we can call GetAllTests.
|
| - runner.test_package.Install()
|
| - all_tests = runner.test_package.GetAllTests()
|
| - # Only includes tests that do not have any match in the disabled list.
|
| - disabled_list = runner.GetDisabledTests()
|
| - return filter(lambda t: not any([fnmatch.fnmatch(t, disabled_pattern)
|
| - for disabled_pattern in disabled_list]),
|
| - all_tests)
|
| + filter_file_path = os.path.join(
|
| + os.path.abspath(os.path.dirname(__file__)),
|
| + 'filter', '%s_disabled' % test_suite)
|
|
|
| + if not filter_file_path or not os.path.exists(filter_file_path):
|
| + logging.info('No filter file found at %s', filter_file_path)
|
| + return '*'
|
|
|
| -def GetAllEnabledTests(runner_factory, devices):
|
| - """Get all enabled tests.
|
| + filters = [x for x in [x.strip() for x in file(filter_file_path).readlines()]
|
| + if x and x[0] != '#']
|
| + disabled_filter = '*-%s' % ':'.join(filters)
|
| + logging.info('Applying filter "%s" obtained from %s',
|
| + disabled_filter, filter_file_path)
|
| + return disabled_filter
|
|
|
| - Obtains a list of enabled tests from the test package on the device,
|
| - then filters it again using the disabled list on the host.
|
| +
|
| +def _GetTestsFromDevice(runner_factory, devices):
|
| + """Get a list of tests from a device.
|
|
|
| Args:
|
| - runner_factory: callable that takes a devices and returns a TestRunner.
|
| - devices: list of devices.
|
| + runner_factory: callable that takes a device and index and returns a
|
| + TestRunner object.
|
| + devices: List of devices.
|
|
|
| Returns:
|
| - List of all enabled tests.
|
| -
|
| - Raises:
|
| - Exception: If no devices available.
|
| + All the tests in the test suite.
|
| """
|
| for device in devices:
|
| try:
|
| logging.info('Obtaining tests from %s', device)
|
| runner = runner_factory(device, 0)
|
| - return GetTestsFromDevice(runner)
|
| - except Exception as e:
|
| + runner.test_package.Install()
|
| + return runner.test_package.GetAllTests()
|
| + except (android_commands.errors.WaitForResponseTimedOutError,
|
| + android_commands.errors.DeviceUnresponsiveError), e:
|
| logging.warning('Failed obtaining tests from %s with exception: %s',
|
| device, e)
|
| raise Exception('No device available to get the list of tests.')
|
|
|
|
|
| +def _FilterTestsUsingPrefixes(all_tests, pre=False, manual=False):
|
| + """Removes tests with disabled prefixes.
|
| +
|
| + Args:
|
| + all_tests: List of tests to filter.
|
| + pre: If True, include tests with _PRE prefix.
|
| + manual: If True, include tests with _MANUAL prefix.
|
| +
|
| + Returns:
|
| + List of tests remaining.
|
| + """
|
| + filtered_tests = []
|
| + filter_prefixes = ['DISABLED_', 'FLAKY_', 'FAILS_']
|
| +
|
| + if not pre:
|
| + filter_prefixes.append('PRE_')
|
| +
|
| + if not manual:
|
| + filter_prefixes.append('MANUAL_')
|
| +
|
| + for t in all_tests:
|
| + test_case, test = t.split('.', 1)
|
| + if not any([test_case.startswith(prefix) or test.startswith(prefix) for
|
| + prefix in filter_prefixes]):
|
| + filtered_tests.append(t)
|
| + return filtered_tests
|
| +
|
| +
|
| +def GetTestsFiltered(test_suite, gtest_filter, runner_factory, devices):
|
| + """Get all tests in the suite and filter them.
|
| +
|
| + Obtains a list of tests from the test package on the device, and
|
| + applies the following filters in order:
|
| + 1. Remove tests with disabled prefixes.
|
| + 2. Remove tests specified in the *_disabled files in the 'filter' dir
|
| + 3. Applies |gtest_filter|.
|
| +
|
| + Args:
|
| + test_suite: Name of the test suite (e.g. base_unittests).
|
| + gtest_filter: A filter including negative and/or positive patterns.
|
| + runner_factory: callable that takes a device and index and returns a
|
| + TestRunner object.
|
| + devices: List of devices.
|
| +
|
| + Returns:
|
| + List of tests remaining.
|
| + """
|
| + tests = _GetTestsFromDevice(runner_factory, devices)
|
| + tests = _FilterTestsUsingPrefixes(
|
| + tests, bool(gtest_filter), bool(gtest_filter))
|
| + tests = unittest_util.FilterTestNames(
|
| + tests, _GetDisabledTestsFilterFromFile(test_suite))
|
| +
|
| + if gtest_filter:
|
| + tests = unittest_util.FilterTestNames(tests, gtest_filter)
|
| +
|
| + return tests
|
| +
|
| +
|
| def _RunATestSuite(options, suite_name):
|
| """Run a single test suite.
|
|
|
| @@ -294,12 +361,10 @@ def _RunATestSuite(options, suite_name):
|
| constants.GTEST_COMMAND_LINE_FILE)
|
|
|
| # Get tests and split them up based on the number of devices.
|
| - if options.test_filter:
|
| - all_tests = [t for t in options.test_filter.split(':') if t]
|
| - else:
|
| - all_tests = GetAllEnabledTests(RunnerFactory, attached_devices)
|
| + tests = GetTestsFiltered(suite_name, options.test_filter,
|
| + RunnerFactory, attached_devices)
|
| num_devices = len(attached_devices)
|
| - tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)]
|
| + tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)]
|
| tests = [t for t in tests if t]
|
|
|
| # Run tests.
|
|
|