Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Dispatches tests, either sharding or replicating them. | 5 """Dispatches tests, either sharding or replicating them. |
| 6 | 6 |
| 7 To dispatch, performs the following steps: | 7 Performs the following steps: |
| 8 * Create a test collection factory, using the given tests | 8 * Create a test collection factory, using the given tests |
| 9 - If sharding: test collection factory returns the same shared test collection | 9 - If sharding: test collection factory returns the same shared test collection |
| 10 to all test runners | 10 to all test runners |
| 11 - If replciating: test collection factory returns a unique test collection to | 11 - If replciating: test collection factory returns a unique test collection to |
| 12 each test runner, with the same set of tests in each. | 12 each test runner, with the same set of tests in each. |
| 13 * Get the list of devices to run on | 13 * Create a test runner for each device |
| 14 * Create test runners | 14 * Run each test runner in its own thread, grabbing tests from the test |
| 15 * Run each test runner in its own thread, pulling tests from the test collection | 15 collection until there are no tests left. |
| 16 generated from the test collection factory until there are no tests left. | |
| 17 """ | 16 """ |
| 18 | 17 |
| 19 import logging | 18 import logging |
| 20 import threading | 19 import threading |
| 21 | 20 |
| 22 from pylib import android_commands | 21 from pylib import android_commands |
| 23 from pylib import constants | 22 from pylib import constants |
| 24 from pylib.utils import reraiser_thread | 23 from pylib.utils import reraiser_thread |
| 25 from pylib.utils import watchdog_timer | 24 from pylib.utils import watchdog_timer |
| 26 | 25 |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 runners: A list of TestRunner objects. | 296 runners: A list of TestRunner objects. |
| 298 timeout: Watchdog timeout in seconds, defaults to the default timeout. | 297 timeout: Watchdog timeout in seconds, defaults to the default timeout. |
| 299 """ | 298 """ |
| 300 threads = reraiser_thread.ReraiserThreadGroup( | 299 threads = reraiser_thread.ReraiserThreadGroup( |
| 301 [reraiser_thread.ReraiserThread(r.TearDown, name=r.device[-4:]) | 300 [reraiser_thread.ReraiserThread(r.TearDown, name=r.device[-4:]) |
| 302 for r in runners]) | 301 for r in runners]) |
| 303 threads.StartAll() | 302 threads.StartAll() |
| 304 threads.JoinAll(watchdog_timer.WatchdogTimer(timeout)) | 303 threads.JoinAll(watchdog_timer.WatchdogTimer(timeout)) |
| 305 | 304 |
| 306 | 305 |
| 307 | 306 def RunTests(tests, runner_factory, devices, shard=True, |
|
craigdh
2013/08/19 18:22:35
Update the unittest as well.
frankf
2013/08/19 19:05:50
Good catch. Done.
On 2013/08/19 18:22:35, craigdh
| |
| 308 def _GetAttachedDevices(wait_for_debugger=False, test_device=None): | 307 test_timeout=DEFAULT_TIMEOUT, setup_timeout=DEFAULT_TIMEOUT, |
| 309 """Get all attached devices. | |
| 310 | |
| 311 If we are using a debugger, limit to only one device. | |
| 312 | |
| 313 Args: | |
| 314 wait_for_debugger: True if this run will use a debugger. | |
| 315 test_device: Name of a specific device to use. | |
| 316 | |
| 317 Returns: | |
| 318 A list of attached devices. | |
| 319 """ | |
| 320 attached_devices = [] | |
| 321 | |
| 322 attached_devices = android_commands.GetAttachedDevices() | |
| 323 if test_device: | |
| 324 assert test_device in attached_devices, ( | |
| 325 'Did not find device %s among attached device. Attached devices: %s' | |
| 326 % (test_device, ', '.join(attached_devices))) | |
| 327 attached_devices = [test_device] | |
| 328 | |
| 329 if len(attached_devices) > 1 and wait_for_debugger: | |
| 330 logging.warning('Debugger can not be sharded, using first available device') | |
| 331 attached_devices = attached_devices[:1] | |
| 332 | |
| 333 return sorted(attached_devices) | |
| 334 | |
| 335 | |
| 336 def RunTests(tests, runner_factory, wait_for_debugger, test_device, | |
| 337 shard=True, | |
| 338 test_timeout=DEFAULT_TIMEOUT, | |
| 339 setup_timeout=DEFAULT_TIMEOUT, | |
| 340 num_retries=2): | 308 num_retries=2): |
| 341 """Run all tests on attached devices, retrying tests that don't pass. | 309 """Run all tests on attached devices, retrying tests that don't pass. |
| 342 | 310 |
| 343 Args: | 311 Args: |
| 344 tests: List of tests to run. | 312 tests: List of tests to run. |
| 345 runner_factory: Callable that takes a device and index and returns a | 313 runner_factory: Callable that takes a device and index and returns a |
| 346 TestRunner object. | 314 TestRunner object. |
| 347 wait_for_debugger: True if this test is using a debugger. | 315 devices: List of attached devices. |
| 348 test_device: A specific device to run tests on, or None. | |
| 349 shard: True if we should shard, False if we should replicate tests. | 316 shard: True if we should shard, False if we should replicate tests. |
| 350 - Sharding tests will distribute tests across all test runners through a | 317 - Sharding tests will distribute tests across all test runners through a |
| 351 shared test collection. | 318 shared test collection. |
| 352 - Replicating tests will copy all tests to each test runner through a | 319 - Replicating tests will copy all tests to each test runner through a |
| 353 unique test collection for each test runner. | 320 unique test collection for each test runner. |
| 354 test_timeout: Watchdog timeout in seconds for running tests. | 321 test_timeout: Watchdog timeout in seconds for running tests. |
| 355 setup_timeout: Watchdog timeout in seconds for creating and cleaning up | 322 setup_timeout: Watchdog timeout in seconds for creating and cleaning up |
| 356 test runners. | 323 test runners. |
| 357 num_retries: Number of retries for a test. | 324 num_retries: Number of retries for a test. |
| 358 | 325 |
| 359 Returns: | 326 Returns: |
| 360 A tuple of (base_test_result.TestRunResults object, exit code). | 327 A tuple of (base_test_result.TestRunResults object, exit code). |
| 361 """ | 328 """ |
| 362 if not tests: | 329 if not tests: |
| 363 logging.critical('No tests to run.') | 330 logging.critical('No tests to run.') |
| 364 return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE) | 331 return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE) |
| 332 | |
| 365 if shard: | 333 if shard: |
| 366 # Generate a shared _TestCollection object for all test runners, so they | 334 # Generate a shared _TestCollection object for all test runners, so they |
| 367 # draw from a common pool of tests. | 335 # draw from a common pool of tests. |
| 368 shared_test_collection = _TestCollection([_Test(t) for t in tests]) | 336 shared_test_collection = _TestCollection([_Test(t) for t in tests]) |
| 369 test_collection_factory = lambda: shared_test_collection | 337 test_collection_factory = lambda: shared_test_collection |
| 370 tag_results_with_device = False | 338 tag_results_with_device = False |
| 371 log_string = 'sharded across devices' | 339 log_string = 'sharded across devices' |
| 372 else: | 340 else: |
| 373 # Generate a unique _TestCollection object for each test runner, but use | 341 # Generate a unique _TestCollection object for each test runner, but use |
| 374 # the same set of tests. | 342 # the same set of tests. |
| 375 test_collection_factory = lambda: _TestCollection([_Test(t) for t in tests]) | 343 test_collection_factory = lambda: _TestCollection([_Test(t) for t in tests]) |
| 376 tag_results_with_device = True | 344 tag_results_with_device = True |
| 377 log_string = 'replicated on each device' | 345 log_string = 'replicated on each device' |
| 378 | 346 |
| 379 devices = _GetAttachedDevices(wait_for_debugger, test_device) | |
| 380 if not devices: | |
| 381 logging.critical('No attached devices.') | |
| 382 return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE) | |
| 383 | |
| 384 logging.info('Will run %d tests (%s): %s', len(tests), log_string, str(tests)) | 347 logging.info('Will run %d tests (%s): %s', len(tests), log_string, str(tests)) |
| 385 runners = _CreateRunners(runner_factory, devices, setup_timeout) | 348 runners = _CreateRunners(runner_factory, devices, setup_timeout) |
| 386 try: | 349 try: |
| 387 return _RunAllTests(runners, test_collection_factory, | 350 return _RunAllTests(runners, test_collection_factory, |
| 388 num_retries, test_timeout, tag_results_with_device) | 351 num_retries, test_timeout, tag_results_with_device) |
| 389 finally: | 352 finally: |
| 390 try: | 353 try: |
| 391 _TearDownRunners(runners, setup_timeout) | 354 _TearDownRunners(runners, setup_timeout) |
| 392 except android_commands.errors.DeviceUnresponsiveError as e: | 355 except android_commands.errors.DeviceUnresponsiveError as e: |
| 393 logging.warning('Device unresponsive during TearDown: [%s]', e) | 356 logging.warning('Device unresponsive during TearDown: [%s]', e) |
| OLD | NEW |