diff --git a/changelog/92.feature b/changelog/92.feature new file mode 100644 index 00000000..8f950c5c --- /dev/null +++ b/changelog/92.feature @@ -0,0 +1 @@ +Warnings are now properly transferred from workers to the master node. diff --git a/setup.cfg b/setup.cfg index ed8a958e..36f3f4dc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,3 +3,6 @@ universal = 1 [metadata] license_file = LICENSE + +[flake8] +max-line-length = 100 diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 557464fa..bc71b8ce 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -339,6 +339,21 @@ def test_func(): "E assert 0", ]) + @pytest.mark.parametrize('n', ['-n0', '-n1']) + def test_logwarning(self, testdir, n): + from pkg_resources import parse_version + if parse_version(pytest.__version__) < parse_version('3.1'): + pytest.skip('pytest warnings requires >= 3.1') + testdir.makepyfile(""" + import warnings + def test_func(): + warnings.warn('this is a warning') + """) + result = testdir.runpytest(n) + result.stdout.fnmatch_lines([ + "*this is a warning*", + ]) + def test_teardownfails_one_function(testdir): p = testdir.makepyfile(""" diff --git a/xdist/dsession.py b/xdist/dsession.py index 6fe7f796..37003577 100644 --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -247,6 +247,11 @@ def slave_collectreport(self, node, rep): if rep.failed: self._failed_slave_collectreport(node, rep) + def slave_logwarning(self, message, code, nodeid, fslocation): + """Emitted when a node calls the pytest_logwarning hook.""" + kwargs = dict(message=message, code=code, nodeid=nodeid, fslocation=fslocation) + self.config.hook.pytest_logwarning.call_historic(kwargs=kwargs) + def _clone_node(self, node): """Return new node based on an existing one. diff --git a/xdist/remote.py b/xdist/remote.py index 7c5ded77..f9760602 100644 --- a/xdist/remote.py +++ b/xdist/remote.py @@ -8,6 +8,7 @@ import sys import os +import pytest class SlaveInteractor: @@ -33,11 +34,11 @@ def pytest_sessionstart(self, session): slaveinfo = getinfodict() self.sendevent("slaveready", slaveinfo=slaveinfo) - def pytest_sessionfinish(self, __multicall__, exitstatus): + @pytest.hookimpl(hookwrapper=True) + def pytest_sessionfinish(self, exitstatus): self.config.slaveoutput['exitstatus'] = exitstatus - res = __multicall__.execute() + yield self.sendevent("slavefinished", slaveoutput=self.config.slaveoutput) - return res def pytest_collection(self, session): self.sendevent("collectionstart") @@ -96,6 +97,10 @@ def pytest_collectreport(self, report): data = serialize_report(report) self.sendevent("collectreport", data=data) + def pytest_logwarning(self, message, code, nodeid, fslocation): + self.sendevent("logwarning", message=message, code=code, nodeid=nodeid, + fslocation=fslocation) + def serialize_report(rep): def disassembled_report(rep): diff --git a/xdist/slavemanage.py b/xdist/slavemanage.py index 0e45a205..adc7fddb 100644 --- a/xdist/slavemanage.py +++ b/xdist/slavemanage.py @@ -315,6 +315,10 @@ def process_from_remote(self, eventcall): # noqa too complex self.notify_inproc(eventname, node=self, rep=rep) elif eventname == "collectionfinish": self.notify_inproc(eventname, node=self, ids=kwargs['ids']) + elif eventname == "logwarning": + self.notify_inproc(eventname, message=kwargs['message'], + code=kwargs['code'], nodeid=kwargs['nodeid'], + fslocation=kwargs['nodeid']) else: raise ValueError("unknown event: %s" % (eventname,)) except KeyboardInterrupt: