Chromium Code Reviews| 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..4d2004559bcdf4da983e9b830aed500c7cafb2f9 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,6 +25,10 @@ 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). |
| @@ -71,7 +76,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 +196,112 @@ 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): |
|
craigdh
2013/07/17 21:27:03
logging.info that no filter file was found?
frankf
2013/07/17 22:18:54
Done.
|
| + 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 devices and returns a TestRunner. |
|
craigdh
2013/07/17 21:27:03
devices -> device and shard index
frankf
2013/07/17 22:18:54
Done.
|
| + 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) |
| + runner.test_package.Install() |
| + return runner.test_package.GetAllTests() |
| except Exception as e: |
| logging.warning('Failed obtaining tests from %s with exception: %s', |
| device, e) |
| raise Exception('No device available to get the list of tests.') |
|
craigdh
2013/07/17 21:27:03
This is a pain right now, because if there is an i
frankf
2013/07/17 22:18:54
The issue is that we're catching too general excep
|
| +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 any([test_case.startswith(prefix) or test.startswith(prefix) for prefix |
|
craigdh
2013/07/17 21:27:03
lose the continue, just do:
if not any(...):
fi
frankf
2013/07/17 22:18:54
Done.
|
| + in filter_prefixes]): |
| + continue |
| + 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 or positive patterns. |
| + runner_factory: Callable that takes a devices and returns a TestRunner. |
| + 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 +360,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. |