| Index: build/android/pylib/base/shard.py
|
| diff --git a/build/android/pylib/base/shard.py b/build/android/pylib/base/shard.py
|
| index 8c429f7d3d01a9df148d25089260e9f085f50724..d963be2edd933e06b3caa350b90ef267363ed290 100644
|
| --- a/build/android/pylib/base/shard.py
|
| +++ b/build/android/pylib/base/shard.py
|
| @@ -184,28 +184,28 @@ def _SetUp(runner_factory, device, out_runners, threadsafe_counter):
|
| logging.warning('Failed to create shard for %s: [%s]', device, e)
|
|
|
|
|
| -def _RunAllTests(runners, tests, num_retries, timeout=None):
|
| +def _RunAllTests(runners, test_collection_factory, num_retries, timeout=None):
|
| """Run all tests using the given TestRunners.
|
|
|
| Args:
|
| runners: a list of TestRunner objects.
|
| - tests: a list of Tests to run using the given TestRunners.
|
| + test_collection_factory: a callable to generate a _TestCollection object for
|
| + each test runner.
|
| num_retries: number of retries for a test.
|
| timeout: watchdog timeout in seconds, defaults to the default timeout.
|
|
|
| Returns:
|
| A tuple of (TestRunResults object, exit code)
|
| """
|
| - logging.warning('Running %s tests with %s test runners.' %
|
| - (len(tests), len(runners)))
|
| - tests_collection = _TestCollection([_Test(t) for t in tests])
|
| + logging.warning('Running tests with %s test runners.' % (len(runners)))
|
| results = []
|
| exit_code = 0
|
| watcher = watchdog_timer.WatchdogTimer(timeout)
|
| +
|
| workers = reraiser_thread.ReraiserThreadGroup(
|
| [reraiser_thread.ReraiserThread(
|
| _RunTestsFromQueue,
|
| - [r, tests_collection, results, watcher, num_retries],
|
| + [r, test_collection_factory(), results, watcher, num_retries],
|
| name=r.device[-4:])
|
| for r in runners])
|
| run_results = base_test_result.TestRunResults()
|
| @@ -267,36 +267,82 @@ def _TearDownRunners(runners, timeout=None):
|
| threads.JoinAll(watchdog_timer.WatchdogTimer(timeout))
|
|
|
|
|
| -def ShardAndRunTests(runner_factory, devices, tests, build_type='Debug',
|
| - test_timeout=DEFAULT_TIMEOUT,
|
| - setup_timeout=DEFAULT_TIMEOUT,
|
| - num_retries=2):
|
| +def ReplicateAndRunTests(tests, *args, **kwargs):
|
| + """Replicates the tests for each device, so all devices run every test.
|
| +
|
| + Args:
|
| + tests: A list of tests to run.
|
| + *args, **kwargs: Args and kwargs to RunTests which we pass through.
|
| +
|
| + Returns:
|
| + A tuple of (base_test_result.TestRunResults object, exit code).
|
| + """
|
| +
|
| + if not tests:
|
| + logging.error('No tests to run.')
|
| + return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE)
|
| +
|
| + logging.info('Will run %d tests: %s', len(tests), str(tests))
|
| +
|
| + # Genereate a unique _TestCollection object for each test runner, but use
|
| + # the same set of tests.
|
| + TestCollectionFactory = lambda: _TestCollection([_Test(t) for t in tests])
|
| + return RunTests(TestCollectionFactory, *args, **kwargs)
|
| +
|
| +
|
| +def ShardAndRunTests(tests, *args, **kwargs):
|
| + """Distrbutes all tests over devices through a shared pool of tests.
|
| +
|
| + Args:
|
| + tests: A list of tests to run.
|
| + *args, **kwargs: Args and kwargs to RunTests which we pass through.
|
| +
|
| + Returns:
|
| + A tuple of (base_test_result.TestRunResults object, exit code).
|
| + """
|
| +
|
| + if not tests:
|
| + logging.error('No tests to run.')
|
| + return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE)
|
| +
|
| + logging.info('Will run %d tests: %s', len(tests), str(tests))
|
| +
|
| + # Genereate a shared _TestCollection object for all test runners, so they draw
|
| + # from a common pool of tests.
|
| + shared_test_collection = _TestCollection([_Test(t) for t in tests])
|
| + TestCollectionFactory = lambda: shared_test_collection
|
| + return RunTests(TestCollectionFactory, *args, **kwargs)
|
| +
|
| +
|
| +def RunTests(test_collection_factory, runner_factory, devices,
|
| + build_type='Debug',
|
| + test_timeout=DEFAULT_TIMEOUT,
|
| + setup_timeout=DEFAULT_TIMEOUT,
|
| + num_retries=2):
|
| """Run all tests on attached devices, retrying tests that don't pass.
|
|
|
| Args:
|
| runner_factory: callable that takes a device and index and returns a
|
| - TestRunner object.
|
| + TestRunner object.
|
| + test_collection_factory: callable that is used to generate a _TestCollection
|
| + object for each test runner.
|
| devices: list of attached device serial numbers as strings.
|
| tests: list of tests to run.
|
| build_type: either 'Debug' or 'Release'.
|
| test_timeout: watchdog timeout in seconds for running tests, defaults to the
|
| - default timeout.
|
| + default timeout.
|
| setup_timeout: watchdog timeout in seconds for creating and cleaning up
|
| - test runners, defaults to the default timeout.
|
| + test runners, defaults to the default timeout.
|
| num_retries: number of retries for a test.
|
|
|
| Returns:
|
| A tuple of (base_test_result.TestRunResults object, exit code).
|
| """
|
| - if not tests:
|
| - logging.error('No tests to run.')
|
| - return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE)
|
| -
|
| - logging.info('Will run %d tests: %s', len(tests), str(tests))
|
| forwarder.Forwarder.KillHost(build_type)
|
| runners = _CreateRunners(runner_factory, devices, setup_timeout)
|
| try:
|
| - return _RunAllTests(runners, tests, num_retries, test_timeout)
|
| + return _RunAllTests(runners, test_collection_factory,
|
| + num_retries, test_timeout)
|
| finally:
|
| try:
|
| _TearDownRunners(runners, setup_timeout)
|
|
|