| OLD | NEW |
| 1 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2006-2008 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 """A Thread object for running the test shell and processing URLs from a | 5 """A Thread object for running the test shell and processing URLs from a |
| 6 shared queue. | 6 shared queue. |
| 7 | 7 |
| 8 Each thread runs a separate instance of the test_shell binary and validates | 8 Each thread runs a separate instance of the test_shell binary and validates |
| 9 the output. When there are no more URLs to process in the shared queue, the | 9 the output. When there are no more URLs to process in the shared queue, the |
| 10 thread exits. | 10 thread exits. |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 self._test_shell_command = test_shell_command | 168 self._test_shell_command = test_shell_command |
| 169 self._test_types = test_types | 169 self._test_types = test_types |
| 170 self._test_args = test_args | 170 self._test_args = test_args |
| 171 self._test_shell_proc = None | 171 self._test_shell_proc = None |
| 172 self._shell_args = shell_args | 172 self._shell_args = shell_args |
| 173 self._options = options | 173 self._options = options |
| 174 self._failures = {} | 174 self._failures = {} |
| 175 self._canceled = False | 175 self._canceled = False |
| 176 self._exception_info = None | 176 self._exception_info = None |
| 177 self._timing_stats = {} | 177 self._timing_stats = {} |
| 178 self._test_times = [] |
| 178 | 179 |
| 179 # Current directory of tests we're running. | 180 # Current directory of tests we're running. |
| 180 self._current_dir = None | 181 self._current_dir = None |
| 181 # Number of tests in self._current_dir. | 182 # Number of tests in self._current_dir. |
| 182 self._num_tests_in_current_dir = None | 183 self._num_tests_in_current_dir = None |
| 183 # Time at which we started running tests from self._current_dir. | 184 # Time at which we started running tests from self._current_dir. |
| 184 self._current_dir_start_time = None | 185 self._current_dir_start_time = None |
| 185 | 186 |
| 186 if self._options.run_singly: | 187 if self._options.run_singly: |
| 187 # When we're running one test per test_shell process, we can enforce | 188 # When we're running one test per test_shell process, we can enforce |
| 188 # a hard timeout. test_shell uses a default of 10 seconds if no | 189 # a hard timeout. test_shell uses a default of 10 seconds if no |
| 189 # time-out-ms is given, and the test_shell watchdog uses 2.5x the | 190 # time-out-ms is given, and the test_shell watchdog uses 2.5x the |
| 190 # test_shell's value. We want to be larger than that. | 191 # test_shell's value. We want to be larger than that. |
| 191 self._time_out_sec = int(self._options.time_out_ms) * 3.0 / 1000.0 | 192 self._time_out_sec = int(self._options.time_out_ms) * 3.0 / 1000.0 |
| 192 logging.info("Setting Python per-test timeout to %s ms (%s sec)" % | 193 logging.info("Setting Python per-test timeout to %s ms (%s sec)" % |
| 193 (1000 * self._time_out_sec, self._time_out_sec)) | 194 (1000 * self._time_out_sec, self._time_out_sec)) |
| 194 | 195 |
| 195 | 196 |
| 196 def GetFailures(self): | 197 def GetFailures(self): |
| 197 """Returns a dictionary mapping test filename to a list of | 198 """Returns a dictionary mapping test filename to a list of |
| 198 TestFailures.""" | 199 TestFailures.""" |
| 199 return self._failures | 200 return self._failures |
| 200 | 201 |
| 201 def GetTimingStats(self): | 202 def GetTimingStats(self): |
| 202 """Returns a dictionary mapping test directory to a tuple of | 203 """Returns a dictionary mapping test directory to a tuple of |
| 203 (number of tests in that directory, time to run the tests)""" | 204 (number of tests in that directory, time to run the tests)""" |
| 204 return self._timing_stats; | 205 return self._timing_stats; |
| 205 | 206 |
| 207 def GetIndividualTestTimingStats(self): |
| 208 """Returns a list of (time, test_filename) tuples where time is the |
| 209 time it took to run the test.""" |
| 210 return self._test_times |
| 211 |
| 206 def Cancel(self): | 212 def Cancel(self): |
| 207 """Set a flag telling this thread to quit.""" | 213 """Set a flag telling this thread to quit.""" |
| 208 self._canceled = True | 214 self._canceled = True |
| 209 | 215 |
| 210 def GetExceptionInfo(self): | 216 def GetExceptionInfo(self): |
| 211 """If run() terminated on an uncaught exception, return it here | 217 """If run() terminated on an uncaught exception, return it here |
| 212 ((type, value, traceback) tuple). | 218 ((type, value, traceback) tuple). |
| 213 Returns None if run() terminated normally. Meant to be called after | 219 Returns None if run() terminated normally. Meant to be called after |
| 214 joining this thread.""" | 220 joining this thread.""" |
| 215 return self._exception_info | 221 return self._exception_info |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 # Ok, load the test URL... | 338 # Ok, load the test URL... |
| 333 self._test_shell_proc.stdin.write(test_uri + "\n") | 339 self._test_shell_proc.stdin.write(test_uri + "\n") |
| 334 # If the test shell is dead, the above may cause an IOError as we | 340 # If the test shell is dead, the above may cause an IOError as we |
| 335 # try to write onto the broken pipe. If this is the first test for | 341 # try to write onto the broken pipe. If this is the first test for |
| 336 # this test shell process, than the test shell did not | 342 # this test shell process, than the test shell did not |
| 337 # successfully start. If this is not the first test, then the | 343 # successfully start. If this is not the first test, then the |
| 338 # previous tests have caused some kind of delayed crash. We don't | 344 # previous tests have caused some kind of delayed crash. We don't |
| 339 # try to recover here. | 345 # try to recover here. |
| 340 self._test_shell_proc.stdin.flush() | 346 self._test_shell_proc.stdin.flush() |
| 341 | 347 |
| 348 start_time = time.time() |
| 349 |
| 342 # ...and read the response | 350 # ...and read the response |
| 343 return ProcessOutput(self._test_shell_proc, filename, test_uri, | 351 failures = ProcessOutput(self._test_shell_proc, filename, test_uri, |
| 344 self._test_types, self._test_args, | 352 self._test_types, self._test_args, self._options.target) |
| 345 self._options.target) | 353 |
| 354 time_to_run_test = time.time() - start_time |
| 355 self._test_times.append((time_to_run_test, filename)) |
| 356 return failures |
| 346 | 357 |
| 347 | 358 |
| 348 def _EnsureTestShellIsRunning(self): | 359 def _EnsureTestShellIsRunning(self): |
| 349 """Start the shared test shell, if it's not running. Not for use when | 360 """Start the shared test shell, if it's not running. Not for use when |
| 350 running tests singly, since those each start a separate test shell in | 361 running tests singly, since those each start a separate test shell in |
| 351 their own thread. | 362 their own thread. |
| 352 """ | 363 """ |
| 353 if (not self._test_shell_proc or | 364 if (not self._test_shell_proc or |
| 354 self._test_shell_proc.poll() is not None): | 365 self._test_shell_proc.poll() is not None): |
| 355 self._test_shell_proc = StartTestShell(self._test_shell_command, | 366 self._test_shell_proc = StartTestShell(self._test_shell_command, |
| 356 self._shell_args) | 367 self._shell_args) |
| 357 | 368 |
| 358 def _KillTestShell(self): | 369 def _KillTestShell(self): |
| 359 """Kill the test shell process if it's running.""" | 370 """Kill the test shell process if it's running.""" |
| 360 if self._test_shell_proc: | 371 if self._test_shell_proc: |
| 361 self._test_shell_proc.stdin.close() | 372 self._test_shell_proc.stdin.close() |
| 362 self._test_shell_proc.stdout.close() | 373 self._test_shell_proc.stdout.close() |
| 363 if self._test_shell_proc.stderr: | 374 if self._test_shell_proc.stderr: |
| 364 self._test_shell_proc.stderr.close() | 375 self._test_shell_proc.stderr.close() |
| 365 if sys.platform not in ('win32', 'cygwin'): | 376 if sys.platform not in ('win32', 'cygwin'): |
| 366 # Closing stdin/stdout/stderr hangs sometimes on OS X. | 377 # Closing stdin/stdout/stderr hangs sometimes on OS X. |
| 367 subprocess.Popen(["kill", "-9", str(self._test_shell_proc.pid)]) | 378 subprocess.Popen(["kill", "-9", str(self._test_shell_proc.pid)]) |
| 368 self._test_shell_proc = None | 379 self._test_shell_proc = None |
| OLD | NEW |