Example #1
0
    def _unschedule(self, coro):
        """Unschedule a coroutine.  Unprime any pending triggers"""
        if coro in self._pending_coros:
            assert not coro.has_started()
            self._pending_coros.remove(coro)
            # Close coroutine so there is no RuntimeWarning that it was never awaited
            coro.close()
            return

        # Unprime the trigger this coroutine is waiting on
        trigger = coro._trigger
        if trigger is not None:
            coro._trigger = None
            if coro in self._trigger2coros.setdefault(trigger, []):
                self._trigger2coros[trigger].remove(coro)
            if not self._trigger2coros[trigger]:
                trigger.unprime()
                del self._trigger2coros[trigger]

        assert self._test is not None

        if coro is self._test:
            if _debug:
                self.log.debug(f"Unscheduling test {coro}")

            if not self._terminate:
                self._terminate = True
                self._cleanup()

        elif Join(coro) in self._trigger2coros:
            self._react(Join(coro))
        else:
            try:
                # throws an error if the background coroutine errored
                # and no one was monitoring it
                coro._outcome.get()
            except (TestComplete, AssertionError) as e:
                coro.log.info("Test stopped by this forked coroutine")
                e = remove_traceback_frames(e, ["_unschedule", "get"])
                self._abort_test(e)
            except Exception as e:
                coro.log.error("Exception raised by this forked coroutine")
                e = remove_traceback_frames(e, ["_unschedule", "get"])
                warnings.warn(
                    '"Unwatched" tasks that throw exceptions will not cause the test to fail. '
                    "See issue #2664 for more details.",
                    FutureWarning,
                )
                self._abort_test(e)
Example #2
0
    def _advance(self, outcome):
        """Advance to the next yield in this coroutine.

        Args:
            outcome: The :any:`outcomes.Outcome` object to resume with.

        Returns:
            The object yielded from the coroutine

        Raises:
            CoroutineComplete: If the coroutine returns or throws an error, self._outcome is set, and
           :exc:`CoroutineComplete` is thrown.
        """
        try:
            self._started = True
            return outcome.send(self._coro)
        except ReturnValue as e:
            self._outcome = outcomes.Value(e.retval)
            raise CoroutineComplete()
        except StopIteration as e:
            retval = getattr(e, 'value', None)  # for python >=3.3
            self._outcome = outcomes.Value(retval)
            raise CoroutineComplete()
        except BaseException as e:
            self._outcome = outcomes.Error(remove_traceback_frames(e, ['_advance', 'send']))
            raise CoroutineComplete()
Example #3
0
def capture(fn, *args, **kwargs):
    """ Obtain an `Outcome` representing the result of a function call """
    try:
        return Value(fn(*args, **kwargs))
    except BaseException as e:
        e = remove_traceback_frames(e, ['capture'])
        return Error(e)
Example #4
0
    def _score_test(self, test: Test, outcome: Outcome) -> Tuple[bool, bool]:
        """
        Given a test and the test's outcome, determine if the test met expectations and log pertinent information
        """

        # scoring outcomes
        result_pass = True
        sim_failed = False

        try:
            outcome.get()
        except Exception as e:
            result = remove_traceback_frames(e, ["_score_test", "get"])
        else:
            result = TestSuccess()

        if (isinstance(result, TestSuccess) and not test.expect_fail
                and not test.expect_error):
            self._log_test_passed(test, None, None)

        elif isinstance(result, AssertionError) and test.expect_fail:
            self._log_test_passed(test, result, "failed as expected")

        elif isinstance(result, TestSuccess) and test.expect_error:
            self._log_test_failed(test, None,
                                  "passed but we expected an error")
            result_pass = False

        elif isinstance(result, TestSuccess):
            self._log_test_failed(test, None,
                                  "passed but we expected a failure")
            result_pass = False

        elif isinstance(result, SimFailure):
            if isinstance(result, test.expect_error):
                self._log_test_passed(test, result, "errored as expected")
            else:
                self.log.error(
                    "Test error has lead to simulator shutting us down")
                result_pass = False
            # whether we expected it or not, the simulation has failed unrecoverably
            sim_failed = True

        elif test.expect_error:
            if isinstance(result, test.expect_error):
                self._log_test_passed(test, result, "errored as expected")
            else:
                self._log_test_failed(test, result,
                                      "errored with unexpected type ")
                result_pass = False

        else:
            self._log_test_failed(test, result, None)
            result_pass = False

            if _pdb_on_exception:
                pdb.post_mortem(result.__traceback__)

        return result_pass, sim_failed
