From 9abaae87780560307426a5749c7b1fc0d0c2cbae Mon Sep 17 00:00:00 2001 From: holger krekel Date: Thu, 22 Apr 2010 17:00:03 +0200 Subject: [PATCH] * introduce explicit pytest_configure_node hook for node configuration, simplifying implementation of slaveinput/slaveoutput data exchange * only require the already released execnet-1.0.5 --- setup.py | 2 +- testing/acceptance_test.py | 40 +++++++++++++++++++------------------- xdist/newhooks.py | 4 ++++ xdist/txnode.py | 32 ++++++++++++------------------ 4 files changed, 37 insertions(+), 41 deletions(-) diff --git a/setup.py b/setup.py index 8544013..9274fe2 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ setup( packages = ['xdist'], entry_points = {'pytest11': ['xdist = xdist.plugin'],}, zip_safe=False, - install_requires = ['execnet>=1.0.6', 'py>=1.2.2'], + install_requires = ['execnet>=1.0.5', 'py>=1.2.2'], classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 1fa074f..441ae97 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -120,30 +120,30 @@ class TestDistribution: def test_data_exchange(self, testdir): c1 = testdir.makeconftest(""" - # This hook only called on master. - def pytest_testnodeready(node): - node.slaveinput['a'] = 42 - node.slaveinput['b'] = 7 + # This hook only called on master. + def pytest_configure_node(node): + node.slaveinput['a'] = 42 + node.slaveinput['b'] = 7 - # This hook only take action on slave. - def pytest_sessionstart(session): - if hasattr(session.config, 'slaveinput'): - a = session.config.slaveinput['a'] - b = session.config.slaveinput['b'] - r = a + b - session.config.slaveoutput['r'] = r + # This hook only takes action on slave. + def pytest_configure(config): + if hasattr(config, 'slaveinput'): + a = config.slaveinput['a'] + b = config.slaveinput['b'] + r = a + b + config.slaveoutput['r'] = r - # This hook only called on master. - def pytest_testnodedown(node, error): - node.config.calc_result = node.slaveoutput['r'] + # This hook only called on master. + def pytest_testnodedown(node, error): + node.config.calc_result = node.slaveoutput['r'] - # This hook only take action on master. - def pytest_terminal_summary(terminalreporter): - if not hasattr(terminalreporter.config, 'slaveinput'): - calc_result = terminalreporter.config.calc_result - terminalreporter._tw.sep('-', 'calculated result is %s' % calc_result) + # This hook only takes action on master. + def pytest_terminal_summary(terminalreporter): + if not hasattr(terminalreporter.config, 'slaveinput'): + calc_result = terminalreporter.config.calc_result + terminalreporter._tw.sep('-', + 'calculated result is %s' % calc_result) """) - p1 = testdir.makepyfile("def test_func(): pass") result = testdir.runpytest(p1, '-d', '--tx=popen') result.stdout.fnmatch_lines([ diff --git a/xdist/newhooks.py b/xdist/newhooks.py index 22a0f84..fa52fa3 100644 --- a/xdist/newhooks.py +++ b/xdist/newhooks.py @@ -8,6 +8,9 @@ def pytest_gwmanage_rsyncstart(source, gateways): def pytest_gwmanage_rsyncfinish(source, gateways): """ called after rsyncing a directory to remote gateways takes place. """ +def pytest_configure_node(node): + """ configure node information before it gets instantiated. """ + def pytest_testnodeready(node): """ Test Node is ready to operate. """ @@ -19,3 +22,4 @@ def pytest_rescheduleitems(items): def pytest_looponfailinfo(failreports, rootdirs): """ info for repeating failing tests. """ + diff --git a/xdist/txnode.py b/xdist/txnode.py index 930502b..d5e9675 100644 --- a/xdist/txnode.py +++ b/xdist/txnode.py @@ -18,12 +18,10 @@ class TXNode(object): self.config = config self.putevent = putevent self.gateway = gateway - self.channel = install_slave(gateway, config) + self.slaveinput = {} + self.channel = install_slave(self) self.channel.setcallback(self.callback, endmarker=self.ENDMARK) self._down = False - self.slaveinputsent = False - self.slaveinput = {} - self.slaveoutput = {} def __repr__(self): id = self.gateway.id @@ -72,30 +70,22 @@ class TXNode(object): py.builtin.print_("!" * 20, excinfo) self.config.pluginmanager.notify_exception(excinfo) - def sendslaveinput(self): - if not self.slaveinputsent: - self.channel.send(self.slaveinput) - self.slaveinputsent = True - def send(self, item): assert item is not None - self.sendslaveinput() self.channel.send(item) def sendlist(self, itemlist): - self.sendslaveinput() self.channel.send(itemlist) def shutdown(self, kill=False): if kill: self.gateway.exit() else: - self.sendslaveinput() self.channel.send(None) -# setting up slave code -def install_slave(gateway, config): - channel = gateway.remote_exec(source=""" +# configuring and setting up slave node +def install_slave(node): + channel = node.gateway.remote_exec(source=""" import os, sys sys.path.insert(0, os.getcwd()) from xdist.mypickle import PickleChannel @@ -108,12 +98,14 @@ def install_slave(gateway, config): channel.receive() channel = PickleChannel(channel) basetemp = None - if gateway.spec.popen: + config = node.config + config.hook.pytest_configure_node(node=node) + if node.gateway.spec.popen: popenbase = config.ensuretemp("popen") basetemp = py.path.local.make_numbered_dir(prefix="slave-", keep=0, rootdir=popenbase) basetemp = str(basetemp) - channel.send((config, basetemp, gateway.id)) + channel.send((config, node.slaveinput, basetemp, node.gateway.id)) return channel class SlaveNode(object): @@ -134,15 +126,15 @@ class SlaveNode(object): def run(self): channel = self.channel - self.config, basetemp, self.nodeid = channel.receive() + self.config, slaveinput, basetemp, self.nodeid = channel.receive() if basetemp: self.config.basetemp = py.path.local(basetemp) + self.config.slaveinput = slaveinput + self.config.slaveoutput = {} self.config.pluginmanager.do_configure(self.config) self.config.pluginmanager.register(self) self.runner = self.config.pluginmanager.getplugin("pytest_runner") self.sendevent("slaveready") - self.config.slaveinput = channel.receive() - self.config.slaveoutput = {} try: self.config.hook.pytest_sessionstart(session=self) while 1: