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
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."""
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."""
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],
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
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
'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()