Example #5
0
def _wait_callback(trigger, callback):
    """
    Wait for a trigger, and call `callback` with the outcome of the yield.
    """
    try:
        ret = outcomes.Value((yield trigger))
    except BaseException as exc:
        # hide this from the traceback
        ret = outcomes.Error(remove_traceback_frames(exc, ['_wait_callback']))
    callback(ret)
Example #6
0
    def unschedule(self, coro):
        """Unschedule a coroutine.  Unprime any pending triggers"""

        # Unprime the trigger this coroutine is waiting on
        try:
            trigger = self._coro2trigger.pop(coro)
        except KeyError:
            # coroutine probably finished
            pass
        else:
            if coro in self._trigger2coros.setdefault(trigger, []):
                self._trigger2coros[trigger].remove(coro)
            if not self._trigger2coros[trigger]:
                trigger.unprime()
                del self._trigger2coros[trigger]

        assert self._test is not None

        if coro is self._test:
            if _debug:
                self.log.debug("Unscheduling test {}".format(coro))

            if not self._terminate:
                self._terminate = True
                self.cleanup()

        elif Join(coro) in self._trigger2coros:
            self.react(Join(coro))
        else:
            try:
                # throws an error if the background coroutine errored
                # and no one was monitoring it
                coro._outcome.get()
            except (TestComplete, AssertionError) as e:
                coro.log.info("Test stopped by this forked coroutine")
                outcome = outcomes.Error(
                    remove_traceback_frames(e, ['unschedule', 'get']))
                self._test._force_outcome(outcome)
            except Exception as e:
                coro.log.error("Exception raised by this forked coroutine")
                outcome = outcomes.Error(
                    remove_traceback_frames(e, ['unschedule', 'get']))
                self._test._force_outcome(outcome)
Example #7
0
async def _wait_callback(trigger, callback):
    """
    Wait for a trigger, and call `callback` with the outcome of the await.
    """
    try:
        ret = outcomes.Value(await trigger)
    except BaseException as exc:
        # hide this from the traceback
        ret = outcomes.Error(remove_traceback_frames(exc, ["_wait_callback"]))
    callback(ret)
Example #8
0
    def _unschedule(self, coro):
        """Unschedule a coroutine.  Unprime any pending triggers"""

        # Unprime the trigger this coroutine is waiting on
        trigger = coro._trigger
        if trigger is not None:
            coro._trigger = None
            if coro in self._trigger2coros.setdefault(trigger, []):
                self._trigger2coros[trigger].remove(coro)
            if not self._trigger2coros[trigger]:
                trigger.unprime()
                del self._trigger2coros[trigger]

        assert self._test is not None

        if coro is self._test:
            if _debug:
                self.log.debug(f"Unscheduling test {coro}")

            if not self._terminate:
                self._terminate = True
                self._cleanup()

        elif Join(coro) in self._trigger2coros:
            self._react(Join(coro))
        else:
            try:
                # throws an error if the background coroutine errored
                # and no one was monitoring it
                coro._outcome.get()
            except (TestComplete, AssertionError) as e:
                coro.log.info("Test stopped by this forked coroutine")
                e = remove_traceback_frames(e, ['_unschedule', 'get'])
                self._test.abort(e)
            except Exception as e:
                coro.log.error("Exception raised by this forked coroutine")
                e = remove_traceback_frames(e, ['_unschedule', 'get'])
                self._test.abort(e)
Example #9
0
    def _advance(self, outcome: outcomes.Outcome) -> typing.Any:
        """Advance to the next yield in this coroutine.

        Args:
            outcome: The :any:`outcomes.Outcome` object to resume with.

        Returns:
            The object yielded from the coroutine or None if coroutine finished

        """
        try:
            self._started = True
            return outcome.send(self._coro)
        except ReturnValue as e:
            self._outcome = outcomes.Value(e.retval)
        except StopIteration as e:
            self._outcome = outcomes.Value(e.value)
        except BaseException as e:
            self._outcome = outcomes.Error(
                remove_traceback_frames(e, ["_advance", "send"]))
