Example #1
0
def make_call_info(exc_info, *, start, stop, duration, when):
    try:
        return CallInfo(
            None, exc_info, start=start, stop=stop, duration=duration, when=when
        )
    except TypeError:
        # support for pytest<6: didn't have a duration parameter then
        return CallInfo(None, exc_info, start=start, stop=stop, when=when)
Example #2
0
 def __init__(self, plugin, item, func, when):
     # pylint:disable=super-init-not-called
     #: context of invocation: one of "setup", "call",
     #: "teardown", "memocollect"
     self._item = item
     self._want_rerun = []
     self.excinfo = None
     from functools import partial
     CallInfo.__init__(self, partial(self.call, func, plugin), when)
Example #3
0
def run_fictitious_testprotocol(item):
    """
    REMINDER: Tests have already run on subprocess. Here we just need to convince the current pytest process that
    the tests have already run and to collect their reports.
    """
    call = CallInfo.from_call(lambda: True, when="setup", reraise=(Exit, ))
    item.ihook.pytest_runtest_makereport(item=item, call=call)
    call = CallInfo.from_call(lambda: True, when="call", reraise=(Exit, ))
    item.ihook.pytest_runtest_makereport(item=item, call=call)
    call = CallInfo.from_call(lambda: True, when="teardown", reraise=(Exit, ))
    item.ihook.pytest_runtest_makereport(item=item, call=call)
Example #4
0
def _addSubTest(self, test_case, test, exc_info):
    if exc_info is not None:
        msg = test._message if isinstance(test._message, str) else None
        call_info = CallInfo(None, ExceptionInfo(exc_info), 0, 0, when="call")
        sub_report = SubTestReport.from_item_and_call(item=self,
                                                      call=call_info)
        sub_report.context = SubTestContext(msg, dict(test.params))
        self.ihook.pytest_runtest_logreport(report=sub_report)
Example #5
0
def pytest_runtest_makereport(item, call):
    if isinstance(item, TestCaseFunction):
        if item._excinfo:
            call.excinfo = item._excinfo.pop(0)
            try:
                del call.result
            except AttributeError:
                pass

    unittest = sys.modules.get("unittest")
    if unittest and call.excinfo and call.excinfo.errisinstance(
            unittest.SkipTest):
        # let's substitute the excinfo with a pytest.skip one
        call2 = CallInfo.from_call(
            lambda: pytest.skip(str(call.excinfo.value)), call.when)
        call.excinfo = call2.excinfo
Example #6
0
    def call_runtest_hook(self, item, when, **kwds):
        """
        Monkey patched from the runner plugin. Responsible for running
        the test. Had to be patched to pass additional info to the
        CallInfo so the tests can be rerun if necessary.

        :param item:
            py.test wrapper for the test function to be run
        :type item:
            :class:`Function`
        """
        hookname = "pytest_runtest_" + when
        ihook = getattr(item.ihook, hookname)
        call_info = CallInfo(
            lambda: ihook(item=item, **kwds),
            when=when,
        )
        self._call_infos[item][when] = call_info
        return call_info
Example #7
0
    def test(self, msg=None, **kwargs):
        start = monotonic()
        exc_info = None

        with self._capturing_output() as captured:
            try:
                yield
            except (Exception, OutcomeException):
                exc_info = ExceptionInfo.from_current()

        stop = monotonic()

        call_info = CallInfo(None, exc_info, start, stop, when="call")
        sub_report = SubTestReport.from_item_and_call(item=self.item,
                                                      call=call_info)
        sub_report.context = SubTestContext(msg, kwargs.copy())

        captured.update_report(sub_report)

        with self.suspend_capture_ctx():
            self.ihook.pytest_runtest_logreport(report=sub_report)
Example #8
0
def pytest_pyfunc_call(pyfuncitem):
    if not pyfuncitem.config.option.reload_loop:
        return None
    else:
        testfunction = pyfuncitem.obj
        iscoroutinefunction = getattr(inspect, "iscoroutinefunction", None)
        if iscoroutinefunction is not None and iscoroutinefunction(
                testfunction):
            msg = "Coroutine functions are not natively supported and have been skipped.\n"
            msg += "You need to install a suitable plugin for your async framework, for example:\n"
            msg += "  - pytest-asyncio\n"
            msg += "  - pytest-trio\n"
            msg += "  - pytest-tornasync"
            warnings.warn(pytest.PytestWarning(msg.format(pyfuncitem.nodeid)))
            pytest.skip(
                msg=
                "coroutine function and no async plugin installed (see warnings)"
            )
        funcargs = pyfuncitem.funcargs
        testargs = {
            arg: funcargs[arg]
            for arg in pyfuncitem._fixtureinfo.argnames
        }
        passing = False
        while not passing:

            info = CallInfo.from_call(lambda: testfunction(**testargs),
                                      when="call",
                                      reraise=None)
            # if info.excinfo:
            if info.excinfo:
                # build the pytest report
                report = pyfuncitem.ihook.pytest_runtest_makereport(
                    item=pyfuncitem, call=info)
                _enter_pdb(pyfuncitem, info.excinfo, report)
            else:
                passing = True
        # after you've successfully gotten the test to pass run it one more time
        # (this hack exists because of the hookwrapper logic)
        return info
def fake_process(trace_fname):
    config = ctype(otype(trace_fname, 4), PytestPluginManager(),
                   lambda x, y: 0)
    plugin = ApiritifPytestPlugin(config)
    next(plugin.pytest_runtest_setup(None))

    yield

    node = Node._create("test", nodeid="tst", config=config, session="some")
    node._report_sections = []
    node.location = []
    node.user_properties = []
    call = CallInfo.from_call(lambda: 1, 'call')
    report = TestReport.from_item_and_call(node, call)
    result = _Result(report, None)
    gen = plugin.pytest_runtest_makereport(node, call)
    next(gen)
    try:
        gen.send(result)
    except StopIteration:
        pass

    plugin.pytest_sessionfinish(None)
Example #10
0
def run_function_from_file(item, params=None):
    file, _, func = item.location
    marker = item.get_closest_marker("subprocess")

    file_index = 1
    args = marker.kwargs.get("args", [])
    args.insert(0, None)
    args.insert(0, sys.executable)
    if marker.kwargs.get("ddtrace_run", False):
        file_index += 1
        args.insert(0, "ddtrace-run")

    env = os.environ.copy()
    env.update(marker.kwargs.get("env", {}))
    if params is not None:
        env.update(params)

    expected_status = marker.kwargs.get("status", 0)

    expected_out = marker.kwargs.get("out", "")
    if expected_out is not None:
        expected_out = expected_out.encode("utf-8")

    expected_err = marker.kwargs.get("err", "")
    if expected_err is not None:
        expected_err = expected_err.encode("utf-8")

    with NamedTemporaryFile(mode="wb", suffix=".pyc") as fp:
        dump_code_to_file(
            compile(FunctionDefFinder(func).find(file), file, "exec"), fp.file)

        start = time.time()
        args[file_index] = fp.name
        out, err, status, _ = call_program(*args, env=env)
        end = time.time()
        excinfo = None

        if status != expected_status:
            excinfo = AssertionError(
                "Expected status %s, got %s.\n=== Captured STDERR ===\n%s=== End of captured STDERR ==="
                % (expected_status, status, err.decode("utf-8")))
        elif expected_out is not None and out != expected_out:
            excinfo = AssertionError("STDOUT: Expected [%s] got [%s]" %
                                     (expected_out, out))
        elif expected_err is not None and err != expected_err:
            excinfo = AssertionError("STDERR: Expected [%s] got [%s]" %
                                     (expected_err, err))

        if PY2 and excinfo is not None:
            try:
                raise excinfo
            except Exception:
                excinfo = ExceptionInfo(sys.exc_info())

        call_info_args = dict(result=None,
                              excinfo=excinfo,
                              start=start,
                              stop=end,
                              when="call")
        if not PY2:
            call_info_args["duration"] = end - start

        return TestReport.from_item_and_call(item, CallInfo(**call_info_args))
Example #11
0
 def call_runtest_hook(self, item, when, **kwds):
     hookname = "pytest_runtest_" + when
     ihook = getattr(item.ihook, hookname)
     return CallInfo(lambda: ihook(item=item, **kwds), when=when)