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 |