| 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 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 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 num_retries: Number of retries for a test. | 164 num_retries: Number of retries for a test. |
| 165 timeout: Watchdog timeout in seconds. | 165 timeout: Watchdog timeout in seconds. |
| 166 tag_results_with_device: If True, appends the name of the device on which | 166 tag_results_with_device: If True, appends the name of the device on which |
| 167 the test was run to the test name. Used when replicating to identify | 167 the test was run to the test name. Used when replicating to identify |
| 168 which device ran each copy of the test, and to ensure each copy of the | 168 which device ran each copy of the test, and to ensure each copy of the |
| 169 test is recorded separately. | 169 test is recorded separately. |
| 170 | 170 |
| 171 Returns: | 171 Returns: |
| 172 A tuple of (TestRunResults object, exit code) | 172 A tuple of (TestRunResults object, exit code) |
| 173 """ | 173 """ |
| 174 logging.warning('Running tests with %s test runners.' % (len(runners))) | 174 logging.warning('Running tests with %s test runners.', len(runners)) |
| 175 results = [] | 175 results = [] |
| 176 exit_code = 0 | 176 exit_code = 0 |
| 177 run_results = base_test_result.TestRunResults() | 177 run_results = base_test_result.TestRunResults() |
| 178 watcher = watchdog_timer.WatchdogTimer(timeout) | 178 watcher = watchdog_timer.WatchdogTimer(timeout) |
| 179 test_collections = [test_collection_factory() for _ in runners] | 179 test_collections = [test_collection_factory() for _ in runners] |
| 180 | 180 |
| 181 threads = [ | 181 threads = [ |
| 182 reraiser_thread.ReraiserThread( | 182 reraiser_thread.ReraiserThread( |
| 183 _RunTestsFromQueue, | 183 _RunTestsFromQueue, |
| 184 [r, tc, results, watcher, num_retries, tag_results_with_device], | 184 [r, tc, results, watcher, num_retries, tag_results_with_device], |
| 185 name=r.device_serial[-4:]) | 185 name=r.device_serial[-4:]) |
| 186 for r, tc in zip(runners, test_collections)] | 186 for r, tc in zip(runners, test_collections)] |
| 187 | 187 |
| 188 workers = reraiser_thread.ReraiserThreadGroup(threads) | 188 workers = reraiser_thread.ReraiserThreadGroup(threads) |
| 189 workers.StartAll() | 189 workers.StartAll() |
| 190 | 190 |
| 191 try: | 191 try: |
| 192 workers.JoinAll(watcher) | 192 workers.JoinAll(watcher) |
| 193 except device_errors.CommandFailedError: | 193 except device_errors.CommandFailedError: |
| 194 logging.exception('Command failed on device.') | 194 logging.exception('Command failed on device.') |
| 195 except device_errors.CommandFailedError: | 195 except device_errors.CommandFailedError: |
| 196 logging.exception('Command timed out on device.') | 196 logging.exception('Command timed out on device.') |
| 197 except device_errors.DeviceUnreachableError: | 197 except device_errors.DeviceUnreachableError: |
| 198 logging.exception('Device became unreachable.') | 198 logging.exception('Device became unreachable.') |
| 199 | 199 |
| 200 if not all((len(tc) == 0 for tc in test_collections)): | 200 if not all((len(tc) == 0 for tc in test_collections)): |
| 201 logging.error('Only ran %d tests (all devices are likely offline).' % | 201 logging.error('Only ran %d tests (all devices are likely offline).', |
| 202 len(results)) | 202 len(results)) |
| 203 for tc in test_collections: | 203 for tc in test_collections: |
| 204 run_results.AddResults(base_test_result.BaseTestResult( | 204 run_results.AddResults(base_test_result.BaseTestResult( |
| 205 t, base_test_result.ResultType.UNKNOWN) for t in tc.test_names()) | 205 t, base_test_result.ResultType.UNKNOWN) for t in tc.test_names()) |
| 206 | 206 |
| 207 for r in results: | 207 for r in results: |
| 208 run_results.AddTestRunResults(r) | 208 run_results.AddTestRunResults(r) |
| 209 if not run_results.DidRunPass(): | 209 if not run_results.DidRunPass(): |
| 210 exit_code = constants.ERROR_EXIT_CODE | 210 exit_code = constants.ERROR_EXIT_CODE |
| 211 return (run_results, exit_code) | 211 return (run_results, exit_code) |
| 212 | 212 |
| 213 | 213 |
| 214 def _CreateRunners(runner_factory, devices, timeout=None): | 214 def _CreateRunners(runner_factory, devices, timeout=None): |
| 215 """Creates a test runner for each device and calls SetUp() in parallel. | 215 """Creates a test runner for each device and calls SetUp() in parallel. |
| 216 | 216 |
| 217 Note: if a device is unresponsive the corresponding TestRunner will not be | 217 Note: if a device is unresponsive the corresponding TestRunner will not be |
| 218 included in the returned list. | 218 included in the returned list. |
| 219 | 219 |
| 220 Args: | 220 Args: |
| 221 runner_factory: Callable that takes a device and index and returns a | 221 runner_factory: Callable that takes a device and index and returns a |
| 222 TestRunner object. | 222 TestRunner object. |
| 223 devices: List of device serial numbers as strings. | 223 devices: List of device serial numbers as strings. |
| 224 timeout: Watchdog timeout in seconds, defaults to the default timeout. | 224 timeout: Watchdog timeout in seconds, defaults to the default timeout. |
| 225 | 225 |
| 226 Returns: | 226 Returns: |
| 227 A list of TestRunner objects. | 227 A list of TestRunner objects. |
| 228 """ | 228 """ |
| 229 logging.warning('Creating %s test runners.' % len(devices)) | 229 logging.warning('Creating %s test runners.', len(devices)) |
| 230 runners = [] | 230 runners = [] |
| 231 counter = _ThreadSafeCounter() | 231 counter = _ThreadSafeCounter() |
| 232 threads = reraiser_thread.ReraiserThreadGroup( | 232 threads = reraiser_thread.ReraiserThreadGroup( |
| 233 [reraiser_thread.ReraiserThread(_SetUp, | 233 [reraiser_thread.ReraiserThread(_SetUp, |
| 234 [runner_factory, d, runners, counter], | 234 [runner_factory, d, runners, counter], |
| 235 name=str(d)[-4:]) | 235 name=str(d)[-4:]) |
| 236 for d in devices]) | 236 for d in devices]) |
| 237 threads.StartAll() | 237 threads.StartAll() |
| 238 threads.JoinAll(watchdog_timer.WatchdogTimer(timeout)) | 238 threads.JoinAll(watchdog_timer.WatchdogTimer(timeout)) |
| 239 return runners | 239 return runners |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 len(tests_expanded), log_string, str(tests_expanded)) | 324 len(tests_expanded), log_string, str(tests_expanded)) |
| 325 runners = _CreateRunners(runner_factory, devices, setup_timeout) | 325 runners = _CreateRunners(runner_factory, devices, setup_timeout) |
| 326 try: | 326 try: |
| 327 return _RunAllTests(runners, test_collection_factory, | 327 return _RunAllTests(runners, test_collection_factory, |
| 328 num_retries, test_timeout, tag_results_with_device) | 328 num_retries, test_timeout, tag_results_with_device) |
| 329 finally: | 329 finally: |
| 330 try: | 330 try: |
| 331 _TearDownRunners(runners, setup_timeout) | 331 _TearDownRunners(runners, setup_timeout) |
| 332 except device_errors.DeviceUnreachableError as e: | 332 except device_errors.DeviceUnreachableError as e: |
| 333 logging.warning('Device unresponsive during TearDown: [%s]', e) | 333 logging.warning('Device unresponsive during TearDown: [%s]', e) |
| 334 except Exception as e: | 334 except Exception: # pylint: disable=broad-except |
| 335 logging.error('Unexpected exception caught during TearDown: %s' % str(e)) | 335 logging.exception('Unexpected exception caught during TearDown') |
| OLD | NEW |