test-webkitpy: use message pools
[WebKit-https.git] / Tools / Scripts / webkitpy / test / runner.py
1 # Copyright (C) 2012 Google, Inc.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1.  Redistributions of source code must retain the above copyright
7 #     notice, this list of conditions and the following disclaimer.
8 # 2.  Redistributions in binary form must reproduce the above copyright
9 #     notice, this list of conditions and the following disclaimer in the
10 #     documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23 """code to actually run a list of python tests."""
24
25 import logging
26 import time
27 import unittest
28
29 from webkitpy.common import message_pool
30
31 _log = logging.getLogger(__name__)
32
33
34 class Runner(object):
35     def __init__(self, printer, options, loader):
36         self.options = options
37         self.printer = printer
38         self.loader = loader
39         self.result = unittest.TestResult()
40         self.worker_factory = lambda caller: _Worker(caller, self.loader)
41
42     def all_test_names(self, suite):
43         names = []
44         if hasattr(suite, '_tests'):
45             for t in suite._tests:
46                 names.extend(self.all_test_names(t))
47         else:
48             names.append(self.printer.test_name(suite))
49         return names
50
51     def run(self, suite):
52         run_start_time = time.time()
53         all_test_names = self.all_test_names(suite)
54
55         with message_pool.get(self, self.worker_factory, 1) as pool:
56             pool.run(('test', test_name) for test_name in all_test_names)
57
58         self.printer.print_result(self.result, time.time() - run_start_time)
59         return self.result
60
61     def handle(self, message_name, source, test_name, delay=None, result=None):
62         if message_name == 'started_test':
63             self.printer.print_started_test(source, test_name)
64             return
65
66         self.result.testsRun += 1
67         self.result.errors.extend(result.errors)
68         self.result.failures.extend(result.failures)
69         self.printer.print_finished_test(source, test_name, delay, result.failures, result.errors)
70
71
72 class _Worker(object):
73     def __init__(self, caller, loader):
74         self._caller = caller
75         self._loader = loader
76
77     def handle(self, message_name, source, test_name):
78         assert message_name == 'test'
79         result = unittest.TestResult()
80         start = time.time()
81         self._caller.post('started_test', test_name)
82         self._loader.loadTestsFromName(test_name, None).run(result)
83         self._caller.post('finished_test', test_name, time.time() - start, result)