def test_execute_async(self): p = self.klass(max_size=2) self.assertEqual(p.free(), 2) r = [] def foo(a): r.append(a) evt = p.execute(foo, 1) self.assertEqual(p.free(), 1) evt.wait() self.assertEqual(r, [1]) api.sleep(0) self.assertEqual(p.free(), 2) #Once the pool is exhausted, calling an execute forces a yield. p.execute_async(foo, 2) self.assertEqual(1, p.free()) self.assertEqual(r, [1]) p.execute_async(foo, 3) self.assertEqual(0, p.free()) self.assertEqual(r, [1]) p.execute_async(foo, 4) self.assertEqual(r, [1, 2, 3]) api.sleep(0) self.assertEqual(r, [1, 2, 3, 4])
def _test_kill(self, p, first_time, kill_exc_type): event, receiver, proc_flag, queue, callback_flag = self.set_links( p, first_time, kill_exc_type) xxxxx = self.set_links_timeout(p.link_value) p.kill() try: sleep(DELAY) except kill_exc_type: assert first_time, 'raising here only first time' else: assert not first_time, 'Should not raise LinkedKilled here after first time' assert not p, p self.assertRaises(proc.ProcExit, event.wait) self.assertRaises(proc.ProcExit, queue.wait) self.assertRaises(kill_exc_type, proc.waitall, [receiver]) self.assertRaises(kill_exc_type, receiver.wait) sleep(DELAY) assert not proc_flag, proc_flag assert not callback_flag, callback_flag self.check_timed_out(*xxxxx)
def test_multiple_listeners_error(self): # if there was an error while calling a callback # it should not prevent the other listeners from being called # also, all of the errors should be logged, check the output # manually that they are p = proc.spawn(lambda: 5) results = [] def listener1(*args): results.append(10) 1 / 0 def listener2(*args): results.append(20) 2 / 0 def listener3(*args): 3 / 0 p.link(listener1) p.link(listener2) p.link(listener3) sleep(DELAY * 10) assert results in [[10, 20], [20, 10]], results p = proc.spawn(int, 'hello') results = [] p.link(listener1) p.link(listener2) p.link(listener3) sleep(DELAY * 10) assert results in [[10, 20], [20, 10]], results
def _test_return(self, p, first_time, result, kill_exc_type, action): event, receiver, proc_flag, queue, callback_flag = self.set_links( p, first_time, kill_exc_type) # stuff that will time out because there's no unhandled exception: xxxxx = self.set_links_timeout(p.link_exception) try: sleep(DELAY * 2) except kill_exc_type: assert first_time, 'raising here only first time' else: assert not first_time, 'Should not raise LinkedKilled here after first time' assert not p, p self.assertEqual(event.wait(), result) self.assertEqual(queue.wait(), result) self.assertRaises(kill_exc_type, receiver.wait) self.assertRaises(kill_exc_type, proc.waitall, [receiver]) sleep(DELAY) assert not proc_flag, proc_flag assert not callback_flag, callback_flag self.check_timed_out(*xxxxx)
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.assertEqual(collect_pending_results(), 1) q.send(sendings[1]) self.assertEqual(collect_pending_results(), 2) q.send(sendings[2]) q.send(sendings[3]) self.assertEqual(collect_pending_results(), 4)
def test_ref(self): err = Error() err_ref = weakref.ref(err) with timeout(DELAY * 2, err): sleep(DELAY) del err assert not err_ref(), repr(err_ref())
def test_waiters_get_woken(self): # verify that when there's someone waiting on an empty pool # and someone puts an immediately-closed connection back in # the pool that the waiter gets woken self.pool = self.create_pool(max_size=1, max_age=0) conn = self.pool.get() self.assertEqual(self.pool.free(), 0) self.assertEqual(self.pool.waiting(), 0) e = coros.event() def retrieve(pool, ev): c = pool.get() ev.send(c) api.spawn(retrieve, self.pool, e) api.sleep(0) # these two sleeps should advance the retrieve api.sleep(0) # coroutine until it's waiting in get() self.assertEqual(self.pool.free(), 0) self.assertEqual(self.pool.waiting(), 1) self.pool.put(conn) timer = api.exc_after(0.3, api.TimeoutError) conn = e.wait() timer.cancel() self.assertEqual(self.pool.free(), 0) self.assertEqual(self.pool.waiting(), 0)
def prepare(self, local_uri=None, logger=None): """Start a listening port specified by local_uri if there isn't one on that port/interface already. Add `local_uri' to the list of expected URIs, so that incoming connections featuring this URI won't be rejected. If `logger' is provided use it for this connection instead of the default one. """ local_uri = local_uri or protocol.URI(port=2855) need_listen = True if local_uri.port: use_tls, listening_port = self.ports.get(local_uri.host, {}).get( local_uri.port, (None, None)) if listening_port is not None: if use_tls == local_uri.use_tls: need_listen = False else: listening_port.stopListening() sleep( 0 ) # make the reactor really stop listening, so that the next listen() call won't fail self.ports.pop(local_uri.host, {}).pop(local_uri.port, None) else: # caller does not care about port number for (use_tls, port) in self.ports[local_uri.host]: if local_uri.use_tls == use_tls: local_uri.port = port.getHost().port need_listen = False if need_listen: port = self._listen(local_uri, self.factory) self.ports.setdefault(local_uri.host, {})[local_uri.port] = (local_uri.use_tls, port) self.expected_local_uris[local_uri] = logger self.local_uri = local_uri return [local_uri]
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_killing_dormant(self): state = [] def test(): try: state.append('start') sleep(DELAY) except: state.append('except') # catching GreenletExit pass # when switching to hub, hub makes itself the parent of this greenlet, # thus after the function's done, the control will go to the parent # QQQ why the first sleep is not enough? sleep(0) state.append('finished') g = spawn(test) sleep(DELAY / 2) assert state == ['start'], state kill(g) # will not get there, unless switching is explicitly scheduled by kill assert state == ['start', 'except'], state sleep(DELAY) assert state == ['start', 'except', 'finished'], state
def server(sock, site, log=None, max_size=512, serv=None, max_http_version=DEFAULT_MAX_HTTP_VERSION): pool = Pool(max_size=max_size) if serv is None: serv = Server(sock, sock.getsockname(), site, log, max_http_version=max_http_version) try: serv.log.write("httpd starting up on %s\n" % (sock.getsockname(), )) while True: try: new_sock, address = sock.accept() proto = HttpProtocol(new_sock, address, serv) pool.execute_async(proto.handle) api.sleep(0) # sleep to allow other coros to run except KeyboardInterrupt: api.get_hub().remove_descriptor(sock.fileno()) serv.log.write("httpd exiting\n") break finally: try: sock.close() except socket.error: pass
def test_blocks_on_pool(self): waiter = coros.queue(0) def greedy(): self.pool.get() self.pool.get() self.pool.get() self.pool.get() # No one should be waiting yet. self.assertEquals(self.pool.waiting(), 0) # The call to the next get will unschedule this routine. self.pool.get() # So this send should never be called. waiter.send('Failed!') killable = api.spawn(greedy) # no one should be waiting yet. self.assertEquals(self.pool.waiting(), 0) ## Wait for greedy api.sleep(0) ## Greedy should be blocking on the last get self.assertEquals(self.pool.waiting(), 1) ## Send will never be called, so balance should be 0. self.assertFalse(waiter.ready()) api.kill(killable)
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_spawn_is_not_cancelled(self): def func(): spawn(self.lst.pop) # exiting immediatelly, but self.lst.pop must be called spawn(func) sleep(0.1) assert self.lst == [], self.lst
def test_timer_cancelled_upon_greenlet_exit(self): def func(): call_after(0.1, self.lst.pop) spawn(func) assert self.lst == [1], self.lst sleep(0.2) assert self.lst == [1], self.lst
def test_timer_fired(self): def func(): call_after(0.1, self.lst.pop) sleep(0.2) spawn(func) assert self.lst == [1], self.lst sleep(0.3) assert self.lst == [], self.lst
def test_child_process_death(self): prox = saranwrap.wrap({}) pid = saranwrap.getpid(prox) self.assertEqual(os.kill(pid, 0), None) # assert that the process is running del prox # removing all references to the proxy should kill the child process api.sleep(0.1) # need to let the signal handler run self.assertRaises(OSError, os.kill, pid, 0) # raises OSError if pid doesn't exist
def test(self): try: sock = socket.socket() api.call_after(0, sock.close) sock.connect(('python.org', 81)) except Exception: api.sleep(0) else: assert False, 'expected an error here'
def test_reader_failed__send(self): client, server = proc.waitall(self.setup_two_endpoints()) client, server = GreenMSRPSession(client), GreenMSRPSession(server) client.reader_job.kill(InjectedError("Killing client's reader_job")) api.sleep(0.1) self.assertRaises(MSRPSessionError, client.send_chunk, self.make_hello(client.msrp)) self.assertRaises(InjectedError, client.receive_chunk) api.sleep(0.1) self.assertRaises(MSRPSessionError, server.send_chunk, self.make_hello(server.msrp)) self.assertRaises(ConnectionClosed, server.receive_chunk)
def test_return(self): def return25(): return 25 p = self.p = proc.spawn(return25) self._test_return(p, True, 25, proc.LinkedCompleted, lambda: sleep(0)) # repeating the same with dead process for _ in xrange(3): self._test_return(p, False, 25, proc.LinkedCompleted, lambda: sleep(0))
def test_nested_timeout(self): with timeout(DELAY, None): with timeout(DELAY * 2, None): sleep(DELAY * 3) raise AssertionError('should not get there') with timeout(DELAY, _SilentException()): with timeout(DELAY * 2, _SilentException()): sleep(DELAY * 3) raise AssertionError('should not get there')
def killall(procs, *throw_args, **kwargs): if not throw_args: throw_args = (ProcExit, ) wait = kwargs.pop('wait', False) if kwargs: raise TypeError('Invalid keyword argument for proc.killall(): %s' % ', '.join(kwargs.keys())) for g in procs: if not g.dead: api.get_hub().schedule_call_global(0, g.throw, *throw_args) if wait and api.getcurrent() is not api.get_hub().greenlet: api.sleep(0)
def serve(): conn, addr = s.accept() conn.settimeout(delay + 1) try: hello = conn.makefile().readline()[:-2] except socket.timeout: return conn.sendall('you said %s. ' % hello) sleep(delay) conn.sendall('BYE') sleep(delay)
def handle(conn): port.stopListening() try: hello = conn.readline() except ConnectionDone: return conn.write('you said %s. ' % hello) sleep(delay) conn.write('BYE') sleep(delay) conn.loseConnection()
def dont_test_max_idle_many(self): # This test is timing-sensitive. Rename the function without the "dont" to run it, but beware that it could fail or take a while. self.pool = self.create_pool(max_size=2, max_idle=0.02) self.connection, conn2 = self.pool.get(), self.pool.get() self.connection.close() api.sleep(0.01) self.assertEqual(len(self.pool.free_items), 1) conn2.close() self.assertEqual(len(self.pool.free_items), 2) api.sleep(0.02) # trigger cleanup of conn1 but not conn2 self.assertEqual(len(self.pool.free_items), 1)
def dont_test_max_age_many(self): # This test is timing-sensitive. Rename the function without the "dont" to run it, but beware that it could fail or take a while. self.pool = self.create_pool(max_size=2, max_age=0.15) self.connection, conn2 = self.pool.get(), self.pool.get() self.connection.close() self.assertEqual(len(self.pool.free_items), 1) api.sleep(0) # not long enough to trigger the age timeout self.assertEqual(len(self.pool.free_items), 1) api.sleep(0.2) # long enough to trigger age timeout self.assertEqual(len(self.pool.free_items), 0) conn2.close() # should not be added to the free items self.assertEqual(len(self.pool.free_items), 0)
def killall(procs, *throw_args, **kwargs): if not throw_args: throw_args = (ProcExit, ) wait = kwargs.pop('wait', False) if kwargs: raise TypeError('Invalid keyword argument for proc.killall(): %s' % ', '.join(list(kwargs.keys()))) for g in procs: if not g.dead: api.get_hub().schedule_call_global(0, g.throw, *throw_args) if wait and api.getcurrent() is not api.get_hub().greenlet: api.sleep(0)
def test_send_last(self): q = coros.queue() def waiter(q): timer = api.exc_after(0.1, api.TimeoutError) self.assertEqual(q.wait(), 'hi2') timer.cancel() api.spawn(waiter, q) api.sleep(0) api.sleep(0) q.send('hi2')
def test(): try: state.append('start') sleep(DELAY) except: state.append('except') # catching GreenletExit pass # when switching to hub, hub makes itself the parent of this greenlet, # thus after the function's done, the control will go to the parent # QQQ why the first sleep is not enough? sleep(0) state.append('finished')
def kill(self, *throw_args): """Raise an exception in the greenlet. Unschedule the current greenlet so that this Proc can handle the exception (or die). The exception can be specified with throw_args. By default, ProcExit is raised. """ if not self.dead: if not throw_args: throw_args = (ProcExit, ) api.get_hub().schedule_call_global(0, self.greenlet.throw, *throw_args) if api.getcurrent() is not api.get_hub().greenlet: api.sleep(0)
def _keepalive(self): while True: api.sleep(self.KEEPALIVE_INTERVAL) if not self.connected: return try: chunk = self.msrp.make_send_request() chunk.add_header(MSRPHeader('Keep-Alive', 'yes')) self.deliver_chunk(chunk) except MSRPTransactionError, e: if e.code == 408: self.msrp.loseConnection(wait=False) self.set_state('CLOSING') return
def _keepalive(self): while True: api.sleep(self.KEEPALIVE_INTERVAL) if not self.connected: return try: chunk = self.msrp.make_send_request() chunk.add_header(protocol.MSRPHeader('Keep-Alive', 'yes')) self.deliver_chunk(chunk) except MSRPTransactionError as e: if e.code == 408: self.msrp.loseConnection(wait=False) self.set_state('CLOSING') return
def start(self): notification_center = NotificationCenter() if self.greenlet is not None: return self.greenlet = api.getcurrent() current_address = host.default_ip while True: new_address = host.default_ip # make sure the address stabilized api.sleep(5) if new_address != host.default_ip: continue if new_address != current_address: notification_center.post_notification(name='SystemIPAddressDidChange', sender=self, data=NotificationData(old_ip_address=current_address, new_ip_address=new_address)) current_address = new_address api.sleep(5)
try: num = int(sys.argv[1]) except: sys.exit("Supply number of test as an argument, 0, 1, 2 or 3") from twisted.internet import reactor def test(): print block_on(reactor.resolver.getHostByName("www.google.com")) print block_on(reactor.resolver.getHostByName("###")) if num == 0: test() elif num == 1: spawn(test) from eventlib.api import sleep print "sleeping.." sleep(5) print "done sleeping.." elif num == 2: from eventlib.twistedutil import join_reactor spawn(test) reactor.run() elif num == 3: from eventlib.twistedutil import join_reactor print "fails because it's impossible to use block_on from the mainloop" reactor.callLater(0, test) reactor.run()