Example #10
0
    def handle_result(self, test):
        """Handle a test completing.

        Dump result to XML and schedule the next test (if any).

        Args:
            test: The test that completed
        """
        assert test is self._running_test

        real_time = time.time() - test.start_time
        sim_time_ns = get_sim_time('ns') - test.start_sim_time
        ratio_time = self._safe_divide(sim_time_ns, real_time)

        self.xunit.add_testcase(name=test.funcname,
                                classname=test.module,
                                time=repr(real_time),
                                sim_time_ns=repr(sim_time_ns),
                                ratio_time=repr(ratio_time))

        # Helper for logging result
        def _result_was():
            result_was = ("{} (result was {})".format(
                test.funcname, result.__class__.__name__))
            return result_was

        result_pass = True

        # check what exception the test threw
        try:
            test._outcome.get()
        except Exception as e:
            if sys.version_info >= (3, 5):
                result = remove_traceback_frames(e, ['handle_result', 'get'])
                # newer versions of the `logging` module accept plain exception objects
                exc_info = result
            elif sys.version_info >= (3, ):
                result = remove_traceback_frames(e, ['handle_result', 'get'])
                # newer versions of python have Exception.__traceback__
                exc_info = (type(result), result, result.__traceback__)
            else:
                # Python 2
                result = e
                exc_info = remove_traceback_frames(sys.exc_info(),
                                                   ['handle_result', 'get'])
        else:
            result = TestSuccess()

        if (isinstance(result, TestSuccess) and not test.expect_fail
                and not test.expect_error):
            self.log.info("Test Passed: %s" % test.funcname)

        elif (isinstance(result, AssertionError) and test.expect_fail):
            self.log.info("Test failed as expected: " + _result_was())

        elif (isinstance(result, TestSuccess) and test.expect_error):
            self.log.error("Test passed but we expected an error: " +
                           _result_was())
            self._add_failure(result)
            result_pass = False

        elif isinstance(result, TestSuccess):
            self.log.error("Test passed but we expected a failure: " +
                           _result_was())
            self._add_failure(result)
            result_pass = False

        elif isinstance(result, SimFailure):
            if isinstance(result, test.expect_error):
                self.log.info("Test errored as expected: " + _result_was())
            else:
                self.log.error(
                    "Test error has lead to simulator shutting us "
                    "down",
                    exc_info=exc_info)
                self._add_failure(result)
                self._store_test_result(test.module, test.funcname, False,
                                        sim_time_ns, real_time, ratio_time)
                self.tear_down()
                return

        elif test.expect_error:
            if isinstance(result, test.expect_error):
                self.log.info("Test errored as expected: " + _result_was())
            else:
                self.log.info("Test errored with unexpected type: " +
                              _result_was())
                self._add_failure(result)
                result_pass = False

        else:
            self.log.error("Test Failed: " + _result_was(), exc_info=exc_info)
            self._add_failure(result)
            result_pass = False

        self._store_test_result(test.module, test.funcname, result_pass,
                                sim_time_ns, real_time, ratio_time)

        self.execute()
