webkitpy: Notify parent process when a worker is spawned
[WebKit-https.git] / Tools / Scripts / webkitpy / test / runner.py
index f8f19b2..3c25a16 100644 (file)
 
 """code to actually run a list of python tests."""
 
-import logging
+import re
 import time
 import unittest
 
 from webkitpy.common import message_pool
 
-_log = logging.getLogger(__name__)
+_test_description = re.compile("(\w+) \(([\w.]+)\)")
+
+
+def unit_test_name(test):
+    m = _test_description.match(str(test))
+    return "%s.%s" % (m.group(2), m.group(1))
 
 
 class Runner(object):
-    def __init__(self, printer, options, loader):
-        self.options = options
+    def __init__(self, printer, loader):
         self.printer = printer
         self.loader = loader
-        self.result = unittest.TestResult()
+        self.tests_run = 0
+        self.errors = []
+        self.failures = []
         self.worker_factory = lambda caller: _Worker(caller, self.loader)
 
-    def all_test_names(self, suite):
-        names = []
-        if hasattr(suite, '_tests'):
-            for t in suite._tests:
-                names.extend(self.all_test_names(t))
-        else:
-            names.append(self.printer.test_name(suite))
-        return names
-
-    def run(self, suite):
-        run_start_time = time.time()
-        all_test_names = self.all_test_names(suite)
-
-        with message_pool.get(self, self.worker_factory, int(self.options.child_processes)) as pool:
-            pool.run(('test', test_name) for test_name in all_test_names)
+    def run(self, test_names, num_workers):
+        if not test_names:
+            return
+        num_workers = min(num_workers, len(test_names))
+        with message_pool.get(self, self.worker_factory, num_workers) as pool:
+            pool.run(('test', test_name) for test_name in test_names)
 
-        self.printer.print_result(self.result, time.time() - run_start_time)
-        return self.result
+    def handle(self, message_name, source, test_name=None, delay=None, failures=None, errors=None):
+        if message_name == 'did_spawn_worker':
+            return
 
-    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
 
-        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.tests_run += 1
+        if failures:
+            self.failures.append((test_name, failures))
+        if errors:
+            self.errors.append((test_name, errors))
+        self.printer.print_finished_test(source, test_name, delay, failures, errors)
 
 
 class _Worker(object):
@@ -79,5 +78,8 @@ class _Worker(object):
         result = unittest.TestResult()
         start = time.time()
         self._caller.post('started_test', test_name)
+
+        # We will need to rework this if a test_name results in multiple tests.
         self._loader.loadTestsFromName(test_name, None).run(result)
-        self._caller.post('finished_test', test_name, time.time() - start, result)
+        self._caller.post('finished_test', test_name, time.time() - start,
+            [failure[1] for failure in result.failures], [error[1] for error in result.errors])