def test_wait_concurrent_complete(self): def gen(): when = yield self.assertAlmostEqual(0.1, when) when = yield 0 self.assertAlmostEqual(0.15, when) when = yield 0 self.assertAlmostEqual(0.1, when) yield 0.1 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) done, pending = loop.run_until_complete( tasks.wait([b, a], timeout=0.1, loop=loop)) self.assertEqual(done, set([a])) self.assertEqual(pending, set([b])) self.assertAlmostEqual(0.1, loop.time()) # move forward to close generator loop.advance_time(10) loop.run_until_complete(tasks.wait([a, b], loop=loop))
def test_wait_first_completed(self): def gen(): when = yield self.assertAlmostEqual(10.0, when) when = yield 0 self.assertAlmostEqual(0.1, when) yield 0.1 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) b = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) task = tasks.Task( tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, loop=loop), loop=loop) done, pending = loop.run_until_complete(task) self.assertEqual({b}, done) self.assertEqual({a}, pending) self.assertFalse(a.done()) self.assertTrue(b.done()) self.assertIsNone(b.result()) self.assertAlmostEqual(0.1, loop.time()) # move forward to close generator loop.advance_time(10) loop.run_until_complete(tasks.wait([a, b], loop=loop))
def test_wait_first_exception_in_wait(self): def gen(): when = yield self.assertAlmostEqual(10.0, when) when = yield 0 self.assertAlmostEqual(0.01, when) yield 0.01 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) # first_exception, exception during waiting a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) @tasks.coroutine def exc(): yield from tasks.sleep(0.01, loop=loop) raise ZeroDivisionError('err') b = tasks.Task(exc(), loop=loop) task = tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION, loop=loop) done, pending = loop.run_until_complete(task) self.assertEqual({b}, done) self.assertEqual({a}, pending) self.assertAlmostEqual(0.01, loop.time()) # move forward to close generator loop.advance_time(10) loop.run_until_complete(tasks.wait([a, b], loop=loop))
def test_wait_first_completed(self): def gen(): when = yield self.assertAlmostEqual(10.0, when) when = yield 0 self.assertAlmostEqual(0.1, when) yield 0.1 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) b = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) task = tasks.Task(tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, loop=loop), loop=loop) done, pending = loop.run_until_complete(task) self.assertEqual({b}, done) self.assertEqual({a}, pending) self.assertFalse(a.done()) self.assertTrue(b.done()) self.assertIsNone(b.result()) self.assertAlmostEqual(0.1, loop.time()) # move forward to close generator loop.advance_time(10) loop.run_until_complete(tasks.wait([a, b], loop=loop))
def test_wait_errors(self): self.assertRaises( ValueError, self.loop.run_until_complete, tasks.wait(set(), loop=self.loop)) self.assertRaises( ValueError, self.loop.run_until_complete, tasks.wait([tasks.sleep(10.0, loop=self.loop)], return_when=-1, loop=self.loop))
def test_wait_errors(self): self.assertRaises(ValueError, self.loop.run_until_complete, tasks.wait(set(), loop=self.loop)) self.assertRaises( ValueError, self.loop.run_until_complete, tasks.wait([tasks.sleep(10.0, loop=self.loop)], return_when=-1, loop=self.loop))
def test_current_task_with_interleaving_tasks(self): self.assertIsNone(tasks.Task.current_task(loop=self.loop)) fut1 = futures.Future(loop=self.loop) fut2 = futures.Future(loop=self.loop) @tasks.coroutine def coro1(loop): self.assertTrue(tasks.Task.current_task(loop=loop) is task1) yield from fut1 self.assertTrue(tasks.Task.current_task(loop=loop) is task1) fut2.set_result(True) @tasks.coroutine def coro2(loop): self.assertTrue(tasks.Task.current_task(loop=loop) is task2) fut1.set_result(True) yield from fut2 self.assertTrue(tasks.Task.current_task(loop=loop) is task2) task1 = tasks.Task(coro1(self.loop), loop=self.loop) task2 = tasks.Task(coro2(self.loop), loop=self.loop) self.loop.run_until_complete(tasks.wait((task1, task2), loop=self.loop)) self.assertIsNone(tasks.Task.current_task(loop=self.loop))
def test_wait_really_done(self): # there is possibility that some tasks in the pending list # became done but their callbacks haven't all been called yet @tasks.coroutine def coro1(): yield @tasks.coroutine def coro2(): yield yield a = tasks.Task(coro1(), loop=self.loop) b = tasks.Task(coro2(), loop=self.loop) task = tasks.Task(tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, loop=self.loop), loop=self.loop) done, pending = self.loop.run_until_complete(task) self.assertEqual({a, b}, done) self.assertTrue(a.done()) self.assertIsNone(a.result()) self.assertTrue(b.done()) self.assertIsNone(b.result())
def test_wait_really_done(self): # there is possibility that some tasks in the pending list # became done but their callbacks haven't all been called yet @tasks.coroutine def coro1(): yield @tasks.coroutine def coro2(): yield yield a = tasks.Task(coro1(), loop=self.loop) b = tasks.Task(coro2(), loop=self.loop) task = tasks.Task( tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, loop=self.loop), loop=self.loop) done, pending = self.loop.run_until_complete(task) self.assertEqual({a, b}, done) self.assertTrue(a.done()) self.assertIsNone(a.result()) self.assertTrue(b.done()) self.assertIsNone(b.result())
def test_exception_waiter(self): stream = streams.StreamReader(loop=self.loop) @tasks.coroutine def set_err(): stream.set_exception(ValueError()) @tasks.coroutine def readline(): yield from stream.readline() t1 = tasks.Task(stream.readline(), loop=self.loop) t2 = tasks.Task(set_err(), loop=self.loop) self.loop.run_until_complete(tasks.wait([t1, t2], loop=self.loop)) self.assertRaises(ValueError, t1.result)
def test_as_completed_concurrent(self): def gen(): when = yield self.assertAlmostEqual(0.05, when) when = yield 0 self.assertAlmostEqual(0.05, when) yield 0.05 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) a = tasks.sleep(0.05, 'a', loop=loop) b = tasks.sleep(0.05, 'b', loop=loop) fs = {a, b} futs = list(tasks.as_completed(fs, loop=loop)) self.assertEqual(len(futs), 2) waiter = tasks.wait(futs, loop=loop) done, pending = loop.run_until_complete(waiter) self.assertEqual(set(f.result() for f in done), {'a', 'b'})
def test_as_completed_with_timeout(self): def gen(): when = yield self.assertAlmostEqual(0.12, when) when = yield 0 self.assertAlmostEqual(0.1, when) when = yield 0 self.assertAlmostEqual(0.15, when) when = yield 0.1 self.assertAlmostEqual(0.12, when) yield 0.02 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) a = tasks.sleep(0.1, 'a', loop=loop) b = tasks.sleep(0.15, 'b', loop=loop) @tasks.coroutine def foo(): values = [] for f in tasks.as_completed([a, b], timeout=0.12, loop=loop): try: v = yield from f values.append((1, v)) except futures.TimeoutError as exc: values.append((2, exc)) return values res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) self.assertEqual(len(res), 2, res) self.assertEqual(res[0], (1, 'a')) self.assertEqual(res[1][0], 2) self.assertIsInstance(res[1][1], futures.TimeoutError) self.assertAlmostEqual(0.12, loop.time()) # move forward to close generator loop.advance_time(10) loop.run_until_complete(tasks.wait([a, b], loop=loop))
def create_connection(self, protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None): """XXX""" if server_hostname is not None and not ssl: raise ValueError('server_hostname is only meaningful with ssl') if server_hostname is None and ssl: # Use host as default for server_hostname. It is an error # if host is empty or not set, e.g. when an # already-connected socket was passed or when only a port # is given. To avoid this error, you can pass # server_hostname='' -- this will bypass the hostname # check. (This also means that if host is a numeric # IP/IPv6 address, we will attempt to verify that exact # address; this will probably fail, but it is possible to # create a certificate for a specific IP address, so we # don't judge it here.) if not host: raise ValueError('You must set server_hostname ' 'when using ssl without a host') server_hostname = host if host is not None or port is not None: if sock is not None: raise ValueError( 'host/port and sock can not be specified at the same time') f1 = self.getaddrinfo( host, port, family=family, type=socket.SOCK_STREAM, proto=proto, flags=flags) fs = [f1] if local_addr is not None: f2 = self.getaddrinfo( *local_addr, family=family, type=socket.SOCK_STREAM, proto=proto, flags=flags) fs.append(f2) else: f2 = None yield from tasks.wait(fs, loop=self) infos = f1.result() if not infos: raise OSError('getaddrinfo() returned empty list') if f2 is not None: laddr_infos = f2.result() if not laddr_infos: raise OSError('getaddrinfo() returned empty list') exceptions = [] for family, type, proto, cname, address in infos: try: sock = socket.socket(family=family, type=type, proto=proto) sock.setblocking(False) if f2 is not None: for _, _, _, _, laddr in laddr_infos: try: sock.bind(laddr) break except OSError as exc: exc = OSError( exc.errno, 'error while ' 'attempting to bind on address ' '{!r}: {}'.format( laddr, exc.strerror.lower())) exceptions.append(exc) else: sock.close() sock = None continue yield from self.sock_connect(sock, address) except OSError as exc: if sock is not None: sock.close() exceptions.append(exc) else: break else: if len(exceptions) == 1: raise exceptions[0] else: # If they all have the same str(), raise one. model = str(exceptions[0]) if all(str(exc) == model for exc in exceptions): raise exceptions[0] # Raise a combined exception so the user can see all # the various error messages. raise OSError('Multiple exceptions: {}'.format( ', '.join(str(exc) for exc in exceptions))) elif sock is None: raise ValueError( 'host and port was not specified and no sock specified') sock.setblocking(False) protocol = protocol_factory() waiter = futures.Future(loop=self) if ssl: sslcontext = None if isinstance(ssl, bool) else ssl transport = self._make_ssl_transport( sock, protocol, sslcontext, waiter, server_side=False, server_hostname=server_hostname) else: transport = self._make_socket_transport(sock, protocol, waiter) yield from waiter return transport, protocol
def foo(): done, pending = yield from tasks.wait([b, a], loop=loop) self.assertEqual(len(done), 2) self.assertEqual(pending, set()) errors = set(f for f in done if f.exception() is not None) self.assertEqual(len(errors), 1)
def foo(): done, pending = yield from tasks.wait([b, a], timeout=0.11, loop=loop) self.assertEqual(done, set([a])) self.assertEqual(pending, set([b]))
def foo(): done, pending = yield from tasks.wait([b, a]) self.assertEqual(done, set([a, b])) self.assertEqual(pending, set()) return 42
def outer(): nonlocal proof d, p = yield from tasks.wait([inner()], loop=self.loop) proof += 100
def create_connection(self, protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None): """XXX""" if server_hostname is not None and not ssl: raise ValueError('server_hostname is only meaningful with ssl') if server_hostname is None and ssl: # Use host as default for server_hostname. It is an error # if host is empty or not set, e.g. when an # already-connected socket was passed or when only a port # is given. To avoid this error, you can pass # server_hostname='' -- this will bypass the hostname # check. (This also means that if host is a numeric # IP/IPv6 address, we will attempt to verify that exact # address; this will probably fail, but it is possible to # create a certificate for a specific IP address, so we # don't judge it here.) if not host: raise ValueError('You must set server_hostname ' 'when using ssl without a host') server_hostname = host if host is not None or port is not None: if sock is not None: raise ValueError( 'host/port and sock can not be specified at the same time') f1 = self.getaddrinfo(host, port, family=family, type=socket.SOCK_STREAM, proto=proto, flags=flags) fs = [f1] if local_addr is not None: f2 = self.getaddrinfo(*local_addr, family=family, type=socket.SOCK_STREAM, proto=proto, flags=flags) fs.append(f2) else: f2 = None yield from tasks.wait(fs, loop=self) infos = f1.result() if not infos: raise OSError('getaddrinfo() returned empty list') if f2 is not None: laddr_infos = f2.result() if not laddr_infos: raise OSError('getaddrinfo() returned empty list') exceptions = [] for family, type, proto, cname, address in infos: try: sock = socket.socket(family=family, type=type, proto=proto) sock.setblocking(False) if f2 is not None: for _, _, _, _, laddr in laddr_infos: try: sock.bind(laddr) break except OSError as exc: exc = OSError( exc.errno, 'error while ' 'attempting to bind on address ' '{!r}: {}'.format(laddr, exc.strerror.lower())) exceptions.append(exc) else: sock.close() sock = None continue yield from self.sock_connect(sock, address) except OSError as exc: if sock is not None: sock.close() exceptions.append(exc) else: break else: if len(exceptions) == 1: raise exceptions[0] else: # If they all have the same str(), raise one. model = str(exceptions[0]) if all(str(exc) == model for exc in exceptions): raise exceptions[0] # Raise a combined exception so the user can see all # the various error messages. raise OSError('Multiple exceptions: {}'.format(', '.join( str(exc) for exc in exceptions))) elif sock is None: raise ValueError( 'host and port was not specified and no sock specified') sock.setblocking(False) protocol = protocol_factory() waiter = futures.Future(loop=self) if ssl: sslcontext = None if isinstance(ssl, bool) else ssl transport = self._make_ssl_transport( sock, protocol, sslcontext, waiter, server_side=False, server_hostname=server_hostname) else: transport = self._make_socket_transport(sock, protocol, waiter) yield from waiter return transport, protocol