def testValueReturns(self): log = [] def f1(): yield 42 def f2(): yield f1() yield activity.resume() def f3(): yield f2() v = activity.resume() log.append(v) t = activity.TaskCell(f3) EventLoop.flush() self.assertEqual(log, [42]) log = [] def f1(): yield activity.Return(42) t = activity.TaskCell(f3) EventLoop.flush() self.assertEqual(log, [42])
def testSequentialCalls(self): log = [] EventLoop.call(log.append, 1) EventLoop.call(log.append, 2) EventLoop.call(log.append, 3) EventLoop.call(log.append, 4) class IdleTimer(trellis.Component): trellis.attrs( idle_timeout = 20, busy = False, ) idle_for = trellis.maintain( lambda self: self.idle_for.begins_with(not self.busy), initially=NOT_YET ) trellis.maintain() # XXX should be perform def alarm(self): if self.idle_for[self.idle_timeout] and EventLoop.running: log.append(5) EventLoop.stop() it = IdleTimer() EventLoop.run() self.assertEqual(log, [1,2,3,4,5])
def testSequentialCalls(self): log = [] EventLoop.call(log.append, 1) EventLoop.call(log.append, 2) EventLoop.call(log.append, 3) EventLoop.call(log.append, 4) class IdleTimer(trellis.Component): trellis.attrs( idle_timeout=20, busy=False, ) idle_for = trellis.maintain( lambda self: self.idle_for.begins_with(not self.busy), initially=NOT_YET) @trellis.maintain # XXX should be perform def alarm(self): if self.idle_for[self.idle_timeout] and EventLoop.running: log.append(5) EventLoop.stop() it = IdleTimer() EventLoop.run() self.assertEqual(log, [1, 2, 3, 4, 5])
def testSendAndThrow(self): log = [] class SendThrowIter(object): count = 0 def next(self): if self.count==0: self.count = 1 def f(): yield 99 return f() raise StopIteration def send(self, value): log.append(value) def f(): raise DummyError; yield None return f() def throw(self, typ, val, tb): log.append(typ) log.append(val.__class__) # type(val) is instance in Py<2.5 log.append(type(tb)) raise StopIteration def fs(): yield SendThrowIter() t = activity.TaskCell(fs) self.assertEqual(log, []) EventLoop.flush() self.assertEqual(log, [99, DummyError,DummyError, types.TracebackType])
def testErrorPropagation(self): log = [] def f1(): raise DummyError def f2(): try: yield f1(); activity.resume() except DummyError: log.append(True) else: pass t = activity.TaskCell(f2) self.assertEqual(log, []) EventLoop.flush() self.assertEqual(log, [True])
def testResumeOnlyOnceUntilFlushed(self): log = [] c1 = trellis.Value(1) c2 = trellis.Value(2) def f(): for i in range(3): c1.value, c2.value log.append(i) yield activity.Pause t = activity.TaskCell(f) self.assertEqual(log, []) EventLoop.flush() self.assertEqual(log, [0]) c1.value = 3 self.assertEqual(log, [0]) c2.value = 4 EventLoop.flush() self.assertEqual(log, [0, 1])
def testErrorPropagation(self): log = [] def f1(): raise DummyError def f2(): try: yield f1() activity.resume() except DummyError: log.append(True) else: pass t = activity.TaskCell(f2) self.assertEqual(log, []) EventLoop.flush() self.assertEqual(log, [True])
def testSequentialCalls(self): log = [] EventLoop.call(log.append, 1) EventLoop.call(log.append, 2) EventLoop.call(log.append, 3) EventLoop.call(log.append, 4) event = Time[0.00001] def c(): if event: # events aren't EventLoop.call(EventLoop.stop) c = trellis.Cell(c) c.value # This will loop indefinitely, if sub-millisecond events aren't # rounded up to the next millisecond. EventLoop.run() self.frame.Destroy() self.assertEqual(log, [1, 2, 3, 4])
def testSendAndThrow(self): log = [] class SendThrowIter(object): count = 0 def next(self): if self.count == 0: self.count = 1 def f(): yield 99 return f() raise StopIteration def send(self, value): log.append(value) def f(): raise DummyError yield None return f() def throw(self, typ, val, tb): log.append(typ) log.append(val.__class__) # type(val) is instance in Py<2.5 log.append(type(tb)) raise StopIteration def fs(): yield SendThrowIter() t = activity.TaskCell(fs) self.assertEqual(log, []) EventLoop.flush() self.assertEqual(log, [99, DummyError, DummyError, types.TracebackType])
def testNoTodoRollbackIntoTask(self): class CV(trellis.Component): v = trellis.attr(False) s = trellis.make(trellis.Set, name='s') @trellis.maintain def maintain(self): if self.v: self.s.add(1) else: self.s.discard(1) @trellis.perform def perform(s): self.assertEqual(s.v, True) @activity.TaskCell def task(): cv = CV() cv.v = True yield activity.Pause EventLoop.run()
def testNoTodoRollbackIntoTask(self): class CV(trellis.Component): v = trellis.attr(False) s = trellis.make(trellis.Set, name="s") @trellis.maintain def maintain(self): if self.v: self.s.add(1) else: self.s.discard(1) @trellis.perform def perform(s): self.assertEqual(s.v, True) @activity.TaskCell def task(): cv = CV() cv.v = True yield activity.Pause EventLoop.run()
def testPauseAndCall(self): log = [] class TaskExample(trellis.Component): trellis.attrs( start = False, stop = False ) def wait_for_start(self): log.append("waiting to start") while not self.start: yield activity.Pause def wait_for_stop(self): while not self.stop: log.append("waiting to stop") yield activity.Pause activity.task() def demo(self): yield self.wait_for_start() log.append("starting") yield self.wait_for_stop() log.append("stopped") self.assertEqual(log, []) t = TaskExample() EventLoop.flush() self.assertEqual(log, ['waiting to start']) log.pop() t.start = True EventLoop.flush() self.assertEqual(log, ['starting', 'waiting to stop']) log.pop() log.pop() t.stop = True EventLoop.flush() self.assertEqual(log, ['stopped'])
def testPauseAndCall(self): log = [] class TaskExample(trellis.Component): trellis.attrs(start=False, stop=False) def wait_for_start(self): log.append("waiting to start") while not self.start: yield activity.Pause def wait_for_stop(self): while not self.stop: log.append("waiting to stop") yield activity.Pause @activity.task def demo(self): yield self.wait_for_start() log.append("starting") yield self.wait_for_stop() log.append("stopped") self.assertEqual(log, []) t = TaskExample() EventLoop.flush() self.assertEqual(log, ['waiting to start']) log.pop() t.start = True EventLoop.flush() self.assertEqual(log, ['starting', 'waiting to stop']) log.pop() log.pop() t.stop = True EventLoop.flush() self.assertEqual(log, ['stopped'])
def c(): if event: # events aren't EventLoop.call(EventLoop.stop)
def testSequentialCalls(self): log = [] EventLoop.call(log.append, 1) EventLoop.call(log.append, 2) EventLoop.call(log.append, 3) EventLoop.call(log.append, 4) EventLoop.call(EventLoop.stop) EventLoop.run() self.assertEqual(log, [1,2,3,4])
def alarm(self): if self.idle_for[self.idle_timeout] and EventLoop.running: log.append(5) EventLoop.stop()
class TestDefaultEventLoop(unittest.TestCase): def setUp(self): self.loop = EventLoop() self.ctrl = trellis.ctrl def testCallAndPoll(self): log = [] self.loop.call(log.append, 1) self.loop.call(log.append, 2) self.assertEqual(log, []) self.loop.poll() self.assertEqual(log, [1]) self.loop.poll() self.assertEqual(log, [1, 2]) self.loop.poll() self.assertEqual(log, [1, 2]) @a def testLoopIsNonAtomic(self): self.assertRaises(AssertionError, self.loop.poll) self.assertRaises(AssertionError, self.loop.flush) self.assertRaises(AssertionError, self.loop.run) def testCallAndFlush(self): log = [] self.loop.call(log.append, 1) self.loop.call(log.append, 2) self.loop.call(self.loop.call, log.append, 3) self.assertEqual(log, []) self.loop.flush() self.assertEqual(log, [1, 2]) self.loop.poll() self.assertEqual(log, [1, 2, 3]) self.loop.poll() self.assertEqual(log, [1, 2, 3]) def testUndoOfCall(self): log = [] def do(): self.loop.call(log.append, 1) sp = self.ctrl.savepoint() self.loop.call(log.append, 2) self.ctrl.rollback_to(sp) self.loop.call(log.append, 3) self.ctrl.atomically(do) self.assertEqual(log, []) self.loop.flush() self.assertEqual(log, [1, 3]) def testScheduleUndo(self): t = Time() t.auto_update = False t20 = t[20] log = [] @trellis.Cell def checktime(): t.reached(t20) log.append(t._events[t20._when]) @trellis.Performer def err_after_reached(): if len(t._schedule) > 1: raise DummyError self.assertRaises(DummyError, checktime.get_value) self.assertEqual(t._schedule, [t20._when, Max]) self.assertEqual(dict(t._events), {t20._when: log[0]}) del checktime self.failUnless(isinstance(log.pop(), trellis.Sensor)) self.assertEqual(dict(t._events), {}) self.assertEqual(log, []) def force_rollback(self): @trellis.Performer def do_it(): raise DummyError def testUpdateUndo(self): t = Time() t.auto_update = False t20 = t[20] @trellis.Cell def checktime(): if t.reached(t20): self.force_rollback() checktime.value self.assertEqual(t._schedule, [t20._when, Max]) self.assertEqual(list(t._events), [t20._when]) self.assertRaises(DummyError, t.advance, 20) self.assertEqual(t._schedule, [t20._when, Max]) self.assertEqual(list(t._events), [t20._when])
def setUp(self): self.loop = EventLoop() self.ctrl = trellis.ctrl