an early version of chakana, an automated test framework used with COOJA
This commit is contained in:
parent
9be473e4b9
commit
65533c0c00
29 changed files with 4983 additions and 0 deletions
184
tools/chakana/monitor.py
Normal file
184
tools/chakana/monitor.py
Normal file
|
@ -0,0 +1,184 @@
|
|||
import Queue
|
||||
import thread
|
||||
|
||||
import chakana.event
|
||||
import chakana.threads
|
||||
from chakana.debug import *
|
||||
|
||||
class Monitor(chakana.threads.ManagedThread):
|
||||
"""Base class for causal path monitors. Pass the threadManager to the
|
||||
constructor. Override the doRun method or pass a routine argument. In
|
||||
the latter case, the routine will be called with the Monitor object as
|
||||
argument plus any extra arguments and keyword arguments specified."""
|
||||
|
||||
def __init__(self, shepherd, routine = None, * args, ** kwArgs):
|
||||
chakana.threads.ManagedThread.__init__(self, shepherd.threadManager())
|
||||
self._shepherd = shepherd
|
||||
self._routine = routine
|
||||
self._args = args
|
||||
self._kwArgs = kwArgs
|
||||
self._ready = 0
|
||||
self._discarded = 0
|
||||
resourceAllocated = 0
|
||||
while resourceAllocated == 0:
|
||||
try:
|
||||
self._isWaitingMonitor = threading.Event()
|
||||
resourceAllocated = 1
|
||||
except thread.error:
|
||||
resourceAllocated = 0
|
||||
shepherd.threadManager().registerPIDerror()
|
||||
debug(Debug, "Monitor created")
|
||||
self._shepherd.registerMonitor(self)
|
||||
|
||||
def startMonitor(self):
|
||||
self.start()
|
||||
debug(Debug, "New monitor thread started: " + repr(self))
|
||||
|
||||
def discard(self):
|
||||
self._discarded = 1
|
||||
self._ready = 0
|
||||
debug(Debug, "Discarding monitor:\n" + repr(self))
|
||||
|
||||
# Wake up thread with empty results
|
||||
if hasattr(self, "_resultQueue"):
|
||||
self._resultQueue.put(None)
|
||||
|
||||
def waitMonitor(self, parentEventpoint = None):
|
||||
debug(Debug, "Waiting for monitor to finish: " + repr(self))
|
||||
|
||||
# While monitor is registered, check for continuations
|
||||
while self in self.shepherd()._monitors:
|
||||
resourceAllocated = 0
|
||||
while resourceAllocated == 0:
|
||||
try:
|
||||
self._isWaitingMonitor.wait()
|
||||
resourceAllocated = 1
|
||||
except thread.error:
|
||||
resourceAllocated = 0
|
||||
self.shepherd().threadManager().registerPIDerror()
|
||||
|
||||
self._isWaitingMonitor.clear()
|
||||
self._ready = 1
|
||||
|
||||
# If all monitors ready, poll continuation
|
||||
allMonitorsReady = 1
|
||||
for monitor in self.shepherd()._monitors:
|
||||
if not monitor._ready:
|
||||
allMonitorsReady = 0
|
||||
if allMonitorsReady:
|
||||
if self in self.shepherd()._monitors:
|
||||
self.shepherd().pollContinuation()
|
||||
else:
|
||||
# A monitor may be waiting for us, tell parent we are ready
|
||||
if parentEventpoint is not None:
|
||||
parentEventpoint._isWaitingEvent.set()
|
||||
self.join()
|
||||
|
||||
def doRun(self):
|
||||
debug(Debug, "Running monitor")
|
||||
try:
|
||||
if (not self._discarded):
|
||||
self.runMonitor()
|
||||
except chakana.error.Discarded:
|
||||
pass
|
||||
self.shepherd().unregisterMonitor(self)
|
||||
self._isWaitingMonitor.set()
|
||||
debug(Debug, "Monitor exiting")
|
||||
|
||||
def runMonitor(self):
|
||||
self._routine(self, * self._args, ** self._kwArgs)
|
||||
|
||||
def waitFor(self, eventList):
|
||||
"""Waits until one of the Events given in 'eventList' have triggered and
|
||||
returns that Event."""
|
||||
if isinstance(eventList, chakana.event.Eventpoint):
|
||||
eventList = [eventList]
|
||||
debug(MinorEvent, "Waiting for events to trigger. Event list: " +
|
||||
str(eventList))
|
||||
assert eventList != []
|
||||
|
||||
# Clean up eventpoints and abort monitor if discarded
|
||||
if self._discarded:
|
||||
for ev in eventList:
|
||||
ev.discard()
|
||||
raise chakana.error.Discarded()
|
||||
|
||||
self.shepherd().registerWaitingMonitor(self)
|
||||
|
||||
resourceAllocated = 0
|
||||
while resourceAllocated == 0:
|
||||
try:
|
||||
self._resultQueue = Queue.Queue()
|
||||
resourceAllocated = 1
|
||||
except thread.error:
|
||||
resourceAllocated = 0
|
||||
self.shepherd().threadManager().registerPIDerror()
|
||||
|
||||
for ev in eventList:
|
||||
# Start thread and wait until eventpoint is waiting
|
||||
ev.await(self._resultQueue)
|
||||
|
||||
resourceAllocated = 0
|
||||
while resourceAllocated == 0:
|
||||
try:
|
||||
ev._isWaitingEvent.wait()
|
||||
resourceAllocated = 1
|
||||
except thread.error:
|
||||
resourceAllocated = 0
|
||||
self.shepherd().threadManager().registerPIDerror()
|
||||
|
||||
ev._isWaitingEvent.clear()
|
||||
|
||||
debug(Event, "Waiting for events: " + repr(eventList))
|
||||
|
||||
assert(not self._discarded)
|
||||
|
||||
self._isWaitingMonitor.set()
|
||||
resourceAllocated = 0
|
||||
while resourceAllocated == 0:
|
||||
try:
|
||||
triggeredEvent = self._resultQueue.get()
|
||||
resourceAllocated = 1
|
||||
except thread.error:
|
||||
resourceAllocated = 0
|
||||
self.shepherd().threadManager().registerPIDerror()
|
||||
|
||||
self._ready = 0
|
||||
self.shepherd().unregisterWaitingMonitor(self)
|
||||
debug(Event, "Eventpoint was triggered: " + repr(eventList))
|
||||
for ev in eventList:
|
||||
if not (ev is triggeredEvent):
|
||||
ev.discard()
|
||||
|
||||
return triggeredEvent
|
||||
|
||||
def shepherd(self):
|
||||
return self._shepherd
|
||||
|
||||
def readVariable(self, ** kwArgs):
|
||||
return self.shepherd().readVariable(** kwArgs)
|
||||
|
||||
def readInt(self, ** kwArgs):
|
||||
return self.shepherd().readInt(** kwArgs)
|
||||
|
||||
def readMemory(self, ** kwArgs):
|
||||
return self.shepherd().readMemory(** kwArgs)
|
||||
|
||||
class TimeoutWrapperMonitor(Monitor):
|
||||
def __init__(self, shepherd, routine, eventpoint = None, timeout = 1000):
|
||||
chakana.monitor.Monitor.__init__(self, shepherd)
|
||||
self._eventpoint = eventpoint
|
||||
self._timeout = timeout
|
||||
self._triggeredEventpoint = None
|
||||
|
||||
def runMonitor(self):
|
||||
timeEventpoint = chakana.event.TimeEventpoint(self.shepherd(), self._timeout)
|
||||
self._triggeredEventpoint = self.waitFor([timeEventpoint, self._eventpoint])
|
||||
|
||||
def getTriggeredEventpoint(self):
|
||||
return self._triggeredEventpoint
|
||||
|
||||
def timedOut(self):
|
||||
return self.getTriggeredEventpoint() != self._eventpoint
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue