588 def run(self, test: WorkflowTest):
589 self.logger.info("-----------------------------------------------------")
590 self.logger.info(f"Running {test.ID} FPE Check")
591
592 result = True
593 for step in test.steps:
594 log = test.validation_path / f"log.{step}"
595 fpes = {}
596 stack_traces = {}
597 with log.open() as file:
598 last_stack_trace = None
599 for line in file:
600 if "WARNING FPE" in line:
601 last_stack_trace = None
602 fpe = None
603 for part in reversed(line.split()):
604 if "[" in part:
606 break
607 if fpe:
608 if fpe in fpes:
609 fpes[fpe] += 1
610 else:
611 fpes[fpe] = 1
612 last_stack_trace = []
613 stack_traces[fpe] = last_stack_trace
614 elif "FPE stacktrace" in line and last_stack_trace is not None:
615 line = next(file)
616 last_stack_trace.append(line.strip()[9:])
617
618 if fpes.keys():
619 msgLvl = logging.WARNING if test.run in self.ignoreTestRuns or test.type in self.ignoreTestTypes or test.ID in self.ignoreTestIDs else logging.ERROR
620 result = False
621 self.logger.log(msgLvl, f" {step} validation test step FPEs")
622 for fpe, count in sorted(fpes.items(), key=lambda item: item[1]):
623 self.logger.log(msgLvl, f"{count:>5} {fpe}")
624 for fpe in fpes.keys():
625 self.logger.log(msgLvl, "-----------------------------------------------------")
626 self.logger.log(msgLvl, f" first stack trace for algorithm {fpe}:")
627 for line in stack_traces[fpe]:
628 self.logger.log(msgLvl, line)
629 self.logger.log(msgLvl, "-----------------------------------------------------")
630
631 if result:
632 self.logger.info("Passed!\n")
633 elif test.run in self.ignoreTestRuns or test.type in self.ignoreTestTypes or test.ID in self.ignoreTestIDs:
634 self.logger.warning("Failed!")
635 self.logger.warning("Check disabled due to irreproducibilities!\n")
636 result = True
637 else:
638 self.logger.
error(
"Failed!\n")
639
640 return result
std::string replace(std::string s, const std::string &s2, const std::string &s3)