[svn r63107] cleanup event handling of dsession
--HG-- branch : trunk
This commit is contained in:
parent
c44764dc51
commit
78495272aa
|
@ -13,7 +13,8 @@ from py.__.test import outcome
|
||||||
import Queue
|
import Queue
|
||||||
|
|
||||||
class LoopState(object):
|
class LoopState(object):
|
||||||
def __init__(self, colitems):
|
def __init__(self, dsession, colitems):
|
||||||
|
self.dsession = dsession
|
||||||
self.colitems = colitems
|
self.colitems = colitems
|
||||||
self.exitstatus = None
|
self.exitstatus = None
|
||||||
# loopstate.dowork is False after reschedule events
|
# loopstate.dowork is False after reschedule events
|
||||||
|
@ -23,6 +24,30 @@ class LoopState(object):
|
||||||
self.shuttingdown = False
|
self.shuttingdown = False
|
||||||
self.testsfailed = False
|
self.testsfailed = False
|
||||||
|
|
||||||
|
def pyevent_itemtestreport(self, event):
|
||||||
|
if event.colitem in self.dsession.item2host:
|
||||||
|
self.dsession.removeitem(event.colitem)
|
||||||
|
if event.failed:
|
||||||
|
self.testsfailed = True
|
||||||
|
|
||||||
|
def pyevent_collectionreport(self, event):
|
||||||
|
if event.passed:
|
||||||
|
self.colitems.extend(event.result)
|
||||||
|
|
||||||
|
def pyevent_testnodeready(self, event):
|
||||||
|
self.dsession.addhost(event.host)
|
||||||
|
|
||||||
|
def pyevent_testnodedown(self, event):
|
||||||
|
pending = self.dsession.removehost(event.host)
|
||||||
|
if pending:
|
||||||
|
crashitem = pending[0]
|
||||||
|
self.dsession.handle_crashitem(crashitem, event.host)
|
||||||
|
self.colitems.extend(pending[1:])
|
||||||
|
|
||||||
|
def pyevent_rescheduleitems(self, event):
|
||||||
|
self.colitems.extend(event.items)
|
||||||
|
self.dowork = False # avoid busywait
|
||||||
|
|
||||||
class DSession(Session):
|
class DSession(Session):
|
||||||
"""
|
"""
|
||||||
Session drives the collection and running of tests
|
Session drives the collection and running of tests
|
||||||
|
@ -36,7 +61,6 @@ class DSession(Session):
|
||||||
self.queue = Queue.Queue()
|
self.queue = Queue.Queue()
|
||||||
self.host2pending = {}
|
self.host2pending = {}
|
||||||
self.item2host = {}
|
self.item2host = {}
|
||||||
self._testsfailed = False
|
|
||||||
if self.config.getvalue("executable") and \
|
if self.config.getvalue("executable") and \
|
||||||
not self.config.getvalue("numprocesses"):
|
not self.config.getvalue("numprocesses"):
|
||||||
self.config.option.numprocesses = 1
|
self.config.option.numprocesses = 1
|
||||||
|
@ -83,8 +107,8 @@ class DSession(Session):
|
||||||
if loopstate.shuttingdown:
|
if loopstate.shuttingdown:
|
||||||
return self.loop_once_shutdown(loopstate)
|
return self.loop_once_shutdown(loopstate)
|
||||||
colitems = loopstate.colitems
|
colitems = loopstate.colitems
|
||||||
if loopstate.dowork and loopstate.colitems:
|
if loopstate.dowork and colitems:
|
||||||
self.triggertesting(colitems)
|
self.triggertesting(loopstate.colitems)
|
||||||
colitems[:] = []
|
colitems[:] = []
|
||||||
# we use a timeout here so that control-C gets through
|
# we use a timeout here so that control-C gets through
|
||||||
while 1:
|
while 1:
|
||||||
|
@ -97,28 +121,6 @@ class DSession(Session):
|
||||||
|
|
||||||
eventname, args, kwargs = eventcall
|
eventname, args, kwargs = eventcall
|
||||||
self.bus.notify(eventname, *args, **kwargs)
|
self.bus.notify(eventname, *args, **kwargs)
|
||||||
if args:
|
|
||||||
ev, = args
|
|
||||||
else:
|
|
||||||
ev = None
|
|
||||||
if eventname == "itemtestreport":
|
|
||||||
self.removeitem(ev.colitem)
|
|
||||||
if ev.failed:
|
|
||||||
loopstate.testsfailed = True
|
|
||||||
elif eventname == "collectionreport":
|
|
||||||
if ev.passed:
|
|
||||||
colitems.extend(ev.result)
|
|
||||||
elif eventname == "testnodeready":
|
|
||||||
self.addhost(ev.host)
|
|
||||||
elif eventname == "testnodedown":
|
|
||||||
pending = self.removehost(ev.host)
|
|
||||||
if pending:
|
|
||||||
crashitem = pending.pop(0)
|
|
||||||
self.handle_crashitem(crashitem, ev.host)
|
|
||||||
colitems.extend(pending)
|
|
||||||
elif eventname == "rescheduleitems":
|
|
||||||
colitems.extend(ev.items)
|
|
||||||
loopstate.dowork = False # avoid busywait
|
|
||||||
|
|
||||||
# termination conditions
|
# termination conditions
|
||||||
if ((loopstate.testsfailed and self.config.option.exitfirst) or
|
if ((loopstate.testsfailed and self.config.option.exitfirst) or
|
||||||
|
@ -143,9 +145,14 @@ class DSession(Session):
|
||||||
else:
|
else:
|
||||||
loopstate.exitstatus = outcome.EXIT_OK
|
loopstate.exitstatus = outcome.EXIT_OK
|
||||||
|
|
||||||
|
def _initloopstate(self, colitems):
|
||||||
|
loopstate = LoopState(self, colitems)
|
||||||
|
self.config.bus.register(loopstate)
|
||||||
|
return loopstate
|
||||||
|
|
||||||
def loop(self, colitems):
|
def loop(self, colitems):
|
||||||
try:
|
try:
|
||||||
loopstate = LoopState(colitems)
|
loopstate = self._initloopstate(colitems)
|
||||||
loopstate.dowork = False # first receive at least one HostUp events
|
loopstate.dowork = False # first receive at least one HostUp events
|
||||||
while 1:
|
while 1:
|
||||||
self.loop_once(loopstate)
|
self.loop_once(loopstate)
|
||||||
|
@ -157,6 +164,7 @@ class DSession(Session):
|
||||||
except:
|
except:
|
||||||
self.bus.notify("internalerror", event.InternalException())
|
self.bus.notify("internalerror", event.InternalException())
|
||||||
exitstatus = outcome.EXIT_INTERNALERROR
|
exitstatus = outcome.EXIT_INTERNALERROR
|
||||||
|
self.config.bus.unregister(loopstate)
|
||||||
if exitstatus == 0 and self._testsfailed:
|
if exitstatus == 0 and self._testsfailed:
|
||||||
exitstatus = outcome.EXIT_TESTSFAILED
|
exitstatus = outcome.EXIT_TESTSFAILED
|
||||||
return exitstatus
|
return exitstatus
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from py.__.test.dsession.dsession import DSession, LoopState
|
from py.__.test.dsession.dsession import DSession
|
||||||
from py.__.test.dsession.masterslave import maketestnodeready
|
from py.__.test.dsession.masterslave import maketestnodeready
|
||||||
from py.__.execnet.gwmanage import GatewaySpec
|
from py.__.execnet.gwmanage import GatewaySpec
|
||||||
from py.__.test.runner import basic_collect_report
|
from py.__.test.runner import basic_collect_report
|
||||||
|
@ -120,7 +120,7 @@ class TestDSession:
|
||||||
host1.node = MockNode()
|
host1.node = MockNode()
|
||||||
session.addhost(host1)
|
session.addhost(host1)
|
||||||
ev = event.RescheduleItems([item])
|
ev = event.RescheduleItems([item])
|
||||||
loopstate = LoopState([])
|
loopstate = session._initloopstate([])
|
||||||
session.queueevent("rescheduleitems", ev)
|
session.queueevent("rescheduleitems", ev)
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
# check that RescheduleEvents are not immediately
|
# check that RescheduleEvents are not immediately
|
||||||
|
@ -148,7 +148,7 @@ class TestDSession:
|
||||||
ev = event.HostDown(host1, None)
|
ev = event.HostDown(host1, None)
|
||||||
session.queueevent("testnodedown", ev)
|
session.queueevent("testnodedown", ev)
|
||||||
|
|
||||||
loopstate = LoopState([item])
|
loopstate = session._initloopstate([item])
|
||||||
loopstate.dowork = False
|
loopstate.dowork = False
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
dumpqueue(session.queue)
|
dumpqueue(session.queue)
|
||||||
|
@ -178,7 +178,8 @@ class TestDSession:
|
||||||
ev = event.HostDown(host, None)
|
ev = event.HostDown(host, None)
|
||||||
session.queueevent("testnodedown", ev)
|
session.queueevent("testnodedown", ev)
|
||||||
evrec = EventRecorder(session.bus)
|
evrec = EventRecorder(session.bus)
|
||||||
loopstate = LoopState([])
|
print session.item2host
|
||||||
|
loopstate = session._initloopstate([])
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
|
|
||||||
assert loopstate.colitems == [item2] # do not reschedule crash item
|
assert loopstate.colitems == [item2] # do not reschedule crash item
|
||||||
|
@ -195,7 +196,7 @@ class TestDSession:
|
||||||
host1 = GatewaySpec("localhost")
|
host1 = GatewaySpec("localhost")
|
||||||
testnodeready = maketestnodeready(host1)
|
testnodeready = maketestnodeready(host1)
|
||||||
session.queueevent("testnodeready", testnodeready)
|
session.queueevent("testnodeready", testnodeready)
|
||||||
loopstate = LoopState([item])
|
loopstate = session._initloopstate([item])
|
||||||
loopstate.dowork = False
|
loopstate.dowork = False
|
||||||
assert len(session.host2pending) == 0
|
assert len(session.host2pending) == 0
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
|
@ -207,7 +208,7 @@ class TestDSession:
|
||||||
|
|
||||||
evrec = EventRecorder(session.bus)
|
evrec = EventRecorder(session.bus)
|
||||||
session.queueevent("NOPevent", 42)
|
session.queueevent("NOPevent", 42)
|
||||||
session.loop_once(LoopState([]))
|
session.loop_once(session._initloopstate([]))
|
||||||
assert evrec.getfirstnamed('NOPevent')
|
assert evrec.getfirstnamed('NOPevent')
|
||||||
|
|
||||||
def runthrough(self, item):
|
def runthrough(self, item):
|
||||||
|
@ -215,7 +216,7 @@ class TestDSession:
|
||||||
host1 = GatewaySpec("localhost")
|
host1 = GatewaySpec("localhost")
|
||||||
host1.node = MockNode()
|
host1.node = MockNode()
|
||||||
session.addhost(host1)
|
session.addhost(host1)
|
||||||
loopstate = LoopState([item])
|
loopstate = session._initloopstate([item])
|
||||||
|
|
||||||
session.queueevent("NOP")
|
session.queueevent("NOP")
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
|
@ -263,7 +264,7 @@ class TestDSession:
|
||||||
session.queueevent("itemtestreport", ev1) # a failing one
|
session.queueevent("itemtestreport", ev1) # a failing one
|
||||||
session.queueevent("itemtestreport", ev2)
|
session.queueevent("itemtestreport", ev2)
|
||||||
# now call the loop
|
# now call the loop
|
||||||
loopstate = LoopState(items)
|
loopstate = session._initloopstate(items)
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
assert loopstate.testsfailed
|
assert loopstate.testsfailed
|
||||||
assert loopstate.shuttingdown
|
assert loopstate.shuttingdown
|
||||||
|
@ -273,7 +274,7 @@ class TestDSession:
|
||||||
session = DSession(item.config)
|
session = DSession(item.config)
|
||||||
host = GatewaySpec("localhost")
|
host = GatewaySpec("localhost")
|
||||||
session.addhost(host)
|
session.addhost(host)
|
||||||
loopstate = LoopState([])
|
loopstate = session._initloopstate([])
|
||||||
loopstate.shuttingdown = True
|
loopstate.shuttingdown = True
|
||||||
evrec = EventRecorder(session.bus)
|
evrec = EventRecorder(session.bus)
|
||||||
session.queueevent("itemtestreport", run(item))
|
session.queueevent("itemtestreport", run(item))
|
||||||
|
@ -322,7 +323,7 @@ class TestDSession:
|
||||||
session.addhost(host)
|
session.addhost(host)
|
||||||
session.senditems([item])
|
session.senditems([item])
|
||||||
session.queueevent("itemtestreport", run(item))
|
session.queueevent("itemtestreport", run(item))
|
||||||
loopstate = LoopState([])
|
loopstate = session._initloopstate([])
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
assert host.node._shutdown is True
|
assert host.node._shutdown is True
|
||||||
assert loopstate.exitstatus is None, "loop did not wait for testnodedown"
|
assert loopstate.exitstatus is None, "loop did not wait for testnodedown"
|
||||||
|
@ -353,7 +354,7 @@ class TestDSession:
|
||||||
# but we have a collection pending
|
# but we have a collection pending
|
||||||
session.queueevent("collectionreport", colreport)
|
session.queueevent("collectionreport", colreport)
|
||||||
|
|
||||||
loopstate = LoopState([])
|
loopstate = session._initloopstate([])
|
||||||
session.loop_once(loopstate)
|
session.loop_once(loopstate)
|
||||||
assert loopstate.exitstatus is None, "loop did not care for collection report"
|
assert loopstate.exitstatus is None, "loop did not care for collection report"
|
||||||
assert not loopstate.colitems
|
assert not loopstate.colitems
|
||||||
|
|
Loading…
Reference in New Issue