def execute(self) -> None: """ Drives the case through its distinct phases Each phase is demarcated in the transcript. """ with ReportService.demarcate(self.name, IReport.Level.info, IReport.Patency.major, trail=False): ReportService.report('Description: {}'.format(self.description), timestamp=False) ReportService.report('Parameters: {}'.format(str(self._kwargs)), timestamp=False) with self.demarcate_phase(ITest.Phase.reserve.name): self.reserve() try: with self.demarcate_phase(ITest.Phase.prepare.name): self.prepare() with self.demarcate_phase(ITest.Phase.test.name): self.test() with self.demarcate_phase(ITest.Phase.audit.name): self.audit() with self.demarcate_phase(ITest.Phase.restore.name): self.restore() except Exception as exception: import traceback self.result.result = ITest.State.ABEND self.result.message = str( exception) + '\n\n' + traceback.format_exc() with self.demarcate_phase(ITest.Phase.report.name): self.report() with self.demarcate_phase(ITest.Phase.release.name): self.release()
def report(self, recurse: bool = True, indent: int = 0) -> None: """ Output the final result(s) to persistent I/O :param recurse: n/a but exists for polymorphism of the encompassing testable :param indent: amount to indent textual output to mirror the testable hierarchy """ message = 'STEP: {} | {} | {}'.format(self.description, self.state, self.message) message = ReportService.indent(message, indent) ReportService.report(message, IReport.Level.info, IReport.Patency.minor)
def report(self, recurse: bool = False, indent: int = 0) -> None: """ Report suite result. Only report to case level by default, since steps will be previously recorded. """ message = 'SUITE {}: {} | {} | {}'.format(self.test, self.description, self.state, self.message) message = ReportService.indent(message, indent) ReportService.report(message, IReport.Level.info, IReport.Patency.minor) super().report(recurse, indent)
def report(self, recurse: bool = True, indent: int = 0) -> None: """ Report case result. Recurse into flights by default to show hierarchy. """ message = 'CASE {}: {} | {} | {}'.format(self.test, self.description, self.state, self.message) message = ReportService.indent(message, indent) ReportService.report(message, IReport.Level.info, IReport.Patency.minor) if recurse: super().report(recurse, indent)
def flyer(self, name: str or None = None, description: str or None = None, state: ITest.State = ITest.State.UNTESTED, message: str or None = None) -> Flight: """ Context manager to run a flight's sequence of actions and verifications All flights need to be run within this context. Currently for recording / reporting but later for state/exception handling. :param name: Short name for reporting references :param description: Meaningful but short explanation of the step :param state: Initial state of the step, which will be updated accordingly :param message: Explanation of state """ if name is None: name = Flight.NAME with ReportService.demarcate("'{}' Flight".format(name), IReport.Level.info, IReport.Patency.minor): with Flight(name, description, state, message) as flight: try: yield flight # results can be updated anytime in context finally: self.record_result(flight.result)
def demarcate_phase(self, phase: str) -> None: """ Output wrapper for bookending any discreet phase of a test :param phase: textual name or short description """ message = '{} / {} phase'.format(self.name, phase) with ReportService.demarcate(message, IReport.Level.none, IReport.Patency.medium): yield
def execute(self) -> None: """ Iteratively runs the sequence of contained subsuites and cases Suites have less phases than cases since they are primarily just organizational """ with ReportService.demarcate(self.name, IReport.Level.info, IReport.Patency.major, trail=False): ReportService.report('Description: {}'.format(self.description), timestamp=False) ReportService.report('Parameters: {}'.format(str(self._kwargs)), timestamp=False) with self.demarcate_phase(ITest.Phase.test.name): self.test() with self.demarcate_phase(ITest.Phase.report.name): self.report()
def sleep(seconds, msg='Unspecified reason', delimiter=".", trailing=True, level=IReport.Level.none): seconds = float(seconds) if seconds > 0: # trick to limit seconds output to 3 decimal places, but also # strip trailing zeros. formatted_seconds = ("%.3f" % seconds).rstrip("0").rstrip(".") if msg is not None: msg = "Sleep %s second(s): %s" % (formatted_seconds, msg) ReportService.report(msg, level=level) while seconds > 0: interval = min(seconds, 1) time.sleep(interval) sys.stdout.write(delimiter) sys.stdout.flush() seconds -= interval if trailing: sys.stdout.write("\n")
def print_name(self): ReportService.report('Node name: {}'.format(self.name))