⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278454 in webkit


Ignore:
Timestamp:
Jun 4, 2021, 7:04:35 AM (5 years ago)
Author:
Jonathan Bedard
Message:

[run-webkit-tests] Use webkitcorepy's TaskPool
https://bugs.webkit.org/show_bug.cgi?id=226234
<rdar://problem/78471695>

Reviewed by Dewei Zhu.

  • Scripts/run-webkit-tests: Stop using multiprocessing_bootstrap.
  • Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py:

(setup_shard): Run setup in Worker process.
(handle_started_test): Notify parent process that a test has started.
(run_shard): Run test shard in Worker process.
(handle_finished_test): Notify parent process that a test has finished.
(teardown_shard): Teardown worker process metadata.
(LayoutTestRunner.init): Make printer public.
(LayoutTestRunner.run_tests): Use TaskPool to spawn multiple workers.
(LayoutTestRunner.update_summary_with_result): Renamed from
_update_summary_with_result, strip unused arguments.
(LayoutTestRunner._annotate_results_with_additional_failures): Strip
unused arguments.
(LayoutTestRunner.start_servers): Make printer public.
(LayoutTestRunner.stop_servers): Ditto.
(Worker.setup): Instantiate singleton worker.
(Worker.teardown): Teardown singleton worker.
(Worker.init): Pass port object, remove unused variable.
(Worker.run_tests): Use TaskPool process name.
(Worker.stop): Ditto.
(Worker._kill_driver): Use port options, use TaskPool process name.
(Worker._run_test_with_or_without_timeout): Ditto.
(Worker._clean_up_after_test): Use TaskPool process name.
(Worker._run_test_in_another_thread): Ditto.
(Worker._run_test_in_this_thread): Ditto.
(Worker._run_single_test): Use port options.
(LayoutTestRunner._worker_factory): Deleted.
(LayoutTestRunner._handle_did_spawn_worker): Deleted.
(LayoutTestRunner._update_summary_with_result): Deleted.
(LayoutTestRunner.handle): Deleted.
(LayoutTestRunner._handle_started_test): Deleted.
(LayoutTestRunner._handle_finished_test): Deleted.
(LayoutTestRunner._handle_finished_test_group): Deleted.
(Worker.del): Deleted.
(Worker.start): Deleted.
(Worker.handle): Deleted.
(Worker._run_test): Deleted.
(Worker._finished_test_group): Deleted.

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

(LayoutTestRunnerTests.test_update_summary_with_result): The runner keeps track of it's state.

  • Scripts/webkitpy/layout_tests/run_webkit_tests.py: Remove call to main.
  • Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py:

(RunTest.serial_test_basic): Run all tests in the same process.
(RunTest.test_hung_thread): Deleted.

  • Scripts/webkitpy/port/base.py:

(Port.worker_startup_delay_secs): Deleted.

  • Scripts/webkitpy/port/test.py:

(Port.worker_startup_delay_secs): Deleted.

