12fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# Copyright (C) 2011 Google Inc. All rights reserved.
22fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#
32fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# Redistribution and use in source and binary forms, with or without
42fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# modification, are permitted provided that the following conditions are
52fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# met:
62fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#
72fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#     * Redistributions of source code must retain the above copyright
82fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# notice, this list of conditions and the following disclaimer.
92fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#     * Redistributions in binary form must reproduce the above
102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# copyright notice, this list of conditions and the following disclaimer
112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# in the documentation and/or other materials provided with the
122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# distribution.
132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#     * Neither the name of Google Inc. nor the names of its
142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# contributors may be used to endorse or promote products derived from
152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# this software without specific prior written permission.
162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#
172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block"""Handle messages from the TestRunner and execute actual tests."""
302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
312fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockimport logging
322fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockimport sys
332fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockimport time
342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
352fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockfrom webkitpy.common.system import stack_utils
362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
372fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockfrom webkitpy.layout_tests.layout_package import manager_worker_broker
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochfrom webkitpy.layout_tests.layout_package import worker_mixin
392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block_log = logging.getLogger(__name__)
422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass Worker(manager_worker_broker.AbstractWorker, worker_mixin.WorkerMixin):
452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def __init__(self, worker_connection, worker_number, options):
462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._worker_connection = worker_connection
472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._worker_number = worker_number
482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._options = options
492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._name = 'worker/%d' % worker_number
502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._done = False
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        self._canceled = False
522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._port = None
532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def __del__(self):
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        self.cleanup()
5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def cancel(self):
5881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        """Attempt to abort processing (best effort)."""
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        self._canceled = True
602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def is_done(self):
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return self._done or self._canceled
632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def name(self):
652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return self._name
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def run(self, port):
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        self.safe_init(port)
692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        exception_msg = ""
712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        _log.debug("%s starting" % self._name)
722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        try:
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            self._worker_connection.run_message_loop()
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if not self.is_done():
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                raise AssertionError("%s: ran out of messages in worker queue."
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                     % self._name)
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        except KeyboardInterrupt:
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            exception_msg = ", interrupted"
8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        except:
8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            exception_msg = ", exception raised"
8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        finally:
8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            _log.debug("%s done%s" % (self._name, exception_msg))
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if exception_msg:
8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                exception_type, exception_value, exception_traceback = sys.exc_info()
8681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                stack_utils.log_traceback(_log.error, exception_traceback)
8781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                # FIXME: Figure out how to send a message with a traceback.
8881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                self._worker_connection.post_message('exception',
8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    (exception_type, exception_value, None))
9081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            self._worker_connection.post_message('done')
912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def handle_test_list(self, src, list_name, test_list):
9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if list_name == "tests_to_http_lock":
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            self.start_servers_with_lock()
952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        start_time = time.time()
972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        num_tests = 0
982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        for test_input in test_list:
992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            self._run_test(test_input)
1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            num_tests += 1
1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            self._worker_connection.yield_to_broker()
1022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        elapsed_time = time.time() - start_time
1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._worker_connection.post_message('finished_list', list_name, num_tests, elapsed_time)
1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if self._has_http_lock:
10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            self.stop_servers_with_lock()
1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def handle_stop(self, src):
1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._done = True
1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def _run_test(self, test_input):
11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        test_timeout_sec = self.timeout(test_input)
1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        start = time.time()
1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._worker_connection.post_message('started_test', test_input, test_timeout_sec)
1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        result = self.run_test_with_timeout(test_input, test_timeout_sec)
1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        elapsed_time = time.time() - start
1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._worker_connection.post_message('finished_test', result, elapsed_time)
12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        self.clean_up_after_test(test_input, result)
123