Changeset 88848 in webkit
- Timestamp:
- Jun 14, 2011 1:36:57 PM (13 years ago)
- Location:
- trunk/Tools
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r88838 r88848 1 2011-06-14 Dirk Pranke <dpranke@chromium.org> 2 3 Reviewed by Tony Chang. 4 5 nrwt: handle worker exceptions cleanly 6 https://bugs.webkit.org/show_bug.cgi?id=62614 7 8 This change modifiers new-run-webkit-tests to handle exceptions 9 raised by worker threads better, by: 10 - capturing the worker's stack and logging it in the manager 11 - propagating the worker's exception in the caller correctly 12 - attempting to cancel the workers and clean up even when 13 we get an unexpected exception 14 15 * Scripts/webkitpy/layout_tests/layout_package/manager.py: 16 * Scripts/webkitpy/layout_tests/layout_package/worker.py: 17 * Scripts/webkitpy/layout_tests/run_webkit_tests.py: 18 * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py: 19 1 20 2011-06-14 Qi Zhang <qi.2.zhang@nokia.com> 2 21 -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/manager.py
r88070 r88848 230 230 231 231 232 class WorkerException(Exception): 233 """Raised when we receive an unexpected/unknown exception from a worker.""" 234 pass 235 236 232 237 class Manager: 233 238 """A class for managing running a series of tests on a series of layout … … 688 693 self.cancel_workers() 689 694 interrupted = True 695 except WorkerException: 696 self.cancel_workers() 697 raise 690 698 except: 691 699 # Unexpected exception; don't try to clean up workers. 692 _log.info("Exception raised, exiting") 700 _log.error("Exception raised, exiting") 701 self.cancel_workers() 693 702 raise 694 703 … … 1310 1319 worker_state.done = True 1311 1320 1312 def handle_exception(self, source, exception_info): 1313 exception_type, exception_value, exception_traceback = exception_info 1314 raise exception_type, exception_value, exception_traceback 1321 def handle_exception(self, source, exception_type, exception_value, stack): 1322 if exception_type in (KeyboardInterrupt, TestRunInterruptedException): 1323 raise exception_type(exception_value) 1324 _log.error("%s raised %s('%s'):" % ( 1325 source, 1326 exception_value.__class__.__name__, 1327 str(exception_value))) 1328 self._log_worker_stack(stack) 1329 raise WorkerException(str(exception_value)) 1315 1330 1316 1331 def handle_finished_list(self, source, list_name, num_tests, elapsed_time): … … 1331 1346 self._update_summary_with_result(self._current_result_summary, result) 1332 1347 1348 def _log_worker_stack(self, stack): 1349 webkitpydir = self._port.path_from_webkit_base('Tools', 'Scripts', 'webkitpy') + self._port._filesystem.sep 1350 for filename, line_number, function_name, text in stack: 1351 if filename.startswith(webkitpydir): 1352 filename = filename.replace(webkitpydir, '') 1353 _log.error(' %s:%u (in %s)' % (filename, line_number, function_name)) 1354 _log.error(' %s' % text) 1333 1355 1334 1356 def read_test_files(fs, files): -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/worker.py
r88070 r88848 33 33 import threading 34 34 import time 35 import traceback 35 36 36 37 from webkitpy.common.system import stack_utils … … 100 101 except KeyboardInterrupt: 101 102 exception_msg = ", interrupted" 103 self.post_exception() 102 104 except: 103 105 exception_msg = ", exception raised" 106 self.post_exception() 104 107 finally: 105 108 _log.debug("%s done with message loop%s" % (self._name, exception_msg)) 106 if exception_msg:107 exception_type, exception_value, exception_traceback = sys.exc_info()108 stack_utils.log_traceback(_log.debug, exception_traceback)109 # FIXME: Figure out how to send a message with a traceback.110 self._worker_connection.post_message('exception',111 (exception_type, exception_value, None))112 109 self._worker_connection.post_message('done') 113 110 self.cleanup() 114 111 _log.debug("%s exiting" % self._name) 112 113 def post_exception(self): 114 # Since tracebacks aren't picklable, send the extracted stack instead. 115 exception_type, exception_value, exception_traceback = sys.exc_info() 116 stack_utils.log_traceback(_log.debug, exception_traceback) 117 stack = traceback.extract_tb(exception_traceback) 118 self._worker_connection.post_message('exception', exception_type, exception_value, stack) 115 119 116 120 def handle_test_list(self, src, list_name, test_list): -
trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
r88388 r88848 52 52 _log = logging.getLogger(__name__) 53 53 54 55 WorkerException = manager.WorkerException 54 56 55 57 def run(port, options, args, regular_output=sys.stderr, … … 460 462 sys.exit(main()) 461 463 except KeyboardInterrupt: 462 # this mirrors what the shell normally does 463 sys.exit(signal.SIGINT + 128) 464 # This mirrors what the shell normally does. 465 INTERRUPTED_EXIT_STATUS = signal.SIGINT + 128 466 sys.exit(INTERRUPTED_EXIT_STATUS) 467 except WorkerException, e: 468 # This is a randomly chosen exit code that can be tested against to 469 # indicate that an unexpected exception occurred. 470 EXCEPTIONAL_EXIT_STATUS = 254 471 sys.exit(EXCEPTIONAL_EXIT_STATUS) -
trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
r86126 r88848 221 221 222 222 def test_exception_raised(self): 223 self.assertRaises( ValueError, logging_run,223 self.assertRaises(run_webkit_tests.WorkerException, logging_run, 224 224 ['failures/expected/exception.html'], tests_included=True) 225 225 … … 320 320 # This raises an exception because we run 321 321 # failures/expected/exception.html, which is normally SKIPped. 322 self.assertRaises( ValueError, logging_run, ['--force'])322 self.assertRaises(run_webkit_tests.WorkerException, logging_run, ['--force']) 323 323 324 324 def test_run_part(self):
Note: See TracChangeset
for help on using the changeset viewer.