Location:
trunk/Tools
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r278451 r278454  
     12021-06-04  Jonathan Bedard  <jbedard@apple.com>
     2
     3        [run-webkit-tests] Use webkitcorepy's TaskPool
     4        https://bugs.webkit.org/show_bug.cgi?id=226234
     5        <rdar://problem/78471695>
     6
     7        Reviewed by Dewei Zhu.
     8
     9        * Scripts/run-webkit-tests: Stop using multiprocessing_bootstrap.
     10        * Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py:
     11        (setup_shard): Run setup in Worker process.
     12        (handle_started_test): Notify parent process that a test has started.
     13        (run_shard): Run test shard in Worker process.
     14        (handle_finished_test): Notify parent process that a test has finished.
     15        (teardown_shard): Teardown worker process metadata.
     16        (LayoutTestRunner.__init__): Make printer public.
     17        (LayoutTestRunner.run_tests): Use TaskPool to spawn multiple workers.
     18        (LayoutTestRunner.update_summary_with_result): Renamed from
     19        _update_summary_with_result, strip unused arguments.
     20        (LayoutTestRunner._annotate_results_with_additional_failures): Strip
     21        unused arguments.
     22        (LayoutTestRunner.start_servers): Make printer public.
     23        (LayoutTestRunner.stop_servers): Ditto.
     24        (Worker.setup): Instantiate singleton worker.
     25        (Worker.teardown): Teardown singleton worker.
     26        (Worker.__init__): Pass port object, remove unused variable.
     27        (Worker.run_tests): Use TaskPool process name.
     28        (Worker.stop): Ditto.
     29        (Worker._kill_driver): Use port options, use TaskPool process name.
     30        (Worker._run_test_with_or_without_timeout): Ditto.
     31        (Worker._clean_up_after_test): Use TaskPool process name.
     32        (Worker._run_test_in_another_thread): Ditto.
     33        (Worker._run_test_in_this_thread): Ditto.
     34        (Worker._run_single_test): Use port options.
     35        (LayoutTestRunner._worker_factory): Deleted.
     36        (LayoutTestRunner._handle_did_spawn_worker): Deleted.
     37        (LayoutTestRunner._update_summary_with_result): Deleted.
     38        (LayoutTestRunner.handle): Deleted.
     39        (LayoutTestRunner._handle_started_test): Deleted.
     40        (LayoutTestRunner._handle_finished_test): Deleted.
     41        (LayoutTestRunner._handle_finished_test_group): Deleted.
     42        (Worker.__del__): Deleted.
     43        (Worker.start): Deleted.
     44        (Worker.handle): Deleted.
     45        (Worker._run_test): Deleted.
     46        (Worker._finished_test_group): Deleted.
     47        * Scripts/webkitpy/layout_tests/controllers/layout_test_runner_unittest.py:
     48        (LayoutTestRunnerTests.test_update_summary_with_result): The runner keeps track of it's state.
     49        * Scripts/webkitpy/layout_tests/run_webkit_tests.py: Remove call to main.
     50        * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py:
     51        (RunTest.serial_test_basic): Run all tests in the same process.
     52        (RunTest.test_hung_thread): Deleted.
     53        * Scripts/webkitpy/port/base.py:
     54        (Port.worker_startup_delay_secs): Deleted.
     55        * Scripts/webkitpy/port/test.py:
     56        (Port.worker_startup_delay_secs): Deleted.
     57
    1582021-06-04  Carlos Garcia Campos  <cgarcia@igalia.com>
    259
  • trunk/Tools/Scripts/run-webkit-tests

    r273384 r278454  
    3333import sys
    3434
    35 from webkitpy.common import multiprocessing_bootstrap
     35from webkitpy.layout_tests.run_webkit_tests import main
    3636
    3737if sys.platform.startswith('linux'):
     
    4343    flatpakutils.run_in_sandbox_if_available(sys.argv)
    4444
    45 multiprocessing_bootstrap.run('webkitpy', 'layout_tests', 'run_webkit_tests.py')
     45if __name__ == '__main__':
     46    sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py

    r277781 r278454  
    3333
    3434from webkitcorepy.string_utils import pluralize
     35from webkitcorepy import TaskPool
    3536
    3637from webkitpy.common import message_pool
    3738from webkitpy.common.iteration_compatibility import iteritems
     39from webkitpy.common.interrupt_debugging import log_stack_trace_on_signal
    3840from webkitpy.layout_tests.controllers import single_test_runner
    3941from webkitpy.layout_tests.models.test_run_results import TestRunResults
     
    4850TestExpectations = test_expectations.TestExpectations
    4951
    50 # Export this so callers don't need to know about message pools.
    51 WorkerException = message_pool.WorkerException
     52
     53def setup_shard(port=None, results_directory=None, devices=None, retrying=False):
     54    if devices and getattr(port, 'DEVICE_MANAGER', None):
     55        port.DEVICE_MANAGER.AVAILABLE_DEVICES = devices.get('available_devices', [])
     56        port.DEVICE_MANAGER.INITIALIZED_DEVICES = devices.get('initialized_devices', None)
     57
     58    if retrying:
     59        results_directory = port.host.filesystem.join(results_directory, 'retries')
     60        port.host.filesystem.maybe_make_directory(results_directory)
     61
     62    stack_trace_path = port.host.filesystem.join(results_directory, 'python_stack_trace.txt')
     63    log_stack_trace_on_signal('SIGTERM', output_file=stack_trace_path)
     64    log_stack_trace_on_signal('SIGINT', output_file=stack_trace_path)
     65
     66    port.did_spawn_worker(int((TaskPool.Process.name).split('/')[-1]))
     67    return Worker.setup(port=port, results_directory=results_directory)
     68
     69
     70def handle_started_test(worker, name):
     71    if LayoutTestRunner.instance:
     72        LayoutTestRunner.instance.printer.print_started_test(name)
     73
     74
     75def run_shard(shard):
     76    return Worker.instance.run_tests(shard)
     77
     78
     79def handle_finished_test(worker, result):
     80    if LayoutTestRunner.instance:
     81        LayoutTestRunner.instance.update_summary_with_result(result)
     82
     83
     84def teardown_shard():
     85    return Worker.teardown()
    5286
    5387
     
    6498
    6599class LayoutTestRunner(object):
     100    instance = None
     101
    66102    def __init__(self, options, port, printer, results_directory, needs_http=False, needs_websockets=False, needs_web_platform_test_server=False):
    67103        self._options = options
    68104        self._port = port
    69         self._printer = printer
     105        self.printer = printer
    70106        self._results_directory = results_directory
    71107        self._needs_http = needs_http
     
    101137        run_results = TestRunResults(self._expectations, len(test_inputs))
    102138        self._current_run_results = run_results
    103         self._printer.num_tests = len(test_inputs)
    104         self._printer.num_started = 0
     139        self.printer.num_tests = len(test_inputs)
     140        self.printer.num_started = 0
    105141
    106142        if not retrying:
    107             self._printer.print_expected(run_results, self._expectations.model().get_tests_with_result_type)
    108 
    109         self._printer.write_update('Sharding tests ...')
     143            self.printer.print_expected(run_results, self._expectations.model().get_tests_with_result_type)
     144
     145        self.printer.write_update('Sharding tests ...')
    110146        all_shards = self._sharder.shard_tests(test_inputs, int(self._options.child_processes), self._options.fully_parallel)
    111147
    112         self._printer.print_workers_and_shards(num_workers, len(all_shards))
     148        num_workers = min(num_workers, len(all_shards))
     149        self.printer.print_workers_and_shards(num_workers, len(all_shards))
    113150
    114151        if self._options.dry_run:
    115152            return run_results
    116153
    117         self._printer.write_update('Starting %s ...' % pluralize(num_workers, "worker"))
     154        self.printer.write_update('Starting {} ...'.format(pluralize(num_workers, "worker")))
     155
     156        devices = None
     157        if getattr(self._port, 'DEVICE_MANAGER', None):
     158            devices = dict(
     159                available_devices=self._port.DEVICE_MANAGER.AVAILABLE_DEVICES,
     160                initialized_devices=self._port.DEVICE_MANAGER.INITIALIZED_DEVICES,
     161            )
    118162
    119163        try:
    120             with message_pool.get(self, self._worker_factory, num_workers, self._port.worker_startup_delay_secs(), self._port.host) as pool:
    121                 pool.run(('test_list', shard.name, shard.test_inputs) for shard in all_shards)
     164            LayoutTestRunner.instance = self
     165            with TaskPool(
     166                workers=num_workers,
     167                setup=setup_shard, setupkwargs=dict(
     168                    port=self._port,
     169                    devices=devices,
     170                    results_directory=self._results_directory,
     171                    retrying=self._retrying,
     172                ), teardown=teardown_shard,
     173            ) as pool:
     174                for shard in all_shards:
     175                    pool.do(
     176                        run_shard, shard,
     177                        callback=lambda value: self._annotate_results_with_additional_failures(value),
     178                    )
     179                pool.wait()
     180
    122181        except TestRunInterruptedException as e:
    123182            _log.warning(e.reason)
    124183            run_results.interrupted = True
    125184        except KeyboardInterrupt:
    126             self._printer.flush()
    127             self._printer.writeln('Interrupted, exiting ...')
     185            self.printer.flush()
     186            self.printer.writeln('Interrupted, exiting ...')
    128187            run_results.keyboard_interrupted = True
    129188        except Exception as e:
    130             _log.debug('%s("%s") raised, exiting' % (e.__class__.__name__, str(e)))
     189            _log.debug('{}("{}") raised, exiting'.format(e.__class__.__name__, str(e)))
    131190            raise
     191        finally:
     192            LayoutTestRunner.instance = None
    132193
    133194        return run_results
    134 
    135     def _worker_factory(self, worker_connection):
    136         results_directory = self._results_directory
    137         if self._retrying:
    138             self._filesystem.maybe_make_directory(self._filesystem.join(self._results_directory, 'retries'))
    139             results_directory = self._filesystem.join(self._results_directory, 'retries')
    140         return Worker(worker_connection, results_directory, self._options)
    141 
    142     def _handle_did_spawn_worker(self, worker_number):
    143         self._port.did_spawn_worker(worker_number)
    144195
    145196    def _mark_interrupted_tests_as_skipped(self, run_results):
     
    173224            "Exiting early after %d crashes and %d timeouts." % (run_results.unexpected_crashes, run_results.unexpected_timeouts))
    174225
    175     def _update_summary_with_result(self, run_results, result):
     226    def update_summary_with_result(self, result):
    176227        if result.type == test_expectations.SKIP:
    177228            exp_str = got_str = 'SKIP'
     
    183234            got_str = self._expectations.model().expectation_to_string(result.type)
    184235
    185         run_results.add(result, expected)
    186 
    187         self._printer.print_finished_test(result, expected, exp_str, got_str)
    188 
    189         self._interrupt_if_at_failure_limits(run_results)
    190 
    191     def _annotate_results_with_additional_failures(self, run_results, results):
     236        self._current_run_results.add(result, expected)
     237
     238        self.printer.print_finished_test(result, expected, exp_str, got_str)
     239
     240        self._interrupt_if_at_failure_limits(self._current_run_results)
     241
     242    def _annotate_results_with_additional_failures(self, results):
    192243        for new_result in results:
    193             existing_result = run_results.results_by_name.get(new_result.test_name)
     244            existing_result = self._current_run_results.results_by_name.get(new_result.test_name)
    194245            # When running a chunk (--run-chunk), results_by_name contains all the tests, but (confusingly) all_tests only contains those in the chunk that was run,
    195246            # and we don't want to modify the results of a test that didn't run. existing_result.test_number is only non-None for tests that ran.
     
    203254                        TestExpectations.EXPECTATION_DESCRIPTION[existing_result.type], 'expected' if was_expected else 'unexpected',
    204255                        TestExpectations.EXPECTATION_DESCRIPTION[new_result.type], 'expected' if now_expected else 'unexpected'))
    205                 run_results.change_result_to_failure(existing_result, new_result, was_expected, now_expected)
     256                self._current_run_results.change_result_to_failure(existing_result, new_result, was_expected, now_expected)
    206257
    207258    def start_servers(self):
    208259        if self._needs_http and not self._did_start_http_server and not self._port.is_http_server_running():
    209             self._printer.write_update('Starting HTTP server ...')
     260            self.printer.write_update('Starting HTTP server ...')
    210261            self._port.start_http_server()
    211262            self._did_start_http_server = True
    212263        if self._needs_websockets and not self._did_start_websocket_server and not self._port.is_websocket_server_running():
    213             self._printer.write_update('Starting WebSocket server ...')
     264            self.printer.write_update('Starting WebSocket server ...')
    214265            self._port.start_websocket_server()
    215266            self._did_start_websocket_server = True
    216267        if self._needs_web_platform_test_server and not self._did_start_wpt_server and not self._port.is_wpt_server_running():
    217             self._printer.write_update('Starting Web Platform Test server ...')
     268            self.printer.write_update('Starting Web Platform Test server ...')
    218269            self._port.start_web_platform_test_server()
    219270            self._did_start_wpt_server = True
     
    221272    def stop_servers(self):
    222273        if self._did_start_http_server:
    223             self._printer.write_update('Stopping HTTP server ...')
     274            self.printer.write_update('Stopping HTTP server ...')
    224275            self._port.stop_http_server()
    225276            self._did_start_http_server = False
    226277        if self._did_start_websocket_server:
    227             self._printer.write_update('Stopping WebSocket server ...')
     278            self.printer.write_update('Stopping WebSocket server ...')
    228279            self._port.stop_websocket_server()
    229280            self._did_start_websocket_server = False
    230281        if self._did_start_wpt_server:
    231             self._printer.write_update('Stopping Web Platform Test server ...')
     282            self.printer.write_update('Stopping Web Platform Test server ...')
    232283            self._port.stop_web_platform_test_server()
    233284            self._did_start_wpt_server = False
    234285
    235     def handle(self, name, source, *args):
    236         method = getattr(self, '_handle_' + name)
    237         if method:
    238             return method(source, *args)
    239         raise AssertionError('unknown message %s received from %s, args=%s' % (name, source, repr(args)))
    240 
    241     def _handle_started_test(self, worker_name, test_input, test_timeout_sec):
    242         self._printer.print_started_test(test_input.test_name)
    243 
    244     def _handle_finished_test(self, worker_name, result, log_messages=[]):
    245         self._update_summary_with_result(self._current_run_results, result)
    246 
    247     def _handle_finished_test_group(self, worker_name, overlay_results, log_messages=[]):
    248         self._annotate_results_with_additional_failures(self._current_run_results, overlay_results)
    249 
    250286
    251287class Worker(object):
    252     def __init__(self, caller, results_directory, options):
    253         self._caller = caller
    254         self._worker_number = caller.worker_number
    255         self._name = caller.name
     288    instance = None
     289
     290    @classmethod
     291    def setup(cls, port=None, results_directory=None):
     292        cls.instance = cls(port=port, results_directory=results_directory)
     293
     294    @classmethod
     295    def teardown(cls):
     296        if cls.instance:
     297            cls.instance.stop()
     298        cls.instance = None
     299
     300    def __init__(self, port, results_directory):
     301        self._port = port
    256302        self._results_directory = results_directory
    257         self._options = options
    258 
    259         # The remaining fields are initialized in start()
    260         self._host = None
    261         self._port = None
    262         self._batch_size = None
    263         self._batch_count = None
    264         self._filesystem = None
     303
     304        self._num_tests = 0
     305        self._batch_count = 0
    265306        self._driver = None
    266         self._num_tests = 0
    267 
    268     def __del__(self):
    269         self.stop()
    270 
    271     def start(self):
    272         """This method is called when the object is starting to be used and it is safe
    273         for the object to create state that does not need to be pickled (usually this means
    274         it is called in a child process)."""
    275         self._host = self._caller.host
    276         self._filesystem = self._host.filesystem
    277         self._port = self._host.port_factory.get(self._options.platform, self._options)
    278 
    279         self._batch_count = 0
    280         self._batch_size = self._options.batch_size or 0
    281 
    282     def handle(self, name, source, test_list_name, test_inputs):
    283         assert name == 'test_list'
    284         for test_input in test_inputs:
    285             self._run_test(test_input, test_list_name)
    286 
    287         self._finished_test_group(test_inputs)
    288 
    289     def _run_test(self, test_input, shard_name):
     307        self._batch_size = self._port.get_option('batch_size') or 0
     308
     309    def run_tests(self, shard):
     310        for input in shard.test_inputs:
     311            if not TaskPool.Process.working:
     312                break
     313            Worker.instance.run_test(input, shard.name)
     314
     315        _log.debug('{} finished test group'.format(TaskPool.Process.name))
     316
     317        if self._driver and self._driver.has_crashed():
     318            self._kill_driver()
     319
     320        additional_results = []
     321        if not self._port.get_option('run_singly'):
     322            additional_results = self._do_post_tests_work(self._driver)
     323        return additional_results
     324
     325    def run_test(self, test_input, shard_name):
    290326        self._batch_count += 1
    291327
    292328        stop_when_done = False
    293         if self._batch_size > 0 and self._batch_count >= self._batch_size:
     329        if 0 < self._batch_size <= self._batch_count:
    294330            self._batch_count = 0
    295331            stop_when_done = True
     
    297333        test_timeout_sec = self._timeout(test_input)
    298334        start = time.time()
    299         self._caller.post('started_test', test_input, test_timeout_sec)
     335
     336        TaskPool.Process.queue.send(TaskPool.Task(
     337            handle_started_test, None, TaskPool.Process.name,
     338            test_input.test_name,
     339        ))
    300340
    301341        result = self._run_test_with_or_without_timeout(test_input, test_timeout_sec, stop_when_done)
    302342        result.shard_name = shard_name
    303         result.worker_name = self._name
     343        result.worker_name = TaskPool.Process.name
    304344        result.total_run_time = time.time() - start
    305345        result.test_number = self._num_tests
    306346        self._num_tests += 1
    307347
    308         self._caller.post('finished_test', result)
     348        TaskPool.Process.queue.send(TaskPool.Task(
     349            handle_finished_test, None, TaskPool.Process.name,
     350            result,
     351        ))
    309352
    310353        self._clean_up_after_test(test_input, result)
     
    321364        return additional_results
    322365
    323     def _finished_test_group(self, test_inputs):
    324         _log.debug("%s finished test group" % self._name)
    325 
    326         if self._driver and self._driver.has_crashed():
    327             self._kill_driver()
    328 
    329         additional_results = []
    330         if not self._options.run_singly:
    331             additional_results = self._do_post_tests_work(self._driver)
    332 
    333         self._caller.post('finished_test_group', additional_results)
    334 
    335366    def stop(self):
    336         _log.debug("%s cleaning up" % self._name)
     367        _log.debug('{} cleaning up'.format(TaskPool.Process.name))
    337368        self._kill_driver()
    338369
     
    346377        # string value in milliseconds to a float for Python.
    347378        driver_timeout_sec = 3.0 * float(test_input.timeout) / 1000.0
    348         if not self._options.run_singly:
     379        if not self._port.get_option('run_singly'):
    349380            return driver_timeout_sec
    350381
     
    359390        self._driver = None
    360391        if driver:
    361             _log.debug("%s killing driver" % self._name)
     392            _log.debug('{} killing driver'.format(TaskPool.Process.name))
    362393            driver.stop()
    363394
    364395    def _run_test_with_or_without_timeout(self, test_input, timeout, stop_when_done):
    365         if self._options.run_singly:
     396        if self._port.get_option('run_singly'):
    366397            return self._run_test_in_another_thread(test_input, timeout, stop_when_done)
    367398        return self._run_test_in_this_thread(test_input, stop_when_done)
     
    378409
    379410            # Print the error message(s).
    380             _log.debug("%s %s failed:" % (self._name, test_name))
     411            _log.debug('{} {} failed:'.format(TaskPool.Process.name, test_name))
    381412            for f in result.failures:
    382                 _log.debug("%s  %s" % (self._name, f.message()))
     413                _log.debug('{}  {}'.format(TaskPool.Process.name, f.message()))
    383414        elif result.type == test_expectations.SKIP:
    384             _log.debug("%s %s skipped" % (self._name, test_name))
     415            _log.debug('{} {} skipped'.format(TaskPool.Process.name, test_name))
    385416        else:
    386             _log.debug("%s %s passed" % (self._name, test_name))
     417            _log.debug("{} {} passed".format(TaskPool.Process.name, test_name))
    387418
    388419    def _run_test_in_another_thread(self, test_input, thread_timeout_sec, stop_when_done):
     
    401432        worker = self
    402433
    403         driver = self._port.create_driver(self._worker_number, self._options.no_timeout)
     434        driver = self._port.create_driver(int((TaskPool.Process.name).split('/')[-1]), self._port.get_option('no_timeout'))
    404435
    405436        class SingleTestThread(threading.Thread):
     
    450481            self._kill_driver()
    451482        if not self._driver:
    452             self._driver = self._port.create_driver(self._worker_number, self._options.no_timeout)
     483            self._driver = self._port.create_driver(int((TaskPool.Process.name).split('/')[-1]), self._port.get_option('no_timeout'))
    453484        return self._run_single_test(self._driver, test_input, stop_when_done)
    454485
    455486    def _run_single_test(self, driver, test_input, stop_when_done):
    456         return single_test_runner.run_single_test(self._port, self._options, self._results_directory,
    457             self._name, driver, test_input, stop_when_done)
     487        return single_test_runner.run_single_test(
     488            self._port, self._port._options, self._results_directory,
     489            TaskPool.Process.name,
     490            driver, test_input, stop_when_done,
     491        )
    458492
    459493
  • trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner_unittest.py

    r277781 r278454  
    131131        runner._expectations = expectations
    132132
    133         run_results = TestRunResults(expectations, 1)
     133        runner._current_run_results = TestRunResults(expectations, 1)
    134134        result = TestResult(test, failures=[test_failures.FailureReftestMismatchDidNotOccur()], reftest_type=['!='])
    135         runner._update_summary_with_result(run_results, result)
    136         self.assertEqual(1, run_results.expected)
    137         self.assertEqual(0, run_results.unexpected)
    138 
    139         run_results = TestRunResults(expectations, 1)
     135        runner.update_summary_with_result(result)
     136        self.assertEqual(1, runner._current_run_results.expected)
     137        self.assertEqual(0, runner._current_run_results.unexpected)
     138
     139        runner._current_run_results = TestRunResults(expectations, 1)
    140140        result = TestResult(test, failures=[], reftest_type=['=='])
    141         runner._update_summary_with_result(run_results, result)
    142         self.assertEqual(0, run_results.expected)
    143         self.assertEqual(1, run_results.unexpected)
    144 
    145         run_results = TestRunResults(expectations, 1)
     141        runner.update_summary_with_result(result)
     142        self.assertEqual(0, runner._current_run_results.expected)
     143        self.assertEqual(1, runner._current_run_results.unexpected)
     144
     145        runner._current_run_results = TestRunResults(expectations, 1)
    146146        result = TestResult(leak_test, failures=[])
    147         runner._update_summary_with_result(run_results, result)
    148         self.assertEqual(1, run_results.expected)
    149         self.assertEqual(0, run_results.unexpected)
     147        runner.update_summary_with_result(result)
     148        self.assertEqual(1, runner._current_run_results.expected)
     149        self.assertEqual(0, runner._current_run_results.unexpected)
    150150
    151151    def test_servers_started(self):
  • trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py

    r278184 r278454  
    3333import optparse
    3434import os
    35 import signal
    36 import sys
    3735import traceback
    3836
     
    492490    finally:
    493491        printer.cleanup()
    494 
    495 if __name__ == '__main__':
    496     sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
  • trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py

    r278040 r278454  
    188188        self.assertEqual(details.initial_results.expected_skips, test.TOTAL_SKIPS)
    189189        self.assertEqual(len(details.initial_results.unexpected_results_by_name), test.UNEXPECTED_PASSES + test.UNEXPECTED_FAILURES)
    190         self.assertEqual(details.exit_code, test.UNEXPECTED_FAILURES)
     190        self.assertEqual(details.exit_code, test.UNEXPECTED_FAILURES - 1)  # failures/expected/hang.html actually passes when run in the same process
    191191        self.assertEqual(details.retry_results.total, test.TOTAL_RETRIES)
    192192
     
    255255        details, _, _ = logging_run(['--full-results-html'])
    256256        self.assertEqual(details.exit_code, 0)
    257 
    258     def test_hung_thread(self):
    259         details, err, _ = logging_run(['--run-singly', '--time-out-ms=50', 'failures/expected/hang.html'], tests_included=True)
    260         # Note that hang.html is marked as WontFix and all WontFix tests are
    261         # expected to Pass, so that actually running them generates an "unexpected" error.
    262         self.assertEqual(details.exit_code, 1)
    263         self.assertNotEmpty(err)
    264257
    265258    def test_keyboard_interrupt(self):
  • trunk/Tools/Scripts/webkitpy/port/base.py

    r278332 r278454  
    184184        return [None]
    185185
    186     def worker_startup_delay_secs(self):
    187         # FIXME: If we start workers up too quickly, DumpRenderTree appears
    188         # to thrash on something and time out its first few tests. Until
    189         # we can figure out what's going on, sleep a bit in between
    190         # workers. See https://bugs.webkit.org/show_bug.cgi?id=79147 .
    191         return 0.1
    192 
    193186    def baseline_path(self):
    194187        """Return the absolute path to the directory to store new baselines in for this port."""
  • trunk/Tools/Scripts/webkitpy/port/test.py

    r270954 r278454  
    394394        return 1
    395395
    396     def worker_startup_delay_secs(self):
    397         return 0
    398 
    399396    def check_build(self):
    400397        return True
Note: See TracChangeset for help on using the changeset viewer.