def test_sleeping_during_received(self): # ensure that even if the received method cooperatively # yields, eventually all messages are delivered msgs = [] waiters = [] def received((message, evt)): api.sleep(0) msgs.append(message) evt.send() self.actor.received = received waiters.append(coros.event()) self.actor.cast((1, waiters[-1])) api.sleep(0) waiters.append(coros.event()) self.actor.cast((2, waiters[-1])) waiters.append(coros.event()) self.actor.cast((3, waiters[-1])) api.sleep(0) waiters.append(coros.event()) self.actor.cast((4, waiters[-1])) waiters.append(coros.event()) self.actor.cast((5, waiters[-1])) for evt in waiters: evt.wait() self.assertEqual(msgs, [1, 2, 3, 4, 5])
def test_two_simultaneous_connections(self): """ This test is timing-sensitive. """ self.pool = self.create_pool(2) conn = self.pool.get() self.set_up_test_table(conn) self.fill_test_table(conn) curs = conn.cursor() conn2 = self.pool.get() self.set_up_test_table(conn2) self.fill_test_table(conn2) curs2 = conn2.cursor() results = [] LONG_QUERY = "select * from test_table" SHORT_QUERY = "select * from test_table where row_id <= 20" evt = coros.event() def long_running_query(): self.assert_cursor_works(curs) curs.execute(LONG_QUERY) results.append(1) evt.send() evt2 = coros.event() def short_running_query(): self.assert_cursor_works(curs2) curs2.execute(SHORT_QUERY) results.append(2) evt2.send() api.spawn(long_running_query) api.spawn(short_running_query) evt.wait() evt2.wait() results.sort() self.assertEqual([1, 2], results)
def test_multiple(self): self.actor = IncrActor(concurrency=2) total = [0] def received( (func, ev, value) ): func() total[0] += value ev.send() self.actor.received = received def onemoment(): api.sleep(0.1) evt = coros.event() evt1 = coros.event() self.actor.cast( (onemoment, evt, 1) ) self.actor.cast( (lambda: None, evt1, 2) ) evt1.wait() self.assertEqual(total[0], 2) # both coroutines should have been used self.assertEqual(self.actor._pool.current_size, 2) api.sleep(0) self.assertEqual(self.actor._pool.free(), 1) evt.wait() self.assertEqual(total[0], 3) api.sleep(0) self.assertEqual(self.actor._pool.free(), 2)
def test_sleeping_during_received(self): # ensure that even if the received method cooperatively # yields, eventually all messages are delivered msgs = [] waiters = [] def received( (message, evt) ): api.sleep(0) msgs.append(message) evt.send() self.actor.received = received waiters.append(coros.event()) self.actor.cast( (1, waiters[-1])) api.sleep(0) waiters.append(coros.event()) self.actor.cast( (2, waiters[-1]) ) waiters.append(coros.event()) self.actor.cast( (3, waiters[-1]) ) api.sleep(0) waiters.append(coros.event()) self.actor.cast( (4, waiters[-1]) ) waiters.append(coros.event()) self.actor.cast( (5, waiters[-1]) ) for evt in waiters: evt.wait() self.assertEqual(msgs, [1,2,3,4,5])
def test_multiple(self): self.actor = IncrActor(concurrency=2) total = [0] def received((func, ev, value)): func() total[0] += value ev.send() self.actor.received = received def onemoment(): api.sleep(0.1) evt = coros.event() evt1 = coros.event() self.actor.cast((onemoment, evt, 1)) self.actor.cast((lambda: None, evt1, 2)) evt1.wait() self.assertEqual(total[0], 2) # both coroutines should have been used self.assertEqual(self.actor._pool.current_size, 2) api.sleep(0) self.assertEqual(self.actor._pool.free(), 1) evt.wait() self.assertEqual(total[0], 3) api.sleep(0) self.assertEqual(self.actor._pool.free(), 2)
def set_links(self, p, first_time, kill_exc_type): event = coros.event() self.link(p, event) proc_flag = [] def receiver(): sleep(DELAY) proc_flag.append('finished') receiver = proc.spawn(receiver) self.link(p, receiver) queue = coros.queue(1) self.link(p, queue) try: self.link(p) except kill_exc_type: if first_time: raise else: assert first_time, 'not raising here only first time' callback_flag = ['initial'] self.link(p, lambda *args: callback_flag.remove('initial')) for _ in range(10): self.link(p, coros.event()) self.link(p, coros.queue(1)) return event, receiver, proc_flag, queue, callback_flag
def test_cast_multi_1(self): # make sure that both messages make it in there evt = coros.event() evt1 = coros.event() self.actor.cast(evt) self.actor.cast(evt1) evt.wait() evt1.wait() self.assertEqual(self.actor.value, 2)
def test_event(self): p = proc.spawn(lambda : 100) event = coros.event() p.link(event) self.assertEqual(event.wait(), 100) for i in xrange(3): event2 = coros.event() p.link(event2) self.assertEqual(event2.wait(), 100)
def test_send(self): event1 = event() event2 = event() spawn(event1.send, 'hello event1') exc_after(0, ValueError('interrupted')) try: result = event1.wait() except ValueError: X = object() result = with_timeout(DELAY, event2.wait, timeout_value=X) assert result is X, 'Nobody sent anything to event2 yet it received %r' % (result, )
def test_send(self): event1 = event() event2 = event() spawn(event1.send, 'hello event1') exc_after(0, ValueError('interrupted')) try: result = event1.wait() except ValueError: X = object() result = with_timeout(DELAY, event2.wait, timeout_value=X) assert result is X, 'Nobody sent anything to event2 yet it received %r' % ( result, )
def test_wait_noerrors(self): x = proc.spawn(lambda : 1) y = proc.spawn(lambda : 2) z = proc.spawn(lambda : 3) self.assertEqual(proc.waitall([x, y, z]), [1, 2, 3]) e = coros.event() x.link(e) self.assertEqual(e.wait(), 1) x.unlink(e) e = coros.event() x.link(e) self.assertEqual(e.wait(), 1) self.assertEqual([proc.waitall([X]) for X in [x, y, z]], [[1], [2], [3]])
def test_timeout_and_final_write(self): # This test verifies that a write on a socket that we've # stopped listening for doesn't result in an incorrect switch rpipe, wpipe = os.pipe() rfile = os.fdopen(rpipe, "r", 0) wrap_rfile = greenio.GreenPipe(rfile) wfile = os.fdopen(wpipe, "w", 0) wrap_wfile = greenio.GreenPipe(wfile) def sender(evt): api.sleep(0.02) wrap_wfile.write('hi') evt.send('sent via event') from eventlet import coros evt = coros.event() api.spawn(sender, evt) try: # try and get some data off of this pipe # but bail before any is sent api.exc_after(0.01, api.TimeoutError) _c = wrap_rfile.read(1) self.fail() except api.TimeoutError: pass result = evt.wait() self.assertEquals(result, 'sent via event')
def test_multiple_waiters(self): # tests that multiple waiters get their results back q = coros.queue() def waiter(q, evt): evt.send(q.wait()) sendings = ['1', '2', '3', '4'] evts = [coros.event() for x in sendings] for i, x in enumerate(sendings): api.spawn(waiter, q, evts[i]) api.sleep(0.01) # get 'em all waiting results = set() def collect_pending_results(): for i, e in enumerate(evts): timer = api.exc_after(0.001, api.TimeoutError) try: x = e.wait() results.add(x) timer.cancel() except api.TimeoutError: pass # no pending result at that event return len(results) q.send(sendings[0]) self.assertEquals(collect_pending_results(), 1) q.send(sendings[1]) self.assertEquals(collect_pending_results(), 2) q.send(sendings[2]) q.send(sendings[3]) self.assertEquals(collect_pending_results(), 4)
def create(self): id = uuid.uuid4().hex remove = functools.partial(self._remove_event, id) event = coros.event() self.events[id] = weakref.proxy(event, remove) event.id = id return event, id
def test_timeout_and_final_write(self): # This test verifies that a write on a socket that we've # stopped listening for doesn't result in an incorrect switch rpipe, wpipe = os.pipe() rfile = os.fdopen(rpipe,"r",0) wrap_rfile = greenio.GreenPipe(rfile) wfile = os.fdopen(wpipe,"w",0) wrap_wfile = greenio.GreenPipe(wfile) def sender(evt): api.sleep(0.02) wrap_wfile.write('hi') evt.send('sent via event') from eventlet import coros evt = coros.event() api.spawn(sender, evt) try: # try and get some data off of this pipe # but bail before any is sent api.exc_after(0.01, api.TimeoutError) _c = wrap_rfile.read(1) self.fail() except api.TimeoutError: pass result = evt.wait() self.assertEquals(result, 'sent via event')
def test_execute_async(self): done = coros.event() def some_work(): done.send() pool = self.klass(0, 2) pool.execute_async(some_work) done.wait()
def test_waiting_for_event(self): evt = coros.event() value = 'some stuff' def send_to_event(): evt.send(value) api.spawn(send_to_event) self.assertEqual(evt.wait(), value)
def test_reset(self): evt = coros.event() # calling reset before send should throw self.assertRaises(AssertionError, evt.reset) value = 'some stuff' def send_to_event(): evt.send(value) api.spawn(send_to_event) self.assertEqual(evt.wait(), value) # now try it again, and we should get the same exact value, # and we shouldn't be allowed to resend without resetting value2 = 'second stuff' self.assertRaises(AssertionError, evt.send, value2) self.assertEqual(evt.wait(), value) # reset and everything should be happy evt.reset() def send_to_event2(): evt.send(value2) api.spawn(send_to_event2) self.assertEqual(evt.wait(), value2)
def test_cast(self): evt = coros.event() self.actor.cast(evt) evt.wait() evt.reset() self.assertEqual(self.actor.value, 1) self.actor.cast(evt) evt.wait() self.assertEqual(self.actor.value, 2)
def test_double_exception(self): evt = coros.event() # send an exception through the event evt.send(exc=RuntimeError('from test_double_exception')) self.assertRaises(RuntimeError, evt.wait) evt.reset() # shouldn't see the RuntimeError again api.exc_after(0.001, api.TimeoutError('from test_double_exception')) self.assertRaises(api.TimeoutError, evt.wait)
def _add_child_pobj(pobj): """Add the given popen4 object to the list of child processes we are tracking. Return an event object that can be used to get the process' exit code. """ CHILD_POBJS.append(pobj) event = coros.event() CHILD_EVENTS[pobj] = event return event
def test_two_bogus_waiters(self): def do_receive(q, evt): api.exc_after(0, RuntimeError()) try: result = q.wait() evt.send(result) except RuntimeError: evt.send('timed out') q = coros.queue() e1 = coros.event() e2 = coros.event() api.spawn(do_receive, q, e1) api.spawn(do_receive, q, e2) api.sleep(0) q.send('sent') self.assertEquals(e1.wait(), 'timed out') self.assertEquals(e2.wait(), 'timed out') self.assertEquals(q.wait(), 'sent')
def test_send_exc(self): log = [] e = event() def waiter(): try: result = e.wait() log.append(('received', result)) except Exception, ex: log.append(('catched', ex))
def test_zero_max_size(self): q = coros.queue(0) def sender(evt, q): q.send('hi') evt.send('done') def receiver(evt, q): x = q.wait() evt.send(x) e1 = coros.event() e2 = coros.event() api.spawn(sender, e1, q) api.sleep(0) self.assert_(not e1.ready()) api.spawn(receiver, e2, q) self.assertEquals(e2.wait(),'hi') self.assertEquals(e1.wait(),'done')
def test_two_waiters_one_dies(self): def waiter(q, evt): evt.send(q.wait()) def do_receive(q, evt): api.exc_after(0, RuntimeError()) try: result = q.wait() evt.send(result) except RuntimeError: evt.send('timed out') q = coros.queue() dying_evt = coros.event() waiting_evt = coros.event() api.spawn(do_receive, q, dying_evt) api.spawn(waiter, q, waiting_evt) api.sleep(0) q.send('hi') self.assertEquals(dying_evt.wait(), 'timed out') self.assertEquals(waiting_evt.wait(), 'hi')
def test_multiple_waiters(self): evt = coros.event() value = 'some stuff' results = [] def wait_on_event(i_am_done): evt.wait() results.append(True) i_am_done.send() waiters = [] count = 5 for i in range(count): waiters.append(coros.event()) api.spawn(wait_on_event, waiters[-1]) evt.send() for w in waiters: w.wait() self.assertEqual(len(results), count)
def test_returns_immediately(self): self.pool = self.create_pool() conn = self.pool.get() self.set_up_test_table(conn) self.fill_test_table(conn) curs = conn.cursor() results = [] SHORT_QUERY = "select * from test_table" evt = coros.event() def a_query(): self.assert_cursor_works(curs) curs.execute(SHORT_QUERY) results.append(2) evt.send() evt2 = coros.event() api.spawn(a_query) results.append(1) self.assertEqual([1], results) evt.wait() self.assertEqual([1, 2], results)
def wrapper(*args, **kwargs): from twisted.internet import reactor event = coros.event() def wrapped_func(): try: result = func(*args, **kwargs) except: event.send_exception(*sys.exc_info()) else: event.send(result) if threadable.isInIOThread(): callInGreenThread(wrapped_func) else: reactor.callFromThread(callInGreenThread, wrapped_func) return event
def prepare(self, local_uri=None): """Start listening for an incoming MSRP connection using port and use_tls from local_uri if provided. Return full local path, suitable to put in SDP a:path attribute. Note, that `local_uri' may be updated in place. """ if local_uri is None: local_uri = self.generate_local_uri() self.transport_event = coros.event() local_uri.host = gethostbyname(local_uri.host) factory = SpawnFactory(self.transport_event, MSRPTransport, local_uri, logger=self.logger, use_acm=self.use_acm) self.listening_port = self._listen(local_uri, factory) self.local_uri = local_uri return [local_uri]
def test_waiting(self): def do_wait(q, evt): result = q.wait() evt.send(result) q = coros.queue() e1 = coros.event() api.spawn(do_wait, q, e1) api.sleep(0) self.assertEquals(1, waiting(q)) q.send('hi') api.sleep(0) self.assertEquals(0, waiting(q)) self.assertEquals('hi', e1.wait()) self.assertEquals(0, waiting(q))
def complete(self, full_remote_path): """Wait until one of the incoming connections binds using provided full_remote_path. Return connected and bound MSRPTransport instance. If no such binding was made within MSRPBindSessionTimeout.seconds, raise MSRPBindSessionTimeout. """ full_remote_path = tuple(full_remote_path) event = coros.event() self.expected_remote_paths[full_remote_path] = event try: self.new_full_remote_path_notifier.send() with MSRPBindSessionTimeout.timeout(): return event.wait() finally: self.expected_remote_paths.pop(full_remote_path, None)
def test_reentrant(self): pool = self.klass(0,1) def reenter(): waiter = pool.execute(lambda a: a, 'reenter') self.assertEqual('reenter', waiter.wait()) outer_waiter = pool.execute(reenter) outer_waiter.wait() evt = coros.event() def reenter_async(): pool.execute_async(lambda a: a, 'reenter') evt.send('done') pool.execute_async(reenter_async) evt.wait()
def deliver_chunk(self, chunk, event=None): """Send chunk, wait for the transaction response (if Failure-Report header is not 'no'). Return the transaction response if it's a success, raise MSRPTransactionError if it's not. If chunk's Failure-Report is 'no', return None immediately. """ if chunk.failure_report!='no' and event is None: event = coros.event() self.send_chunk(chunk, event.send) if event is not None: response = event.wait() if isinstance(response, Exception): raise response elif 200 <= response.code <= 299: return response raise MSRPTransactionError(comment=response.comment, code=response.code)
def test_killing_unlinked(self): e = coros.event() def func(): try: 1/0 except: e.send_exception(*sys.exc_info()) p = proc.spawn_link(func) try: try: e.wait() except ZeroDivisionError: pass finally: p.unlink() # this disables LinkedCompleted that otherwise would be raised by the next line sleep(DELAY)
def set_links_timeout(self, link): # stuff that won't be touched event = coros.event() link(event) proc_finished_flag = [] def myproc(): sleep(10) proc_finished_flag.append('finished') return 555 myproc = proc.spawn(myproc) link(myproc) queue = coros.queue(0) link(queue) return event, myproc, proc_finished_flag, queue
def test_multiple_coros(self): evt = coros.event() results = [] def producer(): results.append('prod') evt.send() def consumer(): results.append('cons1') evt.wait() results.append('cons2') pool = self.klass(0, 2) done = pool.execute(consumer) pool.execute_async(producer) done.wait() self.assertEquals(['cons1', 'prod', 'cons2'], results)
def test_waiters_that_cancel(self): q = coros.queue() def do_receive(q, evt): api.exc_after(0, RuntimeError()) try: result = q.wait() evt.send(result) except RuntimeError: evt.send('timed out') evt = coros.event() api.spawn(do_receive, q, evt) self.assertEquals(evt.wait(), 'timed out') q.send('hi') self.assertEquals(q.wait(), 'hi')
def test_raising_received(self): msgs = [] def received((message, evt)): evt.send() if message == 'fail': raise RuntimeError() else: msgs.append(message) self.actor.received = received evt = coros.event() self.actor.cast(('fail', evt)) evt.wait() evt.reset() self.actor.cast(('should_appear', evt)) evt.wait() self.assertEqual(['should_appear'], msgs)
def test_server_connectionMade_never_called(self): # trigger case when protocol instance is created, # but it's connectionMade is never called from gnutls.interfaces.twisted import TLSContext, X509Credentials from gnutls.errors import GNUTLSError cred = X509Credentials(None, None) ctx = TLSContext(cred) ev = event() def handle(conn): ev.send("handle must not be called") s = reactor.listenTLS( 0, pr.SpawnFactory(handle, LineOnlyReceiverTransport), ctx) creator = pr.GreenClientCreator(reactor, LineOnlyReceiverTransport) try: conn = creator.connectTLS('127.0.0.1', s.getHost().port, ctx) except GNUTLSError: pass assert ev.poll() is None, repr(ev.poll())