Changeset 90679 in webkit


Ignore:
Timestamp:
Jul 9, 2011 4:21:30 AM (13 years ago)
Author:
dpranke@chromium.org
Message:

nrwt: stack traces from worker-side exceptions aren't very useful inside test-webkitpy
https://bugs.webkit.org/show_bug.cgi?id=64218

Reviewed by Eric Seidel.

Exceptions aren't picklable and can't be sent across the
manager/worker message queue without losing information. NRWT
handles this by turning the stack trace into a set of strings,
and logging the strings when we receive an exception from the
worker. However, when you are running tests and something
crashes on the worker side, test-webkitpy prints the
manager-side stack trace, which is just confusing and useless.

This patch changes the logic so that exceptions are passed
through as-is when the worker and manager are in the same
process (the --worker-model=inline option). This increases the
code paths slightly but makes crashes much more useful.

  • Scripts/webkitpy/layout_tests/controllers/manager.py:
  • Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py:
  • Scripts/webkitpy/layout_tests/controllers/message_broker.py:
  • Scripts/webkitpy/layout_tests/controllers/worker.py:
  • Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py:
Location:
trunk/Tools
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r90677 r90679  
     12011-07-09  Dirk Pranke  <dpranke@chromium.org>
     2
     3        nrwt: stack traces from worker-side exceptions aren't very useful inside test-webkitpy
     4        https://bugs.webkit.org/show_bug.cgi?id=64218
     5
     6        Reviewed by Eric Seidel.
     7
     8        Exceptions aren't picklable and can't be sent across the
     9        manager/worker message queue without losing information. NRWT
     10        handles this by turning the stack trace into a set of strings,
     11        and logging the strings when we receive an exception from the
     12        worker. However, when you are running tests and something
     13        crashes on the worker side, test-webkitpy prints the
     14        manager-side stack trace, which is just confusing and useless.
     15
     16        This patch changes the logic so that exceptions are passed
     17        through as-is when the worker and manager are in the same
     18        process (the --worker-model=inline option). This increases the
     19        code paths slightly but makes crashes much more useful.
     20
     21        * Scripts/webkitpy/layout_tests/controllers/manager.py:
     22        * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py:
     23        * Scripts/webkitpy/layout_tests/controllers/message_broker.py:
     24        * Scripts/webkitpy/layout_tests/controllers/worker.py:
     25        * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py:
     26
    1272011-07-09  Darin Fisher  <darin@chromium.org>
    228
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py

    r90651 r90679  
    779779            keyboard_interrupted = True
    780780        except TestRunInterruptedException, e:
    781             _log.info(e.reason)
     781            _log.warning(e.reason)
    782782            self.cancel_workers()
    783783            interrupted = True
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py

    r90526 r90679  
    236236        self._broker.run_all_pending(MANAGER_TOPIC, self._manager_client)
    237237
     238    def raise_exception(self, exc_info):
     239        # Since the worker is in the same process as the manager, we can
     240        # raise the exception directly, rather than having to send it through
     241        # the queue. This allows us to preserve the traceback.
     242        raise exc_info[0], exc_info[1], exc_info[2]
     243
    238244
    239245if multiprocessing:
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/message_broker.py

    r90523 r90679  
    6262import logging
    6363import Queue
     64import sys
    6465import time
    65 
     66import traceback
     67
     68from webkitpy.common.system import stack_utils
    6669
    6770_log = logging.getLogger(__name__)
     
    195198        self._broker.post_message(self._client, self._post_topic,
    196199                                  message_name, *message_args)
     200
     201    def raise_exception(self, exc_info):
     202        # Since tracebacks aren't picklable, send the extracted stack instead.
     203        exception_type, exception_value, exception_traceback = sys.exc_info()
     204        stack_utils.log_traceback(_log.debug, exception_traceback)
     205        stack = traceback.extract_tb(exception_traceback)
     206        self._broker.post_message(self._client, self._post_topic, 'exception', exception_type, exception_value, stack)
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py

    r90532 r90679  
    3333import threading
    3434import time
    35 import traceback
    36 
    37 from webkitpy.common.system import stack_utils
     35
    3836from webkitpy.layout_tests.controllers import manager_worker_broker
    3937from webkitpy.layout_tests.controllers import single_test_runner
     
    9694        except KeyboardInterrupt:
    9795            exception_msg = ", interrupted"
    98             self.post_exception()
     96            self._worker_connection.raise_exception(sys.exc_info())
    9997        except:
    10098            exception_msg = ", exception raised"
    101             self.post_exception()
     99            self._worker_connection.raise_exception(sys.exc_info())
    102100        finally:
    103101            _log.debug("%s done with message loop%s" % (self._name, exception_msg))
     
    105103            self.cleanup()
    106104            _log.debug("%s exiting" % self._name)
    107 
    108     def post_exception(self):
    109         # Since tracebacks aren't picklable, send the extracted stack instead.
    110         exception_type, exception_value, exception_traceback = sys.exc_info()
    111         stack_utils.log_traceback(_log.debug, exception_traceback)
    112         stack = traceback.extract_tb(exception_traceback)
    113         self._worker_connection.post_message('exception', exception_type, exception_value, stack)
    114105
    115106    def handle_test_list(self, src, list_name, test_list):
  • trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py

    r90607 r90679  
    237237
    238238    def test_exception_raised(self):
     239        # Exceptions raised by a worker are treated differently depending on
     240        # whether they are in-process or out. inline exceptions work as normal,
     241        # which allows us to get the full stack trace and traceback from the
     242        # worker. The downside to this is that it could be any error, but this
     243        # is actually useful in testing, which is what --worker-model=inline is
     244        # usually used for.
     245        #
     246        # Exceptions raised in a separate process are re-packaged into
     247        # WorkerExceptions, which have a string capture of the stack which can
     248        # be printed, but don't display properly in the unit test exception handlers.
     249        self.assertRaises(ValueError, logging_run,
     250            ['failures/expected/exception.html'], tests_included=True)
     251
    239252        self.assertRaises(run_webkit_tests.WorkerException, logging_run,
    240             ['failures/expected/exception.html'], tests_included=True)
     253            ['--worker-model', 'processes', 'failures/expected/exception.html'], tests_included=True)
    241254
    242255    def test_full_results_html(self):
     
    326339        # This raises an exception because we run
    327340        # failures/expected/exception.html, which is normally SKIPped.
    328         self.assertRaises(run_webkit_tests.WorkerException, logging_run, ['--force'])
     341
     342        # See also the comments in test_exception_raised() about ValueError vs. WorkerException.
     343        self.assertRaises(ValueError, logging_run, ['--force'])
    329344
    330345    def test_run_part(self):
Note: See TracChangeset for help on using the changeset viewer.