[svn r63040] try harder to record and auto-exit gateways after test runs
--HG-- branch : trunk
This commit is contained in:
parent
ee52739b17
commit
941d06e509
|
@ -330,6 +330,7 @@ class Gateway(object):
|
|||
self._cleanup.unregister(self)
|
||||
self._stopexec()
|
||||
self._stopsend()
|
||||
py._com.pyplugins.notify("gateway_exit", self)
|
||||
|
||||
def _stopsend(self):
|
||||
self._send(None)
|
||||
|
|
|
@ -41,6 +41,7 @@ class InstallableGateway(gateway.Gateway):
|
|||
super(InstallableGateway, self).__init__(io=io, _startcount=1)
|
||||
# XXX we dissallow execution form the other side
|
||||
self._initreceive(requestqueue=False)
|
||||
py._com.pyplugins.notify("gateway_init", self)
|
||||
|
||||
def _remote_bootstrap_gateway(self, io, extra=''):
|
||||
""" return Gateway with a asynchronously remotely
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import py
|
||||
pytest_plugins = "pytester"
|
||||
|
||||
class TestExecnetEvents:
|
||||
def test_popengateway(self, eventrecorder):
|
||||
gw = py.execnet.PopenGateway()
|
||||
event = eventrecorder.popevent("gateway_init")
|
||||
assert event.args[0] == gw
|
||||
gw.exit()
|
||||
event = eventrecorder.popevent("gateway_exit")
|
||||
assert event.args[0] == gw
|
|
@ -571,6 +571,9 @@ class TestSocketGateway(SocketGatewaySetup, BasicRemoteExecution):
|
|||
class TestSshGateway(BasicRemoteExecution):
|
||||
def setup_class(cls):
|
||||
sshhost = py.test.config.getvalueorskip("sshhost")
|
||||
if sshhost.find(":") != -1:
|
||||
sshhost = sshhost.split(":")[0]
|
||||
cls.sshhost = sshhost
|
||||
cls.gw = py.execnet.SshGateway(sshhost)
|
||||
|
||||
def test_sshconfig_functional(self):
|
||||
|
@ -578,7 +581,7 @@ class TestSshGateway(BasicRemoteExecution):
|
|||
ssh_config = tmpdir.join("ssh_config")
|
||||
ssh_config.write(
|
||||
"Host alias123\n"
|
||||
" HostName %s\n" % (py.test.config.option.sshhost,))
|
||||
" HostName %s\n" % self.sshhost)
|
||||
gw = py.execnet.SshGateway("alias123", ssh_config=ssh_config)
|
||||
assert gw._cmd.find("-F") != -1
|
||||
assert gw._cmd.find(str(ssh_config)) != -1
|
||||
|
@ -586,7 +589,7 @@ class TestSshGateway(BasicRemoteExecution):
|
|||
gw.exit()
|
||||
|
||||
def test_sshaddress(self):
|
||||
assert self.gw.remoteaddress == py.test.config.option.sshhost
|
||||
assert self.gw.remoteaddress == self.sshhost
|
||||
|
||||
@py.test.mark.xfail("XXX ssh-gateway error handling")
|
||||
def test_connexion_failes_on_non_existing_hosts(self):
|
||||
|
|
|
@ -11,7 +11,7 @@ Instance = py.test.collect.Instance
|
|||
conf_iocapture = "fd" # overridable from conftest.py
|
||||
|
||||
# XXX resultlog should go, pypy's nightrun depends on it
|
||||
pytest_plugins = "default terminal xfail tmpdir resultlog monkeypatch".split()
|
||||
pytest_plugins = "default terminal xfail tmpdir execnetcleanup resultlog monkeypatch".split()
|
||||
|
||||
# ===================================================
|
||||
# Distributed testing specific options
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import py
|
||||
|
||||
class ExecnetcleanupPlugin:
|
||||
_gateways = None
|
||||
_debug = None
|
||||
|
||||
def pytest_configure(self, config):
|
||||
self._debug = config.option.debug
|
||||
|
||||
def trace(self, msg, *args):
|
||||
if self._debug:
|
||||
print "[execnetcleanup %0x] %s %s" %(id(self), msg, args)
|
||||
|
||||
def pyevent_gateway_init(self, gateway):
|
||||
self.trace("init", gateway)
|
||||
if self._gateways is not None:
|
||||
self._gateways.append(gateway)
|
||||
|
||||
def pyevent_gateway_exit(self, gateway):
|
||||
self.trace("exit", gateway)
|
||||
if self._gateways is not None:
|
||||
self._gateways.remove(gateway)
|
||||
|
||||
def pyevent_testrunstart(self, event):
|
||||
self.trace("testrunstart", event)
|
||||
self._gateways = []
|
||||
|
||||
def pyevent_testrunfinish(self, event):
|
||||
self.trace("testrunfinish", event)
|
||||
l = []
|
||||
for gw in self._gateways:
|
||||
gw.exit()
|
||||
l.append(gw)
|
||||
for gw in l:
|
||||
gw.join()
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.apicheck(ExecnetcleanupPlugin)
|
||||
|
||||
@py.test.mark.xfail("clarify plugin registration/unregistration")
|
||||
def test_execnetplugin(testdir):
|
||||
p = ExecnetcleanupPlugin()
|
||||
testdir.plugins.append(p)
|
||||
testdir.inline_runsource("""
|
||||
import py
|
||||
import sys
|
||||
def test_hello():
|
||||
sys._gw = py.execnet.PopenGateway()
|
||||
""", "-s", "--debug")
|
||||
assert not p._gateways
|
||||
assert py.std.sys._gw
|
||||
py.test.raises(KeyError, "py.std.sys._gw.exit()") # already closed
|
||||
|
|
@ -155,8 +155,14 @@ class PytestPluginHooks:
|
|||
def pyevent(self, eventname, *args, **kwargs):
|
||||
""" called for each testing event. """
|
||||
|
||||
def pyevent_gateway_init(self, gateway):
|
||||
""" called a gateway has been initialized. """
|
||||
|
||||
def pyevent_gateway_exit(self, gateway):
|
||||
""" called when gateway is being exited. """
|
||||
|
||||
def pyevent_trace(self, category, msg):
|
||||
""" called for tracing events events. """
|
||||
""" called for tracing events. """
|
||||
|
||||
def pyevent_internalerror(self, event):
|
||||
""" called for internal errors. """
|
||||
|
|
|
@ -21,6 +21,11 @@ class PytesterPlugin:
|
|||
def pytest_pyfuncarg_EventRecorder(self, pyfuncitem):
|
||||
return EventRecorder
|
||||
|
||||
def pytest_pyfuncarg_eventrecorder(self, pyfuncitem):
|
||||
evrec = EventRecorder(py._com.pyplugins)
|
||||
pyfuncitem.addfinalizer(lambda: evrec.pyplugins.unregister(evrec))
|
||||
return evrec
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.apicheck(PytesterPlugin)
|
||||
|
||||
|
@ -245,6 +250,8 @@ class Event:
|
|||
self.name = name
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
def __repr__(self):
|
||||
return "<Event %r %r>" %(self.name, self.args)
|
||||
|
||||
class EventRecorder(object):
|
||||
def __init__(self, pyplugins, debug=False): # True):
|
||||
|
@ -260,6 +267,13 @@ class EventRecorder(object):
|
|||
print "[event: %s]: %s **%s" %(name, ", ".join(map(str, args)), kwargs,)
|
||||
self.events.append(Event(name, args, kwargs))
|
||||
|
||||
def popevent(self, name):
|
||||
for i, event in py.builtin.enumerate(self.events):
|
||||
if event.name == name:
|
||||
del self.events[i]
|
||||
return event
|
||||
raise KeyError("popevent: %r not found in %r" %(name, self.events))
|
||||
|
||||
def get(self, cls):
|
||||
l = []
|
||||
for event in self.events:
|
||||
|
|
|
@ -95,6 +95,7 @@ class PytestPlugins(object):
|
|||
config = self._config
|
||||
del self._config
|
||||
self.pyplugins.call_each("pytest_unconfigure", config=config)
|
||||
config.bus.unregister(self)
|
||||
|
||||
#
|
||||
# XXX old code to automatically load classes
|
||||
|
|
Loading…
Reference in New Issue