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 |