def _init_test(self, test_func): """ Initializes a test. Records outcome if the initialization fails. Records skip if the test is skipped. Saves the initialized test if it successfully initializes. """ test_init_outcome = cocotb.outcomes.capture(test_func, self._dut) if isinstance(test_init_outcome, cocotb.outcomes.Error): self.log.error("Failed to initialize test %s" % test_func.name, exc_info=True) self.xunit.add_testcase(name=test_func.name, classname=test_func.__module__, time="0.0", sim_time_ns="0.0", ratio_time="0.0") result_pass, sim_failed = self._score_test(test_func, test_init_outcome) # Save results self._store_test_result(test_func.__module__, test_func.__qualname__, result_pass, 0.0, 0.0, 0.0) if not result_pass: self.xunit.add_failure() self.failures += 1 # Fail if required if sim_failed: self.tear_down() raise SimFailure( "Test initialization caused a simulator failure. Shutting down." ) else: test = test_init_outcome.get() if test.skip: self.log.info("Skipping test %s" % test_func.name) self.xunit.add_testcase(name=test_func.name, classname=test.module, time="0.0", sim_time_ns="0.0", ratio_time="0.0") self.xunit.add_skipped() self.skipped += 1 self._store_test_result(test.module, test_func.name, None, 0.0, 0.0, 0.0) else: self._queue.append(test) self.ntests += 1
def _sim_event(level, message): """Function that can be called externally to signal an event.""" # SIM_INFO = 0 SIM_TEST_FAIL = 1 SIM_FAIL = 2 from cocotb.result import SimFailure if level is SIM_TEST_FAIL: scheduler.log.error("Failing test at simulator request") scheduler._finish_test(AssertionError(f"Failure from external source: {message}")) elif level is SIM_FAIL: # We simply return here as the simulator will exit # so no cleanup is needed msg = f"Failing test at simulator request before test run completion: {message}" scheduler.log.error(msg) scheduler._finish_scheduler(SimFailure(msg)) else: scheduler.log.error("Unsupported sim event")
def _sim_event(level, message): """Function that can be called externally to signal an event""" SIM_INFO = 0 SIM_TEST_FAIL = 1 SIM_FAIL = 2 from cocotb.result import TestFailure, SimFailure if level is SIM_TEST_FAIL: scheduler.log.error("Failing test at simulator request") scheduler.finish_test(TestFailure("Failure from external source: %s" % message)) elif level is SIM_FAIL: # We simply return here as the simulator will exit so no cleanup is needed scheduler.log.error("Failing test at simulator request before test run completion: %s" % message) scheduler.finish_scheduler(SimFailure("Failing test at simulator request before test run completion %s" % message)) else: scheduler.log.error("Unsupported sim event") return True
def tear_down(self): # fail remaining tests while True: test = self.next_test() if test is None: break self.xunit.add_testcase(name=test.funcname, classname=test.module, time=repr(0), sim_time_ns=repr(0), ratio_time=repr(0)) result_pass, _ = self._score_test( test, cocotb.outcomes.Error(SimFailure())) self._store_test_result(test.__module__, test.__name__, result_pass, 0, 0, 0) if not result_pass: self.xunit.add_failure() self.failures += 1 # Write out final log messages if self.failures: self.log.error("Failed %d out of %d tests (%d skipped)" % (self.failures, self.count - 1, self.skipped)) else: self.log.info("Passed %d tests (%d skipped)" % (self.count - 1, self.skipped)) if len(self.test_results) > 0: self._log_test_summary() self._log_sim_summary() self.log.info("Shutting down...") # Generate output reports self.xunit.write() if self._cov: self._cov.stop() self.log.info("Writing coverage data") self._cov.save() self._cov.html_report() # Setup simulator finalization simulator.stop_simulator()