Example #11
0
    def _score_test(self, test: Test, outcome: Outcome) -> Tuple[bool, bool]:
        """
        Given a test and the test's outcome, determine if the test met expectations and log pertinent information
        """

        # Helper for logging result
        def _result_was():
            result_was = ("{} (result was {})".format(
                test.__qualname__,
                type(result).__qualname__))
            return result_was

        # scoring outcomes
        result_pass = True
        sim_failed = False

        try:
            outcome.get()
        except Exception as e:
            result = remove_traceback_frames(e, ['_score_test', 'get'])
        else:
            result = TestSuccess()

        if (isinstance(result, TestSuccess) and not test.expect_fail
                and not test.expect_error):
            self.log.info("Test Passed: %s" % test.__qualname__)

        elif (isinstance(result, AssertionError) and test.expect_fail):
            self.log.info("Test failed as expected: " + _result_was())

        elif (isinstance(result, TestSuccess) and test.expect_error):
            self.log.error("Test passed but we expected an error: " +
                           _result_was())
            result_pass = False

        elif isinstance(result, TestSuccess):
            self.log.error("Test passed but we expected a failure: " +
                           _result_was())
            result_pass = False

        elif isinstance(result, SimFailure):
            if isinstance(result, test.expect_error):
                self.log.info("Test errored as expected: " + _result_was())
            else:
                self.log.error(
                    "Test error has lead to simulator shutting us "
                    "down",
                    exc_info=result)
                result_pass = False
            # whether we expected it or not, the simulation has failed unrecoverably
            sim_failed = True

        elif test.expect_error:
            if isinstance(result, test.expect_error):
                self.log.info("Test errored as expected: " + _result_was())
            else:
                self.log.error("Test errored with unexpected type: " +
                               _result_was(),
                               exc_info=result)
                result_pass = False

        else:
            self.log.error("Test Failed: " + _result_was(), exc_info=result)
            result_pass = False

            if _pdb_on_exception:
                pdb.post_mortem(result.__traceback__)

        return result_pass, sim_failed
Example #12
0
    def _score_test(self, test, outcome):
        """
        Given a test and the test's outcome, determine if the test met expectations and log pertinent information
        """

        # Helper for logging result
        def _result_was():
            result_was = ("{} (result was {})".format(
                test.__name__, result.__class__.__name__))
            return result_was

        # scoring outcomes
        result_pass = True
        sim_failed = False

        try:
            outcome.get()
        except Exception as e:
            if sys.version_info >= (3, 5):
                result = remove_traceback_frames(e, ['_score_test', 'get'])
                # newer versions of the `logging` module accept plain exception objects
                exc_info = result
            elif sys.version_info >= (3, ):
                result = remove_traceback_frames(e, ['_score_test', 'get'])
                # newer versions of python have Exception.__traceback__
                exc_info = (type(result), result, result.__traceback__)
            else:
                # Python 2
                result = e
                exc_info = remove_traceback_frames(sys.exc_info(),
                                                   ['_score_test', 'get'])
        else:
            result = TestSuccess()

        if (isinstance(result, TestSuccess) and not test.expect_fail
                and not test.expect_error):
            self.log.info("Test Passed: %s" % test.__name__)

        elif (isinstance(result, AssertionError) and test.expect_fail):
            self.log.info("Test failed as expected: " + _result_was())

        elif (isinstance(result, TestSuccess) and test.expect_error):
            self.log.error("Test passed but we expected an error: " +
                           _result_was())
            result_pass = False

        elif isinstance(result, TestSuccess):
            self.log.error("Test passed but we expected a failure: " +
                           _result_was())
            result_pass = False

        elif isinstance(result, SimFailure):
            if isinstance(result, test.expect_error):
                self.log.info("Test errored as expected: " + _result_was())
            else:
                self.log.error(
                    "Test error has lead to simulator shutting us "
                    "down",
                    exc_info=exc_info)
                result_pass = False
            # whether we expected it or not, the simulation has failed unrecoverably
            sim_failed = True

        elif test.expect_error:
            if isinstance(result, test.expect_error):
                self.log.info("Test errored as expected: " + _result_was())
            else:
                self.log.error("Test errored with unexpected type: " +
                               _result_was(),
                               exc_info=exc_info)
                result_pass = False

        else:
            self.log.error("Test Failed: " + _result_was(), exc_info=exc_info)
            result_pass = False

            if _pdb_on_exception:
                if sys.version_info >= (3, 5):
                    traceback = exc_info.__traceback__
                else:
                    traceback = exc_info[2]
                pdb.post_mortem(traceback)

        return result_pass, sim_failed
Example #13
0
 def without_frames(self, frame_names):
     ret = copy.copy(self)
     ret.error_tb = remove_traceback_frames(ret.error_tb, frame_names)
     return ret
Example #14
0
 def without_frames(self, frame_names):
     return Error(remove_traceback_frames(self.error, frame_names))