import exec_utils
import file_utils
import parallelize as par
+import smart_future
import text_utils
import thread_utils
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:
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],
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],
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
@overrides
def get_name(self) -> str:
- return "UnittestTestRunner"
+ return "Unittests"
@overrides
def identify_tests(self) -> List[str]:
@overrides
def get_name(self) -> str:
- return "DoctestTestRunner"
+ return "Doctests"
@overrides
def identify_tests(self) -> List[str]:
@overrides
def get_name(self) -> str:
- return "IntegrationTestRunner"
+ return "Integration Tests"
@overrides
def identify_tests(self) -> List[str]: