test-webkitpy: use message pools
authordpranke@chromium.org <dpranke@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Jul 2012 19:35:14 +0000 (19:35 +0000)
committerdpranke@chromium.org <dpranke@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Jul 2012 19:35:14 +0000 (19:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91292

Reviewed by Ojan Vafai.

Restructure the test-running code to be message-driven and
use a MessagePool; note that this does not yet actually run the
tests in parallel.

Also clean up the unit tests so that the fake loader is passed
to the _Worker properly, and reduce a lot of the cut&pasted code
in the tests.

No functional changes; covered by existing tests.

* Scripts/webkitpy/test/printer.py:
(Printer.print_started_test):
(Printer.print_finished_test):
* Scripts/webkitpy/test/runner.py:
(Runner.__init__):
(Runner.run):
(Runner.handle):
(_Worker):
(_Worker.__init__):
(_Worker.handle):
* Scripts/webkitpy/test/runner_unittest.py:
(RunnerTest.assert_run):
(RunnerTest.test_regular):
(RunnerTest.test_verbose):
(RunnerTest.test_timing):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@122749 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/Scripts/webkitpy/test/printer.py
Tools/Scripts/webkitpy/test/runner.py
Tools/Scripts/webkitpy/test/runner_unittest.py

index 57eeb78..aeaae51 100644 (file)
@@ -1,3 +1,36 @@
+2012-07-16  Dirk Pranke  <dpranke@chromium.org>
+
+        test-webkitpy: use message pools
+        https://bugs.webkit.org/show_bug.cgi?id=91292
+
+        Reviewed by Ojan Vafai.
+
+        Restructure the test-running code to be message-driven and
+        use a MessagePool; note that this does not yet actually run the
+        tests in parallel.
+
+        Also clean up the unit tests so that the fake loader is passed
+        to the _Worker properly, and reduce a lot of the cut&pasted code
+        in the tests.
+
+        No functional changes; covered by existing tests.
+
+        * Scripts/webkitpy/test/printer.py:
+        (Printer.print_started_test):
+        (Printer.print_finished_test):
+        * Scripts/webkitpy/test/runner.py:
+        (Runner.__init__):
+        (Runner.run):
+        (Runner.handle):
+        (_Worker):
+        (_Worker.__init__):
+        (_Worker.handle):
+        * Scripts/webkitpy/test/runner_unittest.py:
+        (RunnerTest.assert_run):
+        (RunnerTest.test_regular):
+        (RunnerTest.test_verbose):
+        (RunnerTest.test_timing):
+
 2012-07-16  Simon Hausmann  <simon.hausmann@nokia.com>
 
         [Qt] Fix Qt5 module dependencies
index 77e28b8..1805978 100644 (file)
@@ -98,7 +98,7 @@ class Printer(object):
         if self.options.pass_through:
             outputcapture.OutputCapture.stream_wrapper = _CaptureAndPassThroughStream
 
-    def print_started_test(self, test_name):
+    def print_started_test(self, source, test_name):
         if self.options.verbose:
             self.stream.write(test_name)
 
index 9c95207..861f0b6 100644 (file)
@@ -26,6 +26,7 @@ import logging
 import time
 import unittest
 
+from webkitpy.common import message_pool
 
 _log = logging.getLogger(__name__)
 
@@ -35,6 +36,8 @@ class Runner(object):
         self.options = options
         self.printer = printer
         self.loader = loader
+        self.result = unittest.TestResult()
+        self.worker_factory = lambda caller: _Worker(caller, self.loader)
 
     def all_test_names(self, suite):
         names = []
@@ -48,28 +51,33 @@ class Runner(object):
     def run(self, suite):
         run_start_time = time.time()
         all_test_names = self.all_test_names(suite)
-        result = unittest.TestResult()
-        stop = run_start_time
-        for test_name in all_test_names:
-            self.printer.print_started_test(test_name)
-            num_failures = len(result.failures)
-            num_errors = len(result.errors)
 
-            start = time.time()
-            # FIXME: it's kinda lame that we re-load the test suites for each
-            # test, and this may slow things down, but this makes implementing
-            # the logging easy and will also allow us to parallelize nicely.
-            self.loader.loadTestsFromName(test_name, None).run(result)
-            stop = time.time()
+        with message_pool.get(self, self.worker_factory, 1) as pool:
+            pool.run(('test', test_name) for test_name in all_test_names)
+
+        self.printer.print_result(self.result, time.time() - run_start_time)
+        return self.result
+
+    def handle(self, message_name, source, test_name, delay=None, result=None):
+        if message_name == 'started_test':
+            self.printer.print_started_test(source, test_name)
+            return
 
-            err = None
-            failure = None
-            if len(result.failures) > num_failures:
-                failure = result.failures[num_failures][1]
-            elif len(result.errors) > num_errors:
-                err = result.errors[num_errors][1]
-            self.printer.print_finished_test(result, test_name, stop - start, failure, err)
+        self.result.testsRun += 1
+        self.result.errors.extend(result.errors)
+        self.result.failures.extend(result.failures)
+        self.printer.print_finished_test(source, test_name, delay, result.failures, result.errors)
 
-        self.printer.print_result(result, stop - run_start_time)
 
-        return result
+class _Worker(object):
+    def __init__(self, caller, loader):
+        self._caller = caller
+        self._loader = loader
+
+    def handle(self, message_name, source, test_name):
+        assert message_name == 'test'
+        result = unittest.TestResult()
+        start = time.time()
+        self._caller.post('started_test', test_name)
+        self._loader.loadTestsFromName(test_name, None).run(result)
+        self._caller.post('finished_test', test_name, time.time() - start, result)
index 1cf0146..a4030a6 100644 (file)
@@ -26,7 +26,7 @@ import unittest
 
 from webkitpy.tool.mocktool import MockOptions
 from webkitpy.test.printer import Printer
-from webkitpy.test.runner import Runner
+from webkitpy.test.runner import Runner, _Worker
 
 
 class FakeModuleSuite(object):
@@ -69,44 +69,27 @@ class FakeLoader(object):
 
 
 class RunnerTest(unittest.TestCase):
-    def test_regular(self):
-        options = MockOptions(verbose=0, timing=False)
+    def assert_run(self, options):
         stream = StringIO.StringIO()
         loader = FakeLoader(('test1 (Foo)', '.', ''),
                             ('test2 (Foo)', 'F', 'test2\nfailed'),
                             ('test3 (Foo)', 'E', 'test3\nerred'))
-        result = Runner(Printer(stream, options), options, loader).run(loader.top_suite())
+        runner = Runner(Printer(stream, options), options, loader)
+        result = runner.run(loader.top_suite())
         self.assertFalse(result.wasSuccessful())
         self.assertEquals(result.testsRun, 3)
         self.assertEquals(len(result.failures), 1)
         self.assertEquals(len(result.errors), 1)
         # FIXME: check the output from the test
 
+    def test_regular(self):
+        self.assert_run(MockOptions(verbose=0, timing=False))
+
     def test_verbose(self):
-        options = MockOptions(verbose=1, timing=False)
-        stream = StringIO.StringIO()
-        loader = FakeLoader(('test1 (Foo)', '.', ''),
-                            ('test2 (Foo)', 'F', 'test2\nfailed'),
-                            ('test3 (Foo)', 'E', 'test3\nerred'))
-        result = Runner(Printer(stream, options), options, loader).run(loader.top_suite())
-        self.assertFalse(result.wasSuccessful())
-        self.assertEquals(result.testsRun, 3)
-        self.assertEquals(len(result.failures), 1)
-        self.assertEquals(len(result.errors), 1)
-        # FIXME: check the output from the test
+        self.assert_run(MockOptions(verbose=1, timing=False))
 
     def test_timing(self):
-        options = MockOptions(verbose=0, timing=True)
-        stream = StringIO.StringIO()
-        loader = FakeLoader(('test1 (Foo)', '.', ''),
-                            ('test2 (Foo)', 'F', 'test2\nfailed'),
-                            ('test3 (Foo)', 'E', 'test3\nerred'))
-        result = Runner(Printer(stream, options), options, loader).run(loader.top_suite())
-        self.assertFalse(result.wasSuccessful())
-        self.assertEquals(result.testsRun, 3)
-        self.assertEquals(len(result.failures), 1)
-        self.assertEquals(len(result.errors), 1)
-        # FIXME: check the output from the test
+        self.assert_run(MockOptions(verbose=0, timing=True))
 
 
 if __name__ == '__main__':