Hammer on that run_tests.py thing again.
[python_utils.git] / tests / run_tests.py
index 9dc067782e7d667d25651d86f018cc89d5389499..f1266e0962cfb44027c3c0cfa2a5a0a98354bf49 100755 (executable)
@@ -22,6 +22,7 @@ import config
 import exec_utils
 import file_utils
 import parallelize as par
+import smart_future
 import text_utils
 import thread_utils
 
@@ -151,17 +152,24 @@ class TemplatedTestRunner(TestRunner, ABC):
                 logger.error('Thread %s saw abnormal results; exiting.', self.get_name())
                 raise Exception("Kill myself!")
 
-    def status_report(self, running: List[Any], done: List[Any]):
+    def status_report(self, started: int, result: TestResults):
         """Periodically called to report current status."""
 
-        total = len(running) + len(done)
+        finished = (
+            len(self.test_results.tests_succeeded)
+            + len(self.test_results.tests_failed)
+            + len(self.test_results.tests_timed_out)
+        )
+        running = started - finished
+        finished_percent = finished / started * 100.0
         logging.info(
-            '%s: %d/%d in flight; %d/%d completed.',
+            '%s: %d/%d in flight; %d/%d finished (%.1f%%).',
             self.get_name(),
-            len(running),
-            total,
-            len(done),
-            total,
+            running,
+            started,
+            finished,
+            started,
+            finished_percent,
         )
 
     def persist_output(self, test_name: str, message: str, output: str) -> None:
@@ -198,7 +206,7 @@ class TemplatedTestRunner(TestRunner, ABC):
             logger.debug(
                 '%s: %s output when it timed out: %s', self.get_name(), test_name, e.output
             )
-            self.persist_output(test_name, msg, e.output)
+            self.persist_output(test_name, msg, e.output.decode('utf-8'))
             return TestResults(
                 test_name,
                 [test_name],
@@ -210,7 +218,7 @@ class TemplatedTestRunner(TestRunner, ABC):
             msg = f'{self.get_name()}: {test_name} ({cmdline}) failed; exit code {e.returncode}'
             logger.error(msg)
             logger.debug('%s: %s output when it failed: %s', self.get_name(), test_name, e.output)
-            self.persist_output(test_name, msg, e.output)
+            self.persist_output(test_name, msg, e.output.decide('utf-8'))
             return TestResults(
                 test_name,
                 [test_name],
@@ -223,26 +231,18 @@ class TemplatedTestRunner(TestRunner, ABC):
     def begin(self, params: TestingParameters) -> TestResults:
         logger.debug('Thread %s started.', self.get_name())
         interesting_tests = self.identify_tests()
+
         running: List[Any] = []
-        done: List[Any] = []
         for test in interesting_tests:
             running.append(self.run_test(test))
+        started = len(running)
 
-        while len(running) > 0:
-            self.status_report(running, done)
+        for future in smart_future.wait_any(running):
             self.check_for_abort()
-            newly_finished = []
-            for fut in running:
-                if fut.is_ready():
-                    newly_finished.append(fut)
-                    result = fut._resolve()
-                    logger.debug('Test %s finished.', result.name)
-                    self.test_results += result
-
-            for fut in newly_finished:
-                running.remove(fut)
-                done.append(fut)
-            time.sleep(1.0)
+            result = future._resolve()
+            self.status_report(started, result)
+            logger.debug('Test %s finished.', result.name)
+            self.test_results += result
 
         logger.debug('Thread %s finished.', self.get_name())
         return self.test_results
@@ -253,7 +253,7 @@ class UnittestTestRunner(TemplatedTestRunner):
 
     @overrides
     def get_name(self) -> str:
-        return "UnittestTestRunner"
+        return "Unittests"
 
     @overrides
     def identify_tests(self) -> List[str]:
@@ -273,7 +273,7 @@ class DoctestTestRunner(TemplatedTestRunner):
 
     @overrides
     def get_name(self) -> str:
-        return "DoctestTestRunner"
+        return "Doctests"
 
     @overrides
     def identify_tests(self) -> List[str]:
@@ -299,7 +299,7 @@ class IntegrationTestRunner(TemplatedTestRunner):
 
     @overrides
     def get_name(self) -> str:
-        return "IntegrationTestRunner"
+        return "Integration Tests"
 
     @overrides
     def identify_tests(self) -> List[str]: