From afca655202b781a0e2be576e7b2017858f9274ad Mon Sep 17 00:00:00 2001 From: hpk Date: Fri, 20 Mar 2009 20:04:36 +0100 Subject: [PATCH] [svn r63153] refactoring almost complete, apart from testnodeready info --HG-- branch : trunk --- py/test/dsession/dsession.py | 78 ++++----- py/test/dsession/hostmanage.py | 9 +- py/test/dsession/masterslave.py | 51 +++--- py/test/dsession/testing/test_dsession.py | 151 ++++++++---------- .../testing/test_functional_dsession.py | 8 +- py/test/dsession/testing/test_hostmanage.py | 10 +- py/test/dsession/testing/test_masterslave.py | 32 ++-- py/test/event.py | 18 +-- py/test/plugin/pytest_plugintester.py | 8 +- py/test/plugin/pytest_terminal.py | 31 ++-- py/test/session.py | 3 +- 11 files changed, 186 insertions(+), 213 deletions(-) diff --git a/py/test/dsession/dsession.py b/py/test/dsession/dsession.py index 95afa78aa..730f02f79 100644 --- a/py/test/dsession/dsession.py +++ b/py/test/dsession/dsession.py @@ -25,7 +25,7 @@ class LoopState(object): self.testsfailed = False def pyevent_itemtestreport(self, event): - if event.colitem in self.dsession.item2host: + if event.colitem in self.dsession.item2node: self.dsession.removeitem(event.colitem) if event.failed: self.testsfailed = True @@ -34,14 +34,14 @@ class LoopState(object): if event.passed: self.colitems.extend(event.result) - def pyevent_testnodeready(self, event): - self.dsession.addhost(event.host) + def pyevent_testnodeready(self, node): + self.dsession.addnode(node) - def pyevent_testnodedown(self, event): - pending = self.dsession.removehost(event.host) + def pyevent_testnodedown(self, node, error=None): + pending = self.dsession.removenode(node) if pending: crashitem = pending[0] - self.dsession.handle_crashitem(crashitem, event.host) + self.dsession.handle_crashitem(crashitem, node) self.colitems.extend(pending[1:]) def pyevent_rescheduleitems(self, event): @@ -59,8 +59,8 @@ class DSession(Session): super(DSession, self).__init__(config=config) self.queue = Queue.Queue() - self.host2pending = {} - self.item2host = {} + self.node2pending = {} + self.item2node = {} if self.config.getvalue("executable") and \ not self.config.getvalue("numprocesses"): self.config.option.numprocesses = 1 @@ -84,7 +84,7 @@ class DSession(Session): if config.option.numprocesses: return try: - config.getvalue('hosts') + config.getvalue('xspecs') except KeyError: print "Please specify test environments for distribution of tests:" print "py.test --tx ssh=user@somehost --tx popen//python=python2.5" @@ -97,9 +97,9 @@ class DSession(Session): def main(self, colitems=None): colitems = self.getinitialitems(colitems) self.sessionstarts() - self.setup_hosts() + self.setup_nodes() exitstatus = self.loop(colitems) - self.teardown_hosts() + self.teardown_nodes() self.sessionfinishes() return exitstatus @@ -124,10 +124,10 @@ class DSession(Session): # termination conditions if ((loopstate.testsfailed and self.config.option.exitfirst) or - (not self.item2host and not colitems and not self.queue.qsize())): + (not self.item2node and not colitems and not self.queue.qsize())): self.triggershutdown() loopstate.shuttingdown = True - elif not self.host2pending: + elif not self.node2pending: loopstate.exitstatus = outcome.EXIT_NOHOSTS def loop_once_shutdown(self, loopstate): @@ -135,10 +135,10 @@ class DSession(Session): # events other than HostDown upstream eventname, args, kwargs = self.queue.get() if eventname == "testnodedown": - ev, = args - self.bus.notify("testnodedown", ev) - self.removehost(ev.host) - if not self.host2pending: + node, error = args[0], args[1] + self.bus.notify("testnodedown", node, error) + self.removenode(node) + if not self.node2pending: # finished if loopstate.testsfailed: loopstate.exitstatus = outcome.EXIT_TESTSFAILED @@ -170,21 +170,21 @@ class DSession(Session): return exitstatus def triggershutdown(self): - for host in self.host2pending: - host.node.shutdown() + for node in self.node2pending: + node.shutdown() - def addhost(self, host): - assert host not in self.host2pending - self.host2pending[host] = [] + def addnode(self, node): + assert node not in self.node2pending + self.node2pending[node] = [] - def removehost(self, host): + def removenode(self, node): try: - pending = self.host2pending.pop(host) + pending = self.node2pending.pop(node) except KeyError: # this happens if we didn't receive a testnodeready event yet return [] for item in pending: - del self.item2host[item] + del self.item2node[item] return pending def triggertesting(self, colitems): @@ -204,17 +204,17 @@ class DSession(Session): def senditems(self, tosend): if not tosend: return - for host, pending in self.host2pending.items(): + for node, pending in self.node2pending.items(): room = self.MAXITEMSPERHOST - len(pending) if room > 0: sending = tosend[:room] - host.node.sendlist(sending) + node.sendlist(sending) for item in sending: - #assert item not in self.item2host, ( - # "sending same item %r to multiple hosts " + #assert item not in self.item2node, ( + # "sending same item %r to multiple " # "not implemented" %(item,)) - self.item2host[item] = host - self.bus.notify("itemstart", event.ItemStart(item, host)) + self.item2node[item] = node + self.bus.notify("itemstart", event.ItemStart(item, node)) pending.extend(sending) tosend[:] = tosend[room:] # update inplace if not tosend: @@ -224,24 +224,24 @@ class DSession(Session): self.queueevent("rescheduleitems", event.RescheduleItems(tosend)) def removeitem(self, item): - if item not in self.item2host: - raise AssertionError(item, self.item2host) - host = self.item2host.pop(item) - self.host2pending[host].remove(item) + if item not in self.item2node: + raise AssertionError(item, self.item2node) + node = self.item2node.pop(item) + self.node2pending[node].remove(item) #self.config.bus.notify("removeitem", item, host.hostid) - def handle_crashitem(self, item, host): - longrepr = "!!! Host %r crashed during running of test %r" %(host, item) + def handle_crashitem(self, item, node): + longrepr = "!!! Node %r crashed during running of test %r" %(node, item) rep = event.ItemTestReport(item, when="???", excinfo=longrepr) self.bus.notify("itemtestreport", rep) - def setup_hosts(self): + def setup_nodes(self): """ setup any neccessary resources ahead of the test run. """ from py.__.test.dsession.hostmanage import HostManager self.hm = HostManager(self.config) self.hm.setup_hosts(putevent=self.queue.put) - def teardown_hosts(self): + def teardown_nodes(self): """ teardown any resources after a test run. """ self.hm.teardown_hosts() diff --git a/py/test/dsession/hostmanage.py b/py/test/dsession/hostmanage.py index 807312437..bf184b8f7 100644 --- a/py/test/dsession/hostmanage.py +++ b/py/test/dsession/hostmanage.py @@ -47,6 +47,7 @@ class HostManager(object): hosts = getxspecs(self.config) self.roots = getconfigroots(config) self.gwmanager = GatewayManager(hosts) + self.nodes = [] def makegateways(self): # we change to the topdir sot that @@ -116,11 +117,9 @@ class HostManager(object): """).waitclose() for gateway in self.gwmanager.gateways: - host = gateway.spec - host.node = MasterNode(host, - gateway, - self.config, - putevent) + node = MasterNode(gateway, self.config, putevent) + self.nodes.append(node) def teardown_hosts(self): + # XXX teardown nodes? self.gwmanager.exit() diff --git a/py/test/dsession/masterslave.py b/py/test/dsession/masterslave.py index d1fbf6545..dec97c850 100644 --- a/py/test/dsession/masterslave.py +++ b/py/test/dsession/masterslave.py @@ -6,13 +6,14 @@ from py.__.test import event from py.__.test.dsession.mypickle import PickleChannel class MasterNode(object): + """ Install slave code, manage sending test tasks & receiving results """ ENDMARK = -1 - def __init__(self, host, gateway, config, putevent): - self.host = host + def __init__(self, gateway, config, putevent): self.config = config self.putevent = putevent - self.channel = install_slave(host, gateway, config) + self.gateway = gateway + self.channel = install_slave(gateway, config) self.channel.setcallback(self.callback, endmarker=self.ENDMARK) self._down = False @@ -32,23 +33,25 @@ class MasterNode(object): err = self.channel._getremoteerror() if not self._down: if not err: - err = "TERMINATED" - self.notify("testnodedown", event.HostDown(self.host, err)) + err = "Not properly terminated" + self.notify("testnodedown", self, err) + self._down = True return - elif eventcall is None: + eventname, args, kwargs = eventcall + if eventname == "slaveready": + self.notify("testnodeready", self) + elif eventname == "slavefinished": self._down = True - self.notify("testnodedown", event.HostDown(self.host, None)) - return - except KeyboardInterrupt: + self.notify("testnodedown", self, None) + else: + self.notify(eventname, *args, **kwargs) + except KeyboardInterrupt: + # should not land in receiver-thread raise except: excinfo = py.code.ExceptionInfo() print "!" * 20, excinfo self.notify("internalerror", event.InternalException(excinfo)) - else: - # XXX we need to have the proper event name - eventname, args, kwargs = eventcall - self.notify(eventname, *args, **kwargs) def send(self, item): assert item is not None @@ -61,7 +64,7 @@ class MasterNode(object): self.channel.send(None) # setting up slave code -def install_slave(host, gateway, config): +def install_slave(gateway, config): channel = gateway.remote_exec(source=""" from py.__.test.dsession.mypickle import PickleChannel from py.__.test.dsession.masterslave import SlaveNode @@ -71,12 +74,12 @@ def install_slave(host, gateway, config): """) channel = PickleChannel(channel) basetemp = None - if host.popen: + if 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((host, config, basetemp)) + channel.send((config, basetemp)) return channel class SlaveNode(object): @@ -91,17 +94,16 @@ class SlaveNode(object): def run(self): channel = self.channel - host, self.config, basetemp = channel.receive() + self.config, basetemp = channel.receive() if basetemp: self.config.basetemp = py.path.local(basetemp) self.config.pytestplugins.do_configure(self.config) - self.sendevent("testnodeready", maketestnodeready(host)) + self.sendevent("slaveready") try: while 1: task = channel.receive() - self.config.bus.notify("masterslave_receivedtask", task) - if task is None: # shutdown - self.channel.send(None) + if task is None: + self.sendevent("slavefinished") break if isinstance(task, list): for item in task: @@ -119,10 +121,3 @@ class SlaveNode(object): testrep = runner(item) self.sendevent("itemtestreport", testrep) - -def maketestnodeready(host="INPROCESS"): - import sys - platinfo = {} - for name in 'platform', 'executable', 'version_info': - platinfo["sys."+name] = getattr(sys, name) - return event.HostUp(host, platinfo) diff --git a/py/test/dsession/testing/test_dsession.py b/py/test/dsession/testing/test_dsession.py index 8c37e3402..c75f97c64 100644 --- a/py/test/dsession/testing/test_dsession.py +++ b/py/test/dsession/testing/test_dsession.py @@ -1,10 +1,11 @@ from py.__.test.dsession.dsession import DSession -from py.__.test.dsession.masterslave import maketestnodeready from py.__.test.runner import basic_collect_report from py.__.test import event from py.__.test import outcome import py +XSpec = py.execnet.XSpec + def run(item): runner = item._getrunner() return runner(item) @@ -33,35 +34,33 @@ class TestDSession: config.initsession().fixoptions() assert config.option.numprocesses == 3 - def test_add_remove_host(self, testdir): + def test_add_remove_node(self, testdir): item = testdir.getitem("def test_func(): pass") rep = run(item) session = DSession(item.config) - host = py.execnet.XSpec("popen") - host.node = MockNode() - assert not session.host2pending - session.addhost(host) - assert len(session.host2pending) == 1 + node = MockNode() + assert not session.node2pending + session.addnode(node) + assert len(session.node2pending) == 1 session.senditems([item]) - pending = session.removehost(host) + pending = session.removenode(node) assert pending == [item] - assert item not in session.item2host - l = session.removehost(host) + assert item not in session.item2node + l = session.removenode(node) assert not l def test_senditems_removeitems(self, testdir): item = testdir.getitem("def test_func(): pass") rep = run(item) session = DSession(item.config) - host = py.execnet.XSpec("popen") - host.node = MockNode() - session.addhost(host) + node = MockNode() + session.addnode(node) session.senditems([item]) - assert session.host2pending[host] == [item] - assert session.item2host[item] == host + assert session.node2pending[node] == [item] + assert session.item2node[item] == node session.removeitem(item) - assert not session.host2pending[host] - assert not session.item2host + assert not session.node2pending[node] + assert not session.item2node def test_triggertesting_collect(self, testdir): modcol = testdir.getmodulecol(""" @@ -78,19 +77,17 @@ class TestDSession: def test_triggertesting_item(self, testdir): item = testdir.getitem("def test_func(): pass") session = DSession(item.config) - host1 = py.execnet.XSpec("popen") - host1.node = MockNode() - host2 = py.execnet.XSpec("popen") - host2.node = MockNode() - session.addhost(host1) - session.addhost(host2) + node1 = MockNode() + node2 = MockNode() + session.addnode(node1) + session.addnode(node2) session.triggertesting([item] * (session.MAXITEMSPERHOST*2 + 1)) - host1_sent = host1.node.sent[0] - host2_sent = host2.node.sent[0] - assert host1_sent == [item] * session.MAXITEMSPERHOST - assert host2_sent == [item] * session.MAXITEMSPERHOST - assert session.host2pending[host1] == host1_sent - assert session.host2pending[host2] == host2_sent + sent1 = node1.sent[0] + sent2 = node2.sent[0] + assert sent1 == [item] * session.MAXITEMSPERHOST + assert sent2 == [item] * session.MAXITEMSPERHOST + assert session.node2pending[node1] == sent1 + assert session.node2pending[node2] == sent2 name, args, kwargs = session.queue.get(block=False) assert name == "rescheduleitems" ev, = args @@ -115,37 +112,34 @@ class TestDSession: def test_rescheduleevent(self, testdir): item = testdir.getitem("def test_func(): pass") session = DSession(item.config) - host1 = GatewaySpec("localhost") - host1.node = MockNode() - session.addhost(host1) + node = MockNode() + session.addnode(node) ev = event.RescheduleItems([item]) loopstate = session._initloopstate([]) session.queueevent("rescheduleitems", ev) session.loop_once(loopstate) # check that RescheduleEvents are not immediately - # rescheduled if there are no hosts + # rescheduled if there are no nodes assert loopstate.dowork == False session.queueevent("anonymous", event.NOP()) session.loop_once(loopstate) session.queueevent("anonymous", event.NOP()) session.loop_once(loopstate) - assert host1.node.sent == [[item]] + assert node.sent == [[item]] session.queueevent("itemtestreport", run(item)) session.loop_once(loopstate) assert loopstate.shuttingdown assert not loopstate.testsfailed - def test_no_hosts_remaining_for_tests(self, testdir): + def test_no_node_remaining_for_tests(self, testdir): item = testdir.getitem("def test_func(): pass") - # setup a session with one host + # setup a session with one node session = DSession(item.config) - host1 = GatewaySpec("localhost") - host1.node = MockNode() - session.addhost(host1) + node = MockNode() + session.addnode(node) # setup a HostDown event - ev = event.HostDown(host1, None) - session.queueevent("testnodedown", ev) + session.queueevent("testnodedown", node, None) loopstate = session._initloopstate([item]) loopstate.dowork = False @@ -162,22 +156,18 @@ class TestDSession: """) item1, item2 = modcol.collect() - # setup a session with two hosts + # setup a session with two nodes session = DSession(item1.config) - host1 = GatewaySpec("localhost") - host1.node = MockNode() - session.addhost(host1) - host2 = GatewaySpec("localhost") - host2.node = MockNode() - session.addhost(host2) + node1, node2 = MockNode(), MockNode() + session.addnode(node1) + session.addnode(node2) - # have one test pending for a host that goes down + # have one test pending for a node that goes down session.senditems([item1, item2]) - host = session.item2host[item1] - ev = event.HostDown(host, None) - session.queueevent("testnodedown", ev) + node = session.item2node[item1] + session.queueevent("testnodedown", node, None) evrec = EventRecorder(session.bus) - print session.item2host + print session.item2node loopstate = session._initloopstate([]) session.loop_once(loopstate) @@ -186,20 +176,19 @@ class TestDSession: assert testrep.failed assert testrep.colitem == item1 assert str(testrep.longrepr).find("crashed") != -1 - assert str(testrep.longrepr).find(host.address) != -1 + #assert str(testrep.longrepr).find(node.gateway.spec) != -1 def test_testnodeready_adds_to_available(self, testdir): item = testdir.getitem("def test_func(): pass") - # setup a session with two hosts + # setup a session with two nodes session = DSession(item.config) - host1 = GatewaySpec("localhost") - testnodeready = maketestnodeready(host1) - session.queueevent("testnodeready", testnodeready) + node1 = MockNode() + session.queueevent("testnodeready", node1) loopstate = session._initloopstate([item]) loopstate.dowork = False - assert len(session.host2pending) == 0 + assert len(session.node2pending) == 0 session.loop_once(loopstate) - assert len(session.host2pending) == 1 + assert len(session.node2pending) == 1 def test_event_propagation(self, testdir, EventRecorder): item = testdir.getitem("def test_func(): pass") @@ -212,20 +201,19 @@ class TestDSession: def runthrough(self, item): session = DSession(item.config) - host1 = GatewaySpec("localhost") - host1.node = MockNode() - session.addhost(host1) + node = MockNode() + session.addnode(node) loopstate = session._initloopstate([item]) session.queueevent("NOP") session.loop_once(loopstate) - assert host1.node.sent == [[item]] + assert node.sent == [[item]] ev = run(item) session.queueevent("itemtestreport", ev) session.loop_once(loopstate) assert loopstate.shuttingdown - session.queueevent("testnodedown", event.HostDown(host1, None)) + session.queueevent("testnodedown", node, None) session.loop_once(loopstate) dumpqueue(session.queue) return session, loopstate.exitstatus @@ -249,12 +237,11 @@ class TestDSession: """) modcol.config.option.exitfirst = True session = DSession(modcol.config) - host1 = GatewaySpec("localhost") - host1.node = MockNode() - session.addhost(host1) + node = MockNode() + session.addnode(node) items = basic_collect_report(modcol).result - # trigger testing - this sends tests to host1 + # trigger testing - this sends tests to the node session.triggertesting(items) # run tests ourselves and produce reports @@ -271,18 +258,17 @@ class TestDSession: def test_shuttingdown_filters_events(self, testdir, EventRecorder): item = testdir.getitem("def test_func(): pass") session = DSession(item.config) - host = GatewaySpec("localhost") - session.addhost(host) + node = MockNode() + session.addnode(node) loopstate = session._initloopstate([]) loopstate.shuttingdown = True evrec = EventRecorder(session.bus) session.queueevent("itemtestreport", run(item)) session.loop_once(loopstate) assert not evrec.getfirstnamed("testnodedown") - ev = event.HostDown(host) - session.queueevent("testnodedown", ev) + session.queueevent("testnodedown", node, None) session.loop_once(loopstate) - assert evrec.getfirstnamed('testnodedown') == ev + assert evrec.getfirstnamed('testnodedown') == node def test_filteritems(self, testdir, EventRecorder): modcol = testdir.getmodulecol(""" @@ -317,17 +303,16 @@ class TestDSession: item = testdir.getitem("def test_func(): pass") session = DSession(item.config) - host = GatewaySpec("localhost") - host.node = MockNode() - session.addhost(host) + node = MockNode() + session.addnode(node) session.senditems([item]) session.queueevent("itemtestreport", run(item)) loopstate = session._initloopstate([]) session.loop_once(loopstate) - assert host.node._shutdown is True + assert node._shutdown is True assert loopstate.exitstatus is None, "loop did not wait for testnodedown" assert loopstate.shuttingdown - session.queueevent("testnodedown", event.HostDown(host, None)) + session.queueevent("testnodedown", node, None) session.loop_once(loopstate) assert loopstate.exitstatus == 0 @@ -339,15 +324,13 @@ class TestDSession: pass """) session = DSession(modcol.config) - host = GatewaySpec("localhost") - host.node = MockNode() - session.addhost(host) + node = MockNode() + session.addnode(node) colreport = basic_collect_report(modcol) item1, item2 = colreport.result session.senditems([item1]) - # host2pending will become empty when the loop sees - # the report + # node2pending will become empty when the loop sees the report session.queueevent("itemtestreport", run(item1)) # but we have a collection pending diff --git a/py/test/dsession/testing/test_functional_dsession.py b/py/test/dsession/testing/test_functional_dsession.py index 8e54f6f99..cef5df1d4 100644 --- a/py/test/dsession/testing/test_functional_dsession.py +++ b/py/test/dsession/testing/test_functional_dsession.py @@ -52,10 +52,10 @@ class TestAsyncFunctional: assert ev.skipped ev, = eq.geteventargs("itemtestreport") assert ev.failed - # see that the host is really down - ev, = eq.geteventargs("testnodedown") - assert ev.host.popen - ev, = eq.geteventargs("testrunfinish") + # see that the node is really down + node, error = eq.geteventargs("testnodedown") + assert node.gateway.spec.popen + eq.geteventargs("testrunfinish") def test_distribution_rsyncdirs_example(self, testdir): source = testdir.mkdir("source") diff --git a/py/test/dsession/testing/test_hostmanage.py b/py/test/dsession/testing/test_hostmanage.py index 9d20bb723..3f292ede7 100644 --- a/py/test/dsession/testing/test_hostmanage.py +++ b/py/test/dsession/testing/test_hostmanage.py @@ -47,7 +47,7 @@ class TestHostManager: assert dest.join("dir1", "dir2").check() assert dest.join("dir1", "dir2", 'hello').check() - def test_hostmanager_init_rsync_roots(self, source, dest): + def test_init_rsync_roots(self, source, dest): dir2 = source.ensure("dir1", "dir2", dir=1) source.ensure("dir1", "somefile", dir=1) dir2.ensure("hello") @@ -63,7 +63,7 @@ class TestHostManager: assert not dest.join("dir1").check() assert not dest.join("bogus").check() - def test_hostmanager_rsyncignore(self, source, dest): + def test_rsyncignore(self, source, dest): dir2 = source.ensure("dir1", "dir2", dir=1) dir5 = source.ensure("dir5", "dir6", "bogus") dirf = source.ensure("dir5", "file") @@ -81,7 +81,7 @@ class TestHostManager: assert dest.join("dir5","file").check() assert not dest.join("dir6").check() - def test_hostmanage_optimise_popen(self, source, dest): + def test_optimise_popen(self, source, dest): hosts = ["popen"] * 3 source.join("conftest.py").write("rsyncdirs = ['a']") source.ensure('a', dir=1) @@ -92,7 +92,7 @@ class TestHostManager: assert gwspec._samefilesystem() assert not gwspec.chdir - def test_hostmanage_setup_hosts_DEBUG(self, source, EventRecorder): + def test_setup_hosts_DEBUG(self, source, EventRecorder): hosts = ["popen"] * 2 source.join("conftest.py").write("rsyncdirs = ['a']") source.ensure('a', dir=1) @@ -107,7 +107,7 @@ class TestHostManager: assert l hm.teardown_hosts() - def test_hostmanage_ssh_setup_hosts(self, specssh, testdir): + def test_ssh_setup_hosts(self, specssh, testdir): testdir.makepyfile(__init__="", test_x=""" def test_one(): pass diff --git a/py/test/dsession/testing/test_masterslave.py b/py/test/dsession/testing/test_masterslave.py index 167fa74ff..0d8c52cff 100644 --- a/py/test/dsession/testing/test_masterslave.py +++ b/py/test/dsession/testing/test_masterslave.py @@ -42,9 +42,9 @@ class MySetup: config = py.test.config._reparse([]) self.config = config self.queue = py.std.Queue.Queue() - self.host = py.execnet.XSpec("popen") - self.gateway = py.execnet.makegateway(self.host) - self.node = MasterNode(self.host, self.gateway, self.config, putevent=self.queue.put) + self.xspec = py.execnet.XSpec("popen") + self.gateway = py.execnet.makegateway(self.xspec) + self.node = MasterNode(self.gateway, self.config, putevent=self.queue.put) assert not self.node.channel.isclosed() return self.node @@ -64,14 +64,20 @@ def pytest_pyfuncarg_testdir(__call__, pyfuncitem): testdir.chdir() return testdir -class TestMasterSlaveConnection: +def test_node_hash_equality(mysetup): + node = mysetup.makenode() + node2 = mysetup.makenode() + assert node != node2 + assert node == node + assert not (node != node) +class TestMasterSlaveConnection: def test_crash_invalid_item(self, mysetup): node = mysetup.makenode() node.send(123) # invalid item - ev, = mysetup.geteventargs("testnodedown") - assert ev.host == mysetup.host - assert str(ev.error).find("AttributeError") != -1 + n, error = mysetup.geteventargs("testnodedown") + assert n is node + assert str(error).find("AttributeError") != -1 def test_crash_killed(self, testdir, mysetup): if not hasattr(py.std.os, 'kill'): @@ -83,16 +89,16 @@ class TestMasterSlaveConnection: """) node = mysetup.makenode(item.config) node.send(item) - ev, = mysetup.geteventargs("testnodedown") - assert ev.host == mysetup.host - assert str(ev.error).find("TERMINATED") != -1 + n, error = mysetup.geteventargs("testnodedown") + assert n is node + assert str(error).find("Not properly terminated") != -1 def test_node_down(self, mysetup): node = mysetup.makenode() node.shutdown() - ev, = mysetup.geteventargs("testnodedown") - assert ev.host == mysetup.host - assert not ev.error + n, error = mysetup.geteventargs("testnodedown") + assert n is node + assert not error node.callback(node.ENDMARK) excinfo = py.test.raises(IOError, "mysetup.geteventargs('testnodedown', timeout=0.01)") diff --git a/py/test/event.py b/py/test/event.py index 3add3efcd..7fffc359c 100644 --- a/py/test/event.py +++ b/py/test/event.py @@ -146,20 +146,10 @@ class RescheduleItems(BaseEvent): def __init__(self, items): self.items = items -class HostGatewayReady(BaseEvent): - def __init__(self, host, roots): - self.host = host - self.roots = roots - -class HostUp(BaseEvent): - def __init__(self, host, platinfo): - self.host = host - self.platinfo = platinfo - -class HostDown(BaseEvent): - def __init__(self, host, error=None): - self.host = host - self.error = error +#class HostGatewayReady(BaseEvent): +# def __init__(self, host, roots): +# self.host = host +# self.roots = roots # --------------------------------------------------------------------- # Events related to rsyncing diff --git a/py/test/plugin/pytest_plugintester.py b/py/test/plugin/pytest_plugintester.py index 6271646dc..3c43e5ae3 100644 --- a/py/test/plugin/pytest_plugintester.py +++ b/py/test/plugin/pytest_plugintester.py @@ -200,11 +200,11 @@ class PytestPluginHooks: within the gateway manager context. """ - def pyevent_testnodeready(self, event): - """ Host is up. """ + def pyevent_testnodeready(self, node): + """ Node is ready to operate. """ - def pyevent_testnodedown(self, event): - """ Host is down. """ + def pyevent_testnodedown(self, node, error): + """ Node is down. """ def pyevent_rescheduleitems(self, event): """ Items from a host that went down. """ diff --git a/py/test/plugin/pytest_terminal.py b/py/test/plugin/pytest_terminal.py index 2dbea7adb..55171f665 100644 --- a/py/test/plugin/pytest_terminal.py +++ b/py/test/plugin/pytest_terminal.py @@ -103,19 +103,20 @@ class TerminalReporter: # which garbles our output if we use self.write_line self.write_line(msg) - def pyevent_testnodeready(self, event): - d = event.platinfo.copy() - d['host'] = getattr(event.host, 'address', event.host) - d['version'] = repr_pythonversion(d['sys.version_info']) - self.write_line("HOSTUP: %(host)s %(sys.platform)s " - "%(sys.executable)s - Python %(version)s" % - d) + def pyevent_testnodeready(self, node): + # XXX + self.write_line("Node Ready: %r, spec %r" % (node,node.gateway.spec)) + + #d = event.platinfo.copy() + #d['host'] = getattr(event.host, 'address', event.host) + #d['version'] = repr_pythonversion(d['sys.version_info']) + #self.write_line("HOSTUP: %(host)s %(sys.platform)s " + # "%(sys.executable)s - Python %(version)s" % + # d) - def pyevent_testnodedown(self, event): - host = event.host - error = event.error + def pyevent_testnodedown(self, node, error): if error: - self.write_line("HostDown %s: %s" %(host, error)) + self.write_line("Node Down: %r: %r" %(node, error)) def pyevent_trace(self, category, msg): if self.config.option.debug or \ @@ -323,13 +324,13 @@ def repr_pythonversion(v=None): from py.__.test import event from py.__.test.runner import basic_run_report -from py.__.test.dsession.masterslave import maketestnodeready class TestTerminal: + @py.test.mark.xfail def test_testnodeready(self, testdir, linecomp): item = testdir.getitem("def test_func(): pass") rep = TerminalReporter(item.config, linecomp.stringio) - rep.pyevent_testnodeready(maketestnodeready()) + XXX # rep.pyevent_testnodeready(maketestnodeready()) linecomp.assert_contains_lines([ "*INPROCESS* %s %s - Python %s" %(sys.platform, sys.executable, repr_pythonversion(sys.version_info)) @@ -428,10 +429,10 @@ class TestTerminal: rep = TerminalReporter(modcol.config, file=linecomp.stringio) class gw1: id = "X1" - spec = py.execnet.GatewaySpec("popen") + spec = py.execnet.XSpec("popen") class gw2: id = "X2" - spec = py.execnet.GatewaySpec("popen") + spec = py.execnet.XSpec("popen") rep.pyevent_gwmanage_newgateway(gateway=gw1) linecomp.assert_contains_lines([ "X1 instantiated gateway from spec*", diff --git a/py/test/session.py b/py/test/session.py index 0acea677a..d5833fcd7 100644 --- a/py/test/session.py +++ b/py/test/session.py @@ -12,7 +12,6 @@ from py.__.test import event, outcome Item = py.test.collect.Item Collector = py.test.collect.Collector from runner import basic_collect_report -from py.__.test.dsession.masterslave import maketestnodeready class Session(object): """ @@ -117,7 +116,7 @@ class Session(object): colitems = self.getinitialitems(colitems) self.shouldstop = False self.sessionstarts() - self.bus.notify("testnodeready", maketestnodeready()) + #self.bus.notify("testnodeready", maketestnodeready()) exitstatus = outcome.EXIT_OK captured_excinfo = None try: