Changeset 121816 in webkit


Ignore:
Timestamp:
Jul 3, 2012 5:14:25 PM (12 years ago)
Author:
dpranke@chromium.org
Message:

nrwt: clean up exception handling and make sure we log some more failures
https://bugs.webkit.org/show_bug.cgi?id=90503

Reviewed by Ojan Vafai.

There were several places where exceptions weren't getting
logged, most notably if you passed a bad value to --platform.
This change tests that and cleans things up a bit; more cleanup
will be possible when we rework the manager_worker_broker code.

  • Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py:

(_BrokerConnection.raise_exception):
(_InlineWorkerConnection.raise_exception):

  • Scripts/webkitpy/layout_tests/controllers/worker.py:

(Worker.run):
(Worker.kill_driver):

  • Scripts/webkitpy/layout_tests/port/factory.py:

(PortFactory.get):

  • Scripts/webkitpy/layout_tests/run_webkit_tests.py:

(run):
(main):

  • Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py:

(MainTest.test_unsupported_platfrom):

Location:
trunk/Tools
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r121812 r121816  
     12012-07-03  Dirk Pranke  <dpranke@chromium.org>
     2
     3        nrwt: clean up exception handling and make sure we log some more failures
     4        https://bugs.webkit.org/show_bug.cgi?id=90503
     5
     6        Reviewed by Ojan Vafai.
     7
     8        There were several places where exceptions weren't getting
     9        logged, most notably if you passed a bad value to --platform.
     10        This change tests that and cleans things up a bit; more cleanup
     11        will be possible when we rework the manager_worker_broker code.
     12
     13        * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py:
     14        (_BrokerConnection.raise_exception):
     15        (_InlineWorkerConnection.raise_exception):
     16        * Scripts/webkitpy/layout_tests/controllers/worker.py:
     17        (Worker.run):
     18        (Worker.kill_driver):
     19        * Scripts/webkitpy/layout_tests/port/factory.py:
     20        (PortFactory.get):
     21        * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
     22        (run):
     23        (main):
     24        * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py:
     25        (MainTest.test_unsupported_platfrom):
     26
    1272012-07-03  Dirk Pranke  <dpranke@chromium.org>
    228
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py

    r121809 r121816  
    256256
    257257    def raise_exception(self, exc_info):
    258         # Since tracebacks aren't picklable, send the extracted stack instead.
     258        # Since tracebacks aren't picklable, send the extracted stack instead,
     259        # but at least log the full traceback.
    259260        exception_type, exception_value, exception_traceback = sys.exc_info()
    260         stack_utils.log_traceback(_log.debug, exception_traceback)
     261        stack_utils.log_traceback(_log.error, exception_traceback)
    261262        stack = traceback.extract_tb(exception_traceback)
    262263        self._broker.post_message(self._client, self._post_topic, 'exception', exception_type, exception_value, stack)
     
    306307        finally:
    307308            _log.debug("%s done with message loop%s" % (self._name, exception_msg))
    308             self.worker.cleanup()
    309             self._worker_connection.post_message('done')
     309            try:
     310                self.worker.cleanup()
     311            finally:
     312                # Make sure we post a done so that we can flush the log messages
     313                # and clean up properly even if we raise an exception in worker.cleanup().
     314                self._worker_connection.post_message('done')
    310315
    311316    def handle_stop(self, source):
     
    457462        # Since the worker is in the same process as the manager, we can
    458463        # raise the exception directly, rather than having to send it through
    459         # the queue. This allows us to preserve the traceback.
    460         raise exc_info[0], exc_info[1], exc_info[2]
     464        # the queue. This allows us to preserve the traceback, but we log
     465        # it anyway for consistency with the multiprocess case.
     466        exception_type, exception_value, exception_traceback = sys.exc_info()
     467        stack_utils.log_traceback(_log.error, exception_traceback)
     468        raise exception_type, exception_value, exception_traceback
    461469
    462470
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py

    r121809 r121816  
    135135
    136136    def kill_driver(self):
    137         if self._driver:
     137        # Be careful about how and when we kill the driver; if driver.stop()
     138        # raises an exception, this routine may get re-entered via __del__.
     139        driver = self._driver
     140        self._driver = None
     141        if driver:
    138142            _log.debug("%s killing driver" % self._name)
    139             self._driver.stop()
    140             self._driver = None
     143            driver.stop()
    141144
    142145    def run_test_with_timeout(self, test_input, timeout):
  • trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py

    r121577 r121816  
    113113                port_name = cls.determine_full_port_name(self._host, options, port_name)
    114114                return cls(self._host, port_name, options=options, **kwargs)
    115         raise NotImplementedError('unsupported port: %s' % port_name)
     115        raise NotImplementedError('unsupported platform: "%s"' % port_name)
    116116
    117117    def all_port_names(self):
  • trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py

    r121507 r121816  
    3838
    3939from webkitpy.common.host import Host
    40 from webkitpy.layout_tests.controllers.manager import Manager
     40from webkitpy.common.system import stack_utils
     41from webkitpy.layout_tests.controllers.manager import Manager, WorkerException, TestRunInterruptedException
    4142from webkitpy.layout_tests.models import test_expectations
    4243from webkitpy.layout_tests.port import port_options
     
    4546
    4647_log = logging.getLogger(__name__)
     48
     49
     50# This mirrors what the shell normally does.
     51INTERRUPTED_EXIT_STATUS = signal.SIGINT + 128
     52
     53# This is a randomly chosen exit code that can be tested against to
     54# indicate that an unexpected exception occurred.
     55EXCEPTIONAL_EXIT_STATUS = 254
    4756
    4857
     
    120129        unexpected_result_count = manager.run()
    121130        _log.debug("Testing completed, Exit status: %d" % unexpected_result_count)
     131    except Exception:
     132        exception_type, exception_value, exception_traceback = sys.exc_info()
     133        if exception_type not in (KeyboardInterrupt, TestRunInterruptedException, WorkerException):
     134            stack_utils.log_traceback(_log.error, exception_traceback)
     135        raise
    122136    finally:
    123137        printer.cleanup()
     
    434448
    435449
    436 def main():
    437     options, args = parse_args()
     450def main(argv=None):
     451    options, args = parse_args(argv)
    438452    if options.platform and 'test' in options.platform:
    439453        # It's a bit lame to import mocks into real code, but this allows the user
     
    444458    else:
    445459        host = Host()
    446     port = host.port_factory.get(options.platform, options)
     460
     461    try:
     462        port = host.port_factory.get(options.platform, options)
     463    except NotImplementedError, e:
     464        # FIXME: is this the best way to handle unsupported port names?
     465        print >> sys.stderr, str(e)
     466        return EXCEPTIONAL_EXIT_STATUS
     467
    447468    logging.getLogger().setLevel(logging.DEBUG if options.verbose else logging.INFO)
    448469    return run(port, options, args)
     
    452473    try:
    453474        sys.exit(main())
    454     except KeyboardInterrupt:
    455         # This mirrors what the shell normally does.
    456         INTERRUPTED_EXIT_STATUS = signal.SIGINT + 128
    457         sys.exit(INTERRUPTED_EXIT_STATUS)
    458     except Exception:
    459         # This is a randomly chosen exit code that can be tested against to
    460         # indicate that an unexpected exception occurred.
    461         EXCEPTIONAL_EXIT_STATUS = 254
     475    except Exception, e:
     476        if e.__class__ in (KeyboardInterrupt, TestRunInterruptedException):
     477            sys.exit(INTERRUPTED_EXIT_STATUS)
    462478        sys.exit(EXCEPTIONAL_EXIT_STATUS)
  • trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py

    r121812 r121816  
    905905        self.assertEquals(full_results['has_pretty_patch'], False)
    906906
     907    def test_unsupported_platform(self):
     908        oc = outputcapture.OutputCapture()
     909        try:
     910            oc.capture_output()
     911            res = run_webkit_tests.main(['--platform', 'foo'])
     912        finally:
     913            stdout, stderr, logs = oc.restore_output()
     914
     915        self.assertEquals(res, run_webkit_tests.EXCEPTIONAL_EXIT_STATUS)
     916        self.assertEquals(stdout, '')
     917        self.assertTrue('unsupported platform' in stderr)
     918
     919        # This is empty because we don't even get a chance to configure the logger before failing.
     920        self.assertEquals(logs, '')
    907921
    908922class EndToEndTest(unittest.TestCase):
Note: See TracChangeset for help on using the changeset viewer.