re-introduce slaveinput/slaveoutput configure protocol
This commit is contained in:
@@ -175,8 +175,8 @@ class TestDistribution:
|
|||||||
node.slaveinput['a'] = 42
|
node.slaveinput['a'] = 42
|
||||||
node.slaveinput['b'] = 7
|
node.slaveinput['b'] = 7
|
||||||
|
|
||||||
# This hook only takes action on slave.
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
|
# this attribute is only set on slaves
|
||||||
if hasattr(config, 'slaveinput'):
|
if hasattr(config, 'slaveinput'):
|
||||||
a = config.slaveinput['a']
|
a = config.slaveinput['a']
|
||||||
b = config.slaveinput['b']
|
b = config.slaveinput['b']
|
||||||
@@ -187,7 +187,6 @@ class TestDistribution:
|
|||||||
def pytest_testnodedown(node, error):
|
def pytest_testnodedown(node, error):
|
||||||
node.config.calc_result = node.slaveoutput['r']
|
node.config.calc_result = node.slaveoutput['r']
|
||||||
|
|
||||||
# This hook only takes action on master.
|
|
||||||
def pytest_terminal_summary(terminalreporter):
|
def pytest_terminal_summary(terminalreporter):
|
||||||
if not hasattr(terminalreporter.config, 'slaveinput'):
|
if not hasattr(terminalreporter.config, 'slaveinput'):
|
||||||
calc_result = terminalreporter.config.calc_result
|
calc_result = terminalreporter.config.calc_result
|
||||||
@@ -210,18 +209,20 @@ class TestDistribution:
|
|||||||
""")
|
""")
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
def pytest_sessionfinish(session):
|
def pytest_sessionfinish(session):
|
||||||
|
# on the slave
|
||||||
if hasattr(session.config, 'slaveoutput'):
|
if hasattr(session.config, 'slaveoutput'):
|
||||||
session.config.slaveoutput['s2'] = 42
|
session.config.slaveoutput['s2'] = 42
|
||||||
|
# on the master
|
||||||
def pytest_testnodedown(node, error):
|
def pytest_testnodedown(node, error):
|
||||||
assert node.slaveoutput['s2'] == 42
|
assert node.slaveoutput['s2'] == 42
|
||||||
print ("s2call-finished")
|
print ("s2call-finished")
|
||||||
""")
|
""")
|
||||||
args = ["-n1"]
|
args = ["-n1", "--debug"]
|
||||||
result = testdir.runpytest(*args)
|
result = testdir.runpytest(*args)
|
||||||
s = result.stdout.str()
|
s = result.stdout.str()
|
||||||
assert result.ret
|
assert result.ret == 2
|
||||||
assert 'SIGINT' in s
|
|
||||||
assert 's2call' in s
|
assert 's2call' in s
|
||||||
|
assert "Interrupted" in s
|
||||||
|
|
||||||
def test_keyboard_interrupt_dist(self, testdir):
|
def test_keyboard_interrupt_dist(self, testdir):
|
||||||
# xxx could be refined to check for return code
|
# xxx could be refined to check for return code
|
||||||
|
|||||||
@@ -162,8 +162,13 @@ class DSession:
|
|||||||
node.shutdown()
|
node.shutdown()
|
||||||
|
|
||||||
def slave_slavefinished(self, node):
|
def slave_slavefinished(self, node):
|
||||||
|
self.config.hook.pytest_testnodedown(node=node, error=None)
|
||||||
|
if node.slaveoutput['exitstatus'] == 2: # keyboard-interrupt
|
||||||
|
self.shouldstop = "%s received keyboard-interrupt" % (node,)
|
||||||
|
self.slave_errordown(node, "keyboard-interrupt")
|
||||||
|
return
|
||||||
crashitem = self.sched.remove_node(node)
|
crashitem = self.sched.remove_node(node)
|
||||||
assert not crashitem, (crashitem, node)
|
#assert not crashitem, (crashitem, node)
|
||||||
if self.shuttingdown and not self.sched.hasnodes():
|
if self.shuttingdown and not self.sched.hasnodes():
|
||||||
self.session_finished = True
|
self.session_finished = True
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,10 @@
|
|||||||
|
|
||||||
import py
|
import py
|
||||||
import sys
|
import sys
|
||||||
import execnet
|
|
||||||
from py._plugin import pytest_runner as runner # XXX load dynamically
|
from py._plugin import pytest_runner as runner # XXX load dynamically
|
||||||
|
|
||||||
def make_reltoroot(roots, args):
|
def make_reltoroot(roots, args):
|
||||||
# XXX introduce/use public API for splitting args
|
# XXX introduce/use public API for splitting py.test args
|
||||||
splitcode = "::"
|
splitcode = "::"
|
||||||
l = []
|
l = []
|
||||||
for arg in args:
|
for arg in args:
|
||||||
@@ -32,6 +31,7 @@ class SlaveController(object):
|
|||||||
self.putevent = putevent
|
self.putevent = putevent
|
||||||
self.gateway = gateway
|
self.gateway = gateway
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.slaveinput = {'slaveid': gateway.id}
|
||||||
self._down = False
|
self._down = False
|
||||||
self.log = py.log.Producer("slavectl-%s" % gateway.id)
|
self.log = py.log.Producer("slavectl-%s" % gateway.id)
|
||||||
if not self.config.option.debug:
|
if not self.config.option.debug:
|
||||||
@@ -46,7 +46,9 @@ class SlaveController(object):
|
|||||||
args = self.config.args
|
args = self.config.args
|
||||||
if not spec.popen or spec.chdir:
|
if not spec.popen or spec.chdir:
|
||||||
args = make_reltoroot(self.nodemanager.roots, args)
|
args = make_reltoroot(self.nodemanager.roots, args)
|
||||||
|
self.config.hook.pytest_configure_node(node=self)
|
||||||
self.channel = self.gateway.remote_exec(init_slave_session,
|
self.channel = self.gateway.remote_exec(init_slave_session,
|
||||||
|
slaveinput=self.slaveinput,
|
||||||
args=args, option_dict=vars(self.config.option),
|
args=args, option_dict=vars(self.config.option),
|
||||||
)
|
)
|
||||||
if self.putevent:
|
if self.putevent:
|
||||||
@@ -123,14 +125,12 @@ class SlaveController(object):
|
|||||||
py.builtin.print_("!" * 20, excinfo)
|
py.builtin.print_("!" * 20, excinfo)
|
||||||
self.config.pluginmanager.notify_exception(excinfo)
|
self.config.pluginmanager.notify_exception(excinfo)
|
||||||
|
|
||||||
def init_slave_session(channel, args, option_dict):
|
def init_slave_session(channel, slaveinput, args, option_dict):
|
||||||
import py
|
import py
|
||||||
#outchannel = channel.gateway.newchannel()
|
|
||||||
#sys.stdout = sys.stderr = outchannel.makefile('w')
|
|
||||||
#channel.send(outchannel)
|
|
||||||
#fullwidth, hasmarkup = channel.receive()
|
|
||||||
from xdist.remote import remote_initconfig, SlaveInteractor
|
from xdist.remote import remote_initconfig, SlaveInteractor
|
||||||
config = remote_initconfig(py.test.config, option_dict, args)
|
config = remote_initconfig(py.test.config, option_dict, args)
|
||||||
|
config.slaveinput = slaveinput
|
||||||
|
config.slaveoutput = {}
|
||||||
interactor = SlaveInteractor(config, channel)
|
interactor = SlaveInteractor(config, channel)
|
||||||
config.hook.pytest_cmdline_main(config=config)
|
config.hook.pytest_cmdline_main(config=config)
|
||||||
|
|
||||||
@@ -148,7 +148,8 @@ def remote_initconfig(config, option_dict, args):
|
|||||||
class SlaveInteractor:
|
class SlaveInteractor:
|
||||||
def __init__(self, config, channel):
|
def __init__(self, config, channel):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.log = py.log.Producer("slave")
|
self.slaveid = config.slaveinput.get('slaveid', "?")
|
||||||
|
self.log = py.log.Producer("slave-%s" % self.slaveid)
|
||||||
if not config.option.debug:
|
if not config.option.debug:
|
||||||
py.log.setconsumer(self.log._keywords, None)
|
py.log.setconsumer(self.log._keywords, None)
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
@@ -167,8 +168,11 @@ class SlaveInteractor:
|
|||||||
self.collection = session.collection
|
self.collection = session.collection
|
||||||
self.sendevent("slaveready")
|
self.sendevent("slaveready")
|
||||||
|
|
||||||
def pytest_sessionfinish(self):
|
def pytest_sessionfinish(self, __multicall__, exitstatus):
|
||||||
self.sendevent("slavefinished", slaveoutput={})
|
self.config.slaveoutput['exitstatus'] = exitstatus
|
||||||
|
res = __multicall__.execute()
|
||||||
|
self.sendevent("slavefinished", slaveoutput=self.config.slaveoutput)
|
||||||
|
return res
|
||||||
|
|
||||||
def pytest_perform_collection(self, session):
|
def pytest_perform_collection(self, session):
|
||||||
self.sendevent("collectionstart")
|
self.sendevent("collectionstart")
|
||||||
@@ -188,7 +192,6 @@ class SlaveInteractor:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def pytest_log_finishcollection(self, collection):
|
def pytest_log_finishcollection(self, collection):
|
||||||
self.log("pytest_log_finishcollection")
|
|
||||||
ids = [collection.getid(item) for item in collection.items]
|
ids = [collection.getid(item) for item in collection.items]
|
||||||
self.sendevent("collectionfinish",
|
self.sendevent("collectionfinish",
|
||||||
topdir=str(collection.topdir),
|
topdir=str(collection.topdir),
|
||||||
|
|||||||
Reference in New Issue
Block a user