def Tasklets(): t = stackless.getcurrent() r = [t] while t.next and t.next != r[0]: t = t.next r.append(t) t = stackless.getmain() if t not in r: r.append(t) while t.next and t.next != stackless.getmain(): t = t.next r.append(t) return r
def tearDown(self): # Tasklets created in pickling tests can be left in the scheduler when they finish. We can feel free to # clean them up for the tests. Any tests that expect to exit with no leaked tasklets should do explicit # assertions to check. self.assertTrue(self.__setup_called, "Broken test case: it didn't call super(..., self).setUp()") self.__setup_called = False mainTasklet = stackless.getmain() current = mainTasklet.next while current is not None and current is not mainTasklet: next_ = current.next current.kill() current = next_ run_count = stackless.getruncount() self.assertEqual(run_count, 1, "Leakage from this test, with %d tasklets still in the scheduler" % (run_count - 1)) if withThreads: preexisting_threads = self.__preexisting_threads self.__preexisting_threads = None # avoid pickling problems, see _addSkip expected_thread_count = len(preexisting_threads) active_count = threading.active_count() if active_count > expected_thread_count: activeThreads = set(threading.enumerate()) activeThreads -= preexisting_threads self.assertNotIn(threading.current_thread(), activeThreads, "tearDown runs on the wrong thread.") while activeThreads: activeThreads.pop().join(0.5) active_count = threading.active_count() self.assertEqual(active_count, expected_thread_count, "Leakage from other threads, with %d threads running (%d expected)" % (active_count, expected_thread_count)) gc.collect() # emits warnings about uncollectable objects after each test
def test0(self): "Simple monitored channel send from main tasklet." import stackless # create players chan = stackless.channel() main = stackless.getmain() # implicit sender receiver = stackless.tasklet(lambda ch: ch.receive()) receiver = receiver(chan) # send a value to a monitored channel chanMon = ChannelMonitor() stackless.set_channel_callback(chanMon) val = 42 chan.send(val) stackless.set_channel_callback(None) # compare sent value with monitored one # found = chanMon.history[0][1].tempval # self.assertEqual(val, found) # FAILS - why? # # fails, because the value is moved from sender to receiver # also, I need to modify channels a little :-) # this one works, because I keep a copy of the value. # # print chanMon.history found = chanMon.history[0][-1] self.assertEqual(val, found)
def test_schedule_callback(self): res = [] cb = [] def schedule_cb(prev, next): cb.append((prev, next)) stackless.set_schedule_callback(schedule_cb) def f(i): res.append('A_%s' % i) stackless.schedule() res.append('B_%s' % i) t1 = stackless.tasklet(f)(1) t2 = stackless.tasklet(f)(2) maintask = stackless.getmain() stackless.run() assert res == ['A_1', 'A_2', 'B_1', 'B_2'] assert len(cb) == 5 assert cb[0] == (maintask, t1) assert cb[1] == (t1, t2) assert cb[2] == (t2, t1) assert cb[3] == (t1, t2) assert cb[4] == (t2, maintask)
def test0(self): "Simple monitored channel send from main tasklet." import stackless # create players chan = stackless.channel() main = stackless.getmain() # implicit sender receiver = stackless.tasklet(lambda ch:ch.receive()) receiver = receiver(chan) # send a value to a monitored channel chanMon = ChannelMonitor() stackless.set_channel_callback(chanMon) val = 42 chan.send(val) stackless.set_channel_callback(None) # compare sent value with monitored one # found = chanMon.history[0][1].tempval # self.failUnlessEqual(val, found) # FAILS - why? # # fails, because the value is moved from sender to receiver # also, I need to modify channels a little :-) # this one works, because I keep a copy of the value. # # print chanMon.history found = chanMon.history[0][-1] self.failUnlessEqual(val, found)
def test_schedule_return(self): def f():pass t1= stackless.tasklet(f)() r = stackless.schedule() assert r is stackless.getmain() t2 = stackless.tasklet(f)() r = stackless.schedule('test') assert r == 'test'
def tlet_wrapper(): self.main_other_thread = main = stackless.main try: func(main) except TaskletExit: self.tasklet_killed = True self.main_during_kill = stackless.getmain() raise else: self.fail("func must block!")
def maintest(): ch.receive() global look, stackref, tstate t = stackless.getmain() look = get_stack(t) stackref = t.frame.cstack.startaddr try: tstate = stackless._peek(t.frame) except AttributeError: tstate = None
def blocking(func, *args, **kwargs): """ Wrap a function like the deferred decorator but call it as a blocking call to support synchronous calls in a tasklet outside of the reactor. WARNING: Currently does not function. """ func2 = tasklet(func) deferred = func2(*args, **kwargs) if REACTASK != sl.getcurrent() and sl.getcurrent() != sl.getmain(): return _block_on(deferred) raise RuntimeError("Cannot block in reactor task")
def tearDown(self): # Tasklets created in pickling tests can be left in the scheduler when they finish. We can feel free to # clean them up for the tests. mainTasklet = stackless.getmain() current = mainTasklet.next while current is not mainTasklet: next = current.next current.kill() current = next super(TestPickledTasklets, self).tearDown() del self.verbose
def tearDown(self): # Tasklets created in pickling tests can be left in the scheduler when they finish. We can feel free to # clean them up for the tests. Any tests that expect to exit with no leaked tasklets should do explicit # assertions to check. mainTasklet = stackless.getmain() current = mainTasklet.next while current is not mainTasklet: next = current.next current.kill() current = next self.assertEqual(stackless.getruncount(), 1, "Leakage from this test, with %d tasklets still in the scheduler" % (stackless.getruncount() - 1)) if threading.activeCount() > 1: activeThreads = threading.enumerate() activeThreads.remove(threading.currentThread()) activeThreads[0].join(0.5) if threading.activeCount() > 1: self.assertEqual(threading.activeCount(), 1, "Leakage from other threads, with %d threads running (1 expected)" % (threading.activeCount()))
def GetDefaultDB(self): self.__enter() if len(self._conn_pool) < 1: self._initialize() self.__exit() if stackless.getcurrent() == stackless.getmain(): return self._conn_pool[0] idx = 2 ret = 1 #while idx < len( self._conn_pool ): # if self._conn_pool[idx].conn.waiting() < self._conn_pool[ret].conn.waiting(): # ret = idx # idx += 1 db = self._conn_pool.pop(ret) self._conn_pool.append(db) return db
def _async_query(self,squery): #print '>>>>>>>>>>> _async_query' cur_task = stackless.getcurrent() qid = id(cur_task) if cur_task == stackless.getmain(): #print '>>>>>>>>>>> _orig_query' self._waitings[qid] = False return self._orig_query(squery) # #print '>>>>>>>>>>> _async_query _wait' self._wait() self._waitings[qid] = True self.send_query(squery) if not kernel.event.Bind( self.fd, kernel.event.EVENT_READ, self._event_cb, qid ): return None #print 'Bind fd: %d query: %d to IO, wait...'%(self.fd, qid) try: ret = self._query_channel.receive() except Exception,ex: self._release_wait( qid ) raise ex
def test_simple(self): rlist = [] def f(): rlist.append('f') def g(): rlist.append('g') stackless.schedule() def main(): rlist.append('m') cg = stackless.tasklet(g)() cf = stackless.tasklet(f)() stackless.run() rlist.append('m') main() assert stackless.getcurrent() is stackless.getmain() assert rlist == 'm g f m'.split()
def stackPrint(message, taskletList): mainTasklet = stackless.getmain() count = stackless.getruncount() currentTasklet = stackless.getcurrent() for key in list(taskletList.keys()): taskletList[key].killComplete() #try: #print(mainTasklet.next) #print(mainTasklet.next()) #except Exception: #pass #for i in range(count - 1): #nextTasklet = currentTasklet.next() #if not nextTasklet.is_main or currentTasklet == nextTasklet: #print("Destroy current", nextTasklet) #nextTasklet.kill() #nextTasklet.remove() print(stackless.runcount) myStackless.tasklet(keepAlive)() myStackless.tasklet(printCall)(message) stackless.run()
def test_channel_callback(self): res = [] cb = [] def callback_function(chan, task, sending, willblock): cb.append((chan, task, sending, willblock)) stackless.set_channel_callback(callback_function) def f(chan): chan.send('hello') val = chan.receive() res.append(val) chan = stackless.channel() task = stackless.tasklet(f)(chan) val = chan.receive() res.append(val) chan.send('world') assert res == ['hello', 'world'] maintask = stackless.getmain() assert cb == [(chan, maintask, 0, 1), (chan, task, 1, 0), (chan, maintask, 1, 1), (chan, task, 0, 0)]
def tearDown(self): # Tasklets created in pickling tests can be left in the scheduler when they finish. We can feel free to # clean them up for the tests. Any tests that expect to exit with no leaked tasklets should do explicit # assertions to check. mainTasklet = stackless.getmain() current = mainTasklet.next while current is not None and current is not mainTasklet: next = current.next current.kill() current = next self.assertEqual( stackless.getruncount(), 1, "Leakage from this test, with %d tasklets still in the scheduler" % (stackless.getruncount() - 1)) if withThreads and threading.activeCount() > 1: activeThreads = threading.enumerate() activeThreads.remove(threading.currentThread()) if activeThreads: activeThreads[0].join(0.5) if threading.activeCount() > 1: self.assertEqual( threading.activeCount(), 1, "Leakage from other threads, with %d threads running (1 expected)" % (threading.activeCount()))
def test_channel_callback(self): res = [] cb = [] def callback_function(chan, task, sending, willblock): cb.append((chan, task, sending, willblock)) stackless.set_channel_callback(callback_function) def f(chan): chan.send('hello') val = chan.receive() res.append(val) chan = stackless.channel() task = stackless.tasklet(f)(chan) val = chan.receive() res.append(val) chan.send('world') assert res == ['hello','world'] maintask = stackless.getmain() assert cb == [ (chan, maintask, 0, 1), (chan, task, 1, 0), (chan, maintask, 1, 1), (chan, task, 0, 0) ]
def testStackless(self): events = [] def Divide(a, b): return a / b def Worker(name, c): while True: events.append(name + '.wait') events.append('%s/%s' % (name, c.receive())) def Single(name): events.append(name + '.single') def Cooperative(name): while True: events.append(name + '.coop') stackless.schedule() def CooperativeRemove(name): while True: events.append(name + '.corm') stackless.schedule_remove() def Run(): while True: events.append('schedule') i = len(events) stackless.schedule() if i == len(events): break events.append('done') c = stackless.channel() self.assertTrue(stackless.current is stackless.getmain()) self.assertTrue(stackless.getcurrent() is stackless.main) self.assertEqual(1, stackless.getruncount()) self.assertTrue(stackless.current is stackless.getcurrent().next) self.assertTrue(stackless.current is stackless.getcurrent().prev) ta = stackless.tasklet(Worker)('A', c) tb = stackless.tasklet(Worker)('B', c) tc = stackless.tasklet(Worker)('C', c) td = stackless.tasklet().bind(Worker)('D', c) self.assertEqual(5, stackless.getruncount()) self.assertTrue(td is stackless.current.prev) self.assertTrue(ta is stackless.getcurrent().next) self.assertTrue(td.next is stackless.current) self.assertTrue(td.prev is tc) self.assertEqual(c.preference, -1) self.assertEqual(c.balance, 0) del events[:] events.append('send') self.assertEqual(5, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(1, stackless.getruncount()) Run() self.assertEqual( ' '.join(events), 'send A.wait A/msg A.wait B.wait C.wait D.wait schedule done') self.assertEqual(c.preference, -1) self.assertEqual(c.balance, -4) del events[:] events.append('send') c.preference = 0 # same as c.preference = 1 self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() #print ' '.join(events) self.assertEqual(' '.join(events), 'send schedule A/msg A.wait schedule done') self.assertEqual(c.preference, 0) self.assertEqual(c.balance, -4) del events[:] c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send schedule B/msg B.wait schedule done') self.assertEqual(c.preference, 1) del events[:] c.preference = 2 # same as c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(None, c.send('msg')) self.assertEqual(3, stackless.getruncount()) Run() self.assertEqual( ' '.join(events), 'send schedule C/msg C.wait D/msg D.wait schedule done') # Now the doubly-linked list is (d, main, a, b, c). Why? self.assertEqual(c.balance, -4) del events[:] c.preference = 5 events.append('send') self.assertEqual(c.balance, -4) self.assertEqual(1, stackless.getruncount()) t = stackless.tasklet(Single) self.assertEqual(1, stackless.getruncount()) self.assertTrue(t is t('T')) self.assertEqual(2, stackless.getruncount()) t.remove() self.assertEqual(1, stackless.getruncount()) self.assertEqual(t, t.insert()) self.assertEqual(2, stackless.getruncount()) self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertEqual(None, c.send('msg2')) self.assertEqual(None, c.send('msg3')) self.assertEqual(None, c.send('msg4')) self.assertEqual(6, stackless.getruncount()) events.append('a4') self.assertEqual(c.balance, 0) self.assertEqual(None, c.send('msg5')) self.assertEqual(5, stackless.getruncount()) events.append('a5') self.assertEqual(None, c.send('msg6')) self.assertEqual(5, stackless.getruncount()) Run() self.assertEqual( ' '.join(events), 'send a4 T.single A/msg1 A.wait a5 B/msg2 B.wait schedule C/msg3 C.wait D/msg4 D.wait A/msg5 A.wait B/msg6 B.wait schedule done' ) self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) del events[:] self.assertEqual(c.balance, -4) c.preference = 42 self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) self.assertEqual(None, c.send('msg2')) self.assertEqual(c.balance, -2) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(td is stackless.current.prev) self.assertTrue(td.next is stackless.getcurrent()) self.assertTrue(td.prev is tc) self.assertEqual(None, c.send('msg3')) self.assertEqual(c.balance, -1) self.assertTrue(tc is stackless.current.next) self.assertTrue(ta is stackless.getcurrent().prev) self.assertTrue(ta.next is stackless.current) self.assertTrue(ta.prev is td) self.assertEqual(' '.join(events), '') self.assertEqual(4, stackless.getruncount()) t = stackless.tasklet(Single)('T') self.assertTrue(t is stackless.getcurrent().prev) self.assertTrue(ta is t.prev) self.assertTrue(t.alive) self.assertEqual(5, stackless.getruncount()) t.remove() #self.assertTrue(t.next is None # NotImplementedError in greenstackless) self.assertTrue(ta is stackless.current.prev) self.assertTrue(t.alive) self.assertEqual(4, stackless.getruncount()) t.run() self.assertEqual(4, stackless.getruncount()) self.assertTrue(not t.alive) self.assertEqual(' '.join(events), 'T.single') del events[:] td.run() self.assertEqual(' '.join(events), 'D/msg2 D.wait A/msg3 A.wait') del events[:] self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) tc.run() self.assertEqual(' '.join(events), 'C/msg1 C.wait') del events[:] self.assertEqual(c.balance, -4) self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) t = stackless.tasklet(Cooperative)('T') r = stackless.tasklet(CooperativeRemove)('R') u = stackless.tasklet(Cooperative)('U') self.assertEqual(4, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop R.corm U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] t.kill() # This involves t.run(), so u gets run as well. self.assertEqual(' '.join(events), 'U.coop') self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) u.kill() self.assertEqual(1, stackless.getruncount()) typ, val, tb1 = None, None, None try: Divide(42, 0) except ZeroDivisionError: typ, val, tb1 = sys.exc_info() self.assertTrue(typ is ZeroDivisionError) tb2 = None try: if hasattr(stackless.getcurrent(), 'throw'): # greenstackless stackless.current.throw(typ, val, tb1) else: # Stackless stackless.getcurrent().tempval = stackless.bomb(typ, val, tb1) stackless.current.run() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next # greenstackless adds 2 frames. self.assertTrue(tb1 in (tb2, tb3, tb4)) self.assertTrue(tb2) self.assertEqual(-4, c.balance) ta.kill() self.assertEqual(-3, c.balance) td.kill() self.assertEqual(-2, c.balance) tc.kill() self.assertEqual(-1, c.balance) tb.kill() self.assertEqual(0, c.balance) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None def RaiseException(task): task.raise_exception(ValueError, 42) stackless.tasklet(RaiseException)(stackless.getcurrent()) try: stackless.schedule() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '42') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendException(task): assert c.send_exception(ValueError, 43) is None stackless.tasklet(SendException)(stackless.current) try: c.receive() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '43') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2)
def testStackless(self): events = [] def Divide(a, b): return a / b def Worker(name, c): while True: events.append(name + '.wait') events.append('%s/%s' % (name, c.receive())) def Single(name): events.append(name + '.single') def Cooperative(name): while True: events.append(name + '.coop') stackless.schedule() def CooperativeRemove(name): while True: events.append(name + '.corm') stackless.schedule_remove() def Run(): while True: events.append('schedule') i = len(events) stackless.schedule() if i == len(events): break events.append('done') c = stackless.channel() self.assertTrue(stackless.current is stackless.getmain()) self.assertTrue(stackless.getcurrent() is stackless.main) self.assertEqual(1, stackless.getruncount()) self.assertTrue(stackless.current is stackless.getcurrent().next) self.assertTrue(stackless.current is stackless.getcurrent().prev) ta = stackless.tasklet(Worker)('A', c) tb = stackless.tasklet(Worker)('B', c) tc = stackless.tasklet(Worker)('C', c) td = stackless.tasklet().bind(Worker)('D', c) self.assertEqual(5, stackless.getruncount()) self.assertTrue(td is stackless.current.prev) self.assertTrue(ta is stackless.getcurrent().next) self.assertTrue(td.next is stackless.current) self.assertTrue(td.prev is tc) self.assertEqual(c.preference, -1) self.assertEqual(c.balance, 0) del events[:] events.append('send') self.assertEqual(5, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(1, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send A.wait A/msg A.wait B.wait C.wait D.wait schedule done') self.assertEqual(c.preference, -1) self.assertEqual(c.balance, -4) del events[:] events.append('send') c.preference = 0 # same as c.preference = 1 self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() #print ' '.join(events) self.assertEqual(' '.join(events), 'send schedule A/msg A.wait schedule done') self.assertEqual(c.preference, 0) self.assertEqual(c.balance, -4) del events[:] c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send schedule B/msg B.wait schedule done') self.assertEqual(c.preference, 1) del events[:] c.preference = 2 # same as c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(None, c.send('msg')) self.assertEqual(3, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send schedule C/msg C.wait D/msg D.wait schedule done') # Now the doubly-linked list is (d, main, a, b, c). Why? self.assertEqual(c.balance, -4) del events[:] c.preference = 5 events.append('send') self.assertEqual(c.balance, -4) self.assertEqual(1, stackless.getruncount()) t = stackless.tasklet(Single) self.assertEqual(1, stackless.getruncount()) self.assertTrue(t is t('T')) self.assertEqual(2, stackless.getruncount()) t.remove() self.assertEqual(1, stackless.getruncount()) self.assertEqual(t, t.insert()) self.assertEqual(2, stackless.getruncount()) self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertEqual(None, c.send('msg2')) self.assertEqual(None, c.send('msg3')) self.assertEqual(None, c.send('msg4')) self.assertEqual(6, stackless.getruncount()) events.append('a4') self.assertEqual(c.balance, 0) self.assertEqual(None, c.send('msg5')) self.assertEqual(5, stackless.getruncount()) events.append('a5') self.assertEqual(None, c.send('msg6')) self.assertEqual(5, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send a4 T.single A/msg1 A.wait a5 B/msg2 B.wait schedule C/msg3 C.wait D/msg4 D.wait A/msg5 A.wait B/msg6 B.wait schedule done') self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) del events[:] self.assertEqual(c.balance, -4) c.preference = 42 self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) self.assertEqual(None, c.send('msg2')) self.assertEqual(c.balance, -2) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(td is stackless.current.prev) self.assertTrue(td.next is stackless.getcurrent()) self.assertTrue(td.prev is tc) self.assertEqual(None, c.send('msg3')) self.assertEqual(c.balance, -1) self.assertTrue(tc is stackless.current.next) self.assertTrue(ta is stackless.getcurrent().prev) self.assertTrue(ta.next is stackless.current) self.assertTrue(ta.prev is td) self.assertEqual(' '.join(events), '') self.assertEqual(4, stackless.getruncount()) t = stackless.tasklet(Single)('T') self.assertTrue(t is stackless.getcurrent().prev) self.assertTrue(ta is t.prev) self.assertTrue(t.alive) self.assertEqual(5, stackless.getruncount()) t.remove() #self.assertTrue(t.next is None # NotImplementedError in greenstackless) self.assertTrue(ta is stackless.current.prev) self.assertTrue(t.alive) self.assertEqual(4, stackless.getruncount()) t.run() self.assertEqual(4, stackless.getruncount()) self.assertTrue(not t.alive) self.assertEqual(' '.join(events), 'T.single') del events[:] td.run() self.assertEqual(' '.join(events), 'D/msg2 D.wait A/msg3 A.wait') del events[:] self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) tc.run() self.assertEqual(' '.join(events), 'C/msg1 C.wait') del events[:] self.assertEqual(c.balance, -4) self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) t = stackless.tasklet(Cooperative)('T') r = stackless.tasklet(CooperativeRemove)('R') u = stackless.tasklet(Cooperative)('U') self.assertEqual(4, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop R.corm U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] t.kill() # This involves t.run(), so u gets run as well. self.assertEqual(' '.join(events), 'U.coop') self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) u.kill() self.assertEqual(1, stackless.getruncount()) typ, val, tb1 = None, None, None try: Divide(42, 0) except ZeroDivisionError: typ, val, tb1 = sys.exc_info() self.assertTrue(typ is ZeroDivisionError) tb2 = None try: if hasattr(stackless.getcurrent(), 'throw'): # greenstackless stackless.current.throw(typ, val, tb1) else: # Stackless stackless.getcurrent().tempval = stackless.bomb(typ, val, tb1) stackless.current.run() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next # greenstackless adds 2 frames. self.assertTrue(tb1 in (tb2, tb3, tb4) ) self.assertTrue(tb2) self.assertEqual(-4, c.balance) ta.kill() self.assertEqual(-3, c.balance) td.kill() self.assertEqual(-2, c.balance) tc.kill() self.assertEqual(-1, c.balance) tb.kill() self.assertEqual(0, c.balance) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None def RaiseException(task): task.raise_exception(ValueError, 42) stackless.tasklet(RaiseException)(stackless.getcurrent()) try: stackless.schedule() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '42') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendException(task): assert c.send_exception(ValueError, 43) is None stackless.tasklet(SendException)(stackless.current) try: c.receive() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '43') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2)
def TracebackAll(): for t in Tasklets(): if t != stackless.getmain(): Traceback(tasklet=t)
def propagate_exc(self, errtype, *args): stackless.getmain().throw(errtype, *args)
def _getmain(): return _lookup(stackless.getmain())
import stackless allTasklets = dict() mainTasklet = stackless.getmain() class tasklet(stackless.tasklet): def __init__(self, callable): super().__init__(callable) self.name = hash(str(self)) allTasklets[self.name] = self def killComplete(self, force=False): if (self == mainTasklet or self == stackless.getcurrent()) and not force: return 0 super().kill() super().remove() del allTasklets[self.name]
def is_main(): return stackless.getcurrent() == stackless.getmain()
def tearDown(self): # Test that the C-stack didn't change self.assertEqual(self.__initial_cstack_serial, get_serial_last_jump()) # Test, that stackless errorhandler is None and reset it self.assertIsNone(stackless.set_error_handler(None)) # Test, that switch_trap level is 0 and set the level back to 0 try: # get the level without changing it st_level = stackless.switch_trap(0) self.assertEqual(st_level, 0, "switch_trap is %d" % (st_level, )) except AssertionError: # change the level so that the result is 0 stackless.switch_trap(-st_level) raise # Tasklets created in various tests can be left in the scheduler when they finish. We can feel free to # clean them up for the tests. Any tests that expect to exit with no leaked tasklets should do explicit # assertions to check. self.assertTrue( self.__setup_called, "Broken test case: it didn't call super(..., self).setUp()") self.__setup_called = False mainTasklet = stackless.getmain() current = mainTasklet.next while current is not None and current is not mainTasklet: next_ = current.next current.kill() current = next_ # Tasklets with C-stack can create reference leaks, if the C-stack holds a reference, # that keeps the tasklet-object alive. A common case is the call of a tasklet or channel method, # which causes a tasklet switch. The transient bound-method object keeps the tasklet alive. # Here we kill such tasklets. for current in get_tasklets_with_cstate(): if current.blocked: # print("Killing blocked tasklet", current, file=sys.stderr) current.kill() run_count = stackless.getruncount() self.assertEqual( run_count, 1, "Leakage from this test, with %d tasklets still in the scheduler" % (run_count - 1)) watchdog_list = get_watchdog_list(-1) if watchdog_list is not None: self.assertListEqual( watchdog_list, [None], "Watchdog list is not empty: " + repr(watchdog_list)) if withThreads: for (watchdog_list, tid) in [(get_watchdog_list(tid), tid) for tid in stackless.threads if tid != stackless.current.thread_id ]: if watchdog_list is None: continue self.assertListEqual( watchdog_list, [None], "Thread %d: watchdog list is not empty: %r" % (tid, watchdog_list)) preexisting_threads = self.__preexisting_threads self.__preexisting_threads = None # avoid pickling problems, see _addSkip expected_thread_count = len(preexisting_threads) active_count = threading.active_count() if active_count > expected_thread_count: activeThreads = set(threading.enumerate()) activeThreads -= preexisting_threads self.assertNotIn(threading.current_thread(), activeThreads, "tearDown runs on the wrong thread.") while activeThreads: activeThreads.pop().join(0.5) active_count = threading.active_count() self.assertEqual( active_count, expected_thread_count, "Leakage from other threads, with %d threads running (%d expected)" % (active_count, expected_thread_count)) gc.collect( ) # emits warnings about uncollectable objects after each test unexpected_uncollectable = [] for t in [t for t in gc.garbage if isinstance(t, stackless.tasklet)]: if id(t) not in self.__uncollectable_tasklets: unexpected_uncollectable.append(t) # clean up gc.garbage.remove(t) self.__expected_garbage.append(t) self.assertListEqual( unexpected_uncollectable, [], "New uncollectable tasklets: %r" % unexpected_uncollectable)
def propogate_exc(self, errtype, *args): stackless.getmain().throw(errtype, *args)
def yield_(self): main.mainloop.wakeup_tasklets(None) if stackless.getcurrent() == stackless.getmain(): stackless.run()
def testMain(self): """test stackless.main""" main1 = stackless.main main2 = stackless.getmain() self.assertIs(main1, main2) self.assertIsInstance(main1, stackless.tasklet)