示例#1
0
    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))
示例#2
0
    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))
示例#3
0
    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))
示例#4
0
    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))
示例#5
0
    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))
示例#6
0
    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))
示例#7
0
    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))
示例#8
0
    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))
示例#9
0
    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))
示例#10
0
    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())
示例#11
0
    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())
示例#12
0
    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))
示例#13
0
    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)
示例#14
0
    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)
示例#15
0
    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'})
示例#16
0
    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'})
示例#17
0
    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))
示例#18
0
    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))
示例#19
0
    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
示例#20
0
 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)
示例#21
0
 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]))
示例#22
0
 def foo():
     done, pending = yield from tasks.wait([b, a])
     self.assertEqual(done, set([a, b]))
     self.assertEqual(pending, set())
     return 42
示例#23
0
 def outer():
     nonlocal proof
     d, p = yield from tasks.wait([inner()], loop=self.loop)
     proof += 100
示例#24
0
 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)
示例#25
0
 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]))
示例#26
0
 def foo():
     done, pending = yield from tasks.wait([b, a])
     self.assertEqual(done, set([a, b]))
     self.assertEqual(pending, set())
     return 42
示例#27
0
 def outer():
     nonlocal proof
     d, p = yield from tasks.wait([inner()], loop=self.loop)
     proof += 100
示例#28
0
    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