From: Scott Gasch Date: Fri, 3 Jun 2022 03:09:09 +0000 (-0700) Subject: One bugfix and some cosmetics. X-Git-Url: https://wannabe.guru.org/gitweb/?a=commitdiff_plain;h=19c9d04094b49b25826b875bf06e5e622f97e1d5;p=python_utils.git One bugfix and some cosmetics. --- diff --git a/tests/run_tests.py b/tests/run_tests.py index f1266e0..5162e23 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -12,7 +12,7 @@ import threading import time from abc import ABC, abstractmethod from dataclasses import dataclass -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Tuple from overrides import overrides @@ -116,12 +116,17 @@ class TestRunner(ABC, thread_utils.ThreadWithReturnValue): tests_failed=[], tests_timed_out=[], ) + self.tests_started = 0 @abstractmethod def get_name(self) -> str: """The name of this test collection.""" pass + def get_status(self) -> Tuple[int, TestResults]: + """Ask the TestRunner for its status.""" + return (self.tests_started, self.test_results) + @abstractmethod def begin(self, params: TestingParameters) -> TestResults: """Start execution.""" @@ -152,26 +157,6 @@ class TemplatedTestRunner(TestRunner, ABC): logger.error('Thread %s saw abnormal results; exiting.', self.get_name()) raise Exception("Kill myself!") - def status_report(self, started: int, result: TestResults): - """Periodically called to report current status.""" - - 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 finished (%.1f%%).', - self.get_name(), - running, - started, - finished, - started, - finished_percent, - ) - def persist_output(self, test_name: str, message: str, output: str) -> None: """Called to save the output of a test run.""" @@ -218,7 +203,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.decide('utf-8')) + self.persist_output(test_name, msg, e.output.decode('utf-8')) return TestResults( test_name, [test_name], @@ -235,12 +220,11 @@ class TemplatedTestRunner(TestRunner, ABC): running: List[Any] = [] for test in interesting_tests: running.append(self.run_test(test)) - started = len(running) + self.tests_started = len(running) for future in smart_future.wait_any(running): self.check_for_abort() result = future._resolve() - self.status_report(started, result) logger.debug('Test %s finished.', result.name) self.test_results += result @@ -383,6 +367,10 @@ def main() -> Optional[int]: results: Dict[str, TestResults] = {} while len(results) != len(threads): + started = 0 + done = 0 + failed = 0 + for thread in threads: if not thread.is_alive(): tid = thread.name @@ -395,7 +383,35 @@ def main() -> Optional[int]: 'Thread %s returned abnormal results; killing the others.', tid ) halt_event.set() - time.sleep(1.0) + else: + (s, tr) = thread.get_status() + started += s + failed += len(tr.tests_failed) + len(tr.tests_timed_out) + done += failed + len(tr.tests_succeeded) + + if started > 0: + percent_done = done / started + else: + percent_done = 0.0 + + if failed == 0: + color = ansi.fg('green') + else: + color = ansi.fg('red') + + if percent_done < 100.0: + print( + text_utils.bar_graph( + percent_done, + width=80, + fgcolor=color, + ), + end='\r', + flush=True, + ) + else: + print("Finished.\n") + time.sleep(0.5) if config.config['coverage']: code_coverage_report()