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