示例#1
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))
示例#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_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())
示例#4
0
    def test_wait(self):
        def gen():
            when = yield
            self.assertAlmostEqual(0.1, when)
            when = yield 0
            self.assertAlmostEqual(0.15, when)
            yield 0.15

        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)

        @tasks.coroutine
        def foo():
            done, pending = yield from tasks.wait([b, a], loop=loop)
            self.assertEqual(done, set([a, b]))
            self.assertEqual(pending, set())
            return 42

        res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
        self.assertEqual(res, 42)
        self.assertAlmostEqual(0.15, loop.time())

        # Doing it again should take no time and exercise a different path.
        res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
        self.assertAlmostEqual(0.15, loop.time())
        self.assertEqual(res, 42)
示例#5
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))
示例#6
0
    def test_wait_with_exception(self):
        def gen():
            when = yield
            self.assertAlmostEqual(0.1, when)
            when = yield 0
            self.assertAlmostEqual(0.15, when)
            yield 0.15

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop)

        @tasks.coroutine
        def sleeper():
            yield from tasks.sleep(0.15, loop=loop)
            raise ZeroDivisionError('really')

        b = tasks.Task(sleeper(), loop=loop)

        @tasks.coroutine
        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)

        loop.run_until_complete(tasks.Task(foo(), loop=loop))
        self.assertAlmostEqual(0.15, loop.time())

        loop.run_until_complete(tasks.Task(foo(), loop=loop))
        self.assertAlmostEqual(0.15, loop.time())
示例#7
0
    def test_wait_with_global_loop(self):
        def gen():
            when = yield
            self.assertAlmostEqual(0.01, when)
            when = yield 0
            self.assertAlmostEqual(0.015, when)
            yield 0.015

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        a = tasks.Task(tasks.sleep(0.01, loop=loop), loop=loop)
        b = tasks.Task(tasks.sleep(0.015, loop=loop), loop=loop)

        @tasks.coroutine
        def foo():
            done, pending = yield from tasks.wait([b, a])
            self.assertEqual(done, set([a, b]))
            self.assertEqual(pending, set())
            return 42

        events.set_event_loop(loop)
        try:
            res = loop.run_until_complete(tasks.Task(foo(), loop=loop))
        finally:
            events.set_event_loop(None)

        self.assertEqual(res, 42)
示例#8
0
 def test_get_with_waiting_putters(self):
     q = queues.Queue(loop=self.loop, maxsize=1)
     tasks.Task(q.put('a'), loop=self.loop)
     tasks.Task(q.put('b'), loop=self.loop)
     test_utils.run_briefly(self.loop)
     self.assertEqual(self.loop.run_until_complete(q.get()), 'a')
     self.assertEqual(self.loop.run_until_complete(q.get()), 'b')
示例#9
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))
示例#10
0
    def test_notify(self):
        cond = locks.Condition(loop=self.loop)
        result = []

        @tasks.coroutine
        def c1(result):
            yield from cond.acquire()
            if (yield from cond.wait()):
                result.append(1)
                cond.release()
            return True

        @tasks.coroutine
        def c2(result):
            yield from cond.acquire()
            if (yield from cond.wait()):
                result.append(2)
                cond.release()
            return True

        @tasks.coroutine
        def c3(result):
            yield from cond.acquire()
            if (yield from cond.wait()):
                result.append(3)
                cond.release()
            return True

        t1 = tasks.Task(c1(result), loop=self.loop)
        t2 = tasks.Task(c2(result), loop=self.loop)
        t3 = tasks.Task(c3(result), loop=self.loop)

        test_utils.run_briefly(self.loop)
        self.assertEqual([], result)

        self.loop.run_until_complete(cond.acquire())
        cond.notify(1)
        cond.release()
        test_utils.run_briefly(self.loop)
        self.assertEqual([1], result)

        self.loop.run_until_complete(cond.acquire())
        cond.notify(1)
        cond.notify(2048)
        cond.release()
        test_utils.run_briefly(self.loop)
        self.assertEqual([1, 2, 3], result)

        self.assertTrue(t1.done())
        self.assertTrue(t1.result())
        self.assertTrue(t2.done())
        self.assertTrue(t2.result())
        self.assertTrue(t3.done())
        self.assertTrue(t3.result())
示例#11
0
    def test_acquire(self):
        lock = locks.Lock(loop=self.loop)
        result = []

        self.assertTrue(self.loop.run_until_complete(lock.acquire()))

        @tasks.coroutine
        def c1(result):
            if (yield from lock.acquire()):
                result.append(1)
            return True

        @tasks.coroutine
        def c2(result):
            if (yield from lock.acquire()):
                result.append(2)
            return True

        @tasks.coroutine
        def c3(result):
            if (yield from lock.acquire()):
                result.append(3)
            return True

        t1 = tasks.Task(c1(result), loop=self.loop)
        t2 = tasks.Task(c2(result), loop=self.loop)

        test_utils.run_briefly(self.loop)
        self.assertEqual([], result)

        lock.release()
        test_utils.run_briefly(self.loop)
        self.assertEqual([1], result)

        test_utils.run_briefly(self.loop)
        self.assertEqual([1], result)

        t3 = tasks.Task(c3(result), loop=self.loop)

        lock.release()
        test_utils.run_briefly(self.loop)
        self.assertEqual([1, 2], result)

        lock.release()
        test_utils.run_briefly(self.loop)
        self.assertEqual([1, 2, 3], result)

        self.assertTrue(t1.done())
        self.assertTrue(t1.result())
        self.assertTrue(t2.done())
        self.assertTrue(t2.result())
        self.assertTrue(t3.done())
        self.assertTrue(t3.result())
示例#12
0
    def test_put_cancelled_race(self):
        q = queues.Queue(loop=self.loop, maxsize=1)

        tasks.Task(q.put('a'), loop=self.loop)
        tasks.Task(q.put('c'), loop=self.loop)
        t = tasks.Task(q.put('b'), loop=self.loop)

        test_utils.run_briefly(self.loop)
        t.cancel()
        test_utils.run_briefly(self.loop)
        self.assertTrue(t.done())
        self.assertEqual(q.get_nowait(), 'a')
        self.assertEqual(q.get_nowait(), 'c')
示例#13
0
    def test_get_cancelled_race(self):
        q = queues.Queue(loop=self.loop)

        t1 = tasks.Task(q.get(), loop=self.loop)
        t2 = tasks.Task(q.get(), loop=self.loop)

        test_utils.run_briefly(self.loop)
        t1.cancel()
        test_utils.run_briefly(self.loop)
        self.assertTrue(t1.done())
        q.put_nowait('a')
        test_utils.run_briefly(self.loop)
        self.assertEqual(t2.result(), 'a')
示例#14
0
    def test_task_class(self):
        @tasks.coroutine
        def notmuch():
            return 'ok'

        t = tasks.Task(notmuch(), loop=self.loop)
        self.loop.run_until_complete(t)
        self.assertTrue(t.done())
        self.assertEqual(t.result(), 'ok')
        self.assertIs(t._loop, self.loop)

        loop = events.new_event_loop()
        t = tasks.Task(notmuch(), loop=loop)
        self.assertIs(t._loop, loop)
        loop.close()
示例#15
0
    def test_wait_for_with_global_loop(self):
        def gen():
            when = yield
            self.assertAlmostEqual(0.2, when)
            when = yield 0
            self.assertAlmostEqual(0.01, when)
            yield 0.01

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        @tasks.coroutine
        def foo():
            yield from tasks.sleep(0.2, loop=loop)
            return 'done'

        events.set_event_loop(loop)
        try:
            fut = tasks.Task(foo(), loop=loop)
            with self.assertRaises(futures.TimeoutError):
                loop.run_until_complete(tasks.wait_for(fut, 0.01))
        finally:
            events.set_event_loop(None)

        self.assertAlmostEqual(0.01, loop.time())
        self.assertFalse(fut.done())

        # move forward to close generator
        loop.advance_time(10)
        loop.run_until_complete(fut)
示例#16
0
    def test_wait_for(self):
        def gen():
            when = yield
            self.assertAlmostEqual(0.2, when)
            when = yield 0
            self.assertAlmostEqual(0.1, when)
            when = yield 0.1
            self.assertAlmostEqual(0.4, when)
            yield 0.1

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        @tasks.coroutine
        def foo():
            yield from tasks.sleep(0.2, loop=loop)
            return 'done'

        fut = tasks.Task(foo(), loop=loop)

        with self.assertRaises(futures.TimeoutError):
            loop.run_until_complete(tasks.wait_for(fut, 0.1, loop=loop))

        self.assertFalse(fut.done())
        self.assertAlmostEqual(0.1, loop.time())

        # wait for result
        res = loop.run_until_complete(tasks.wait_for(fut, 0.3, loop=loop))
        self.assertEqual(res, 'done')
        self.assertAlmostEqual(0.2, loop.time())
示例#17
0
    def test_stop_while_run_in_complete(self):
        def gen():
            when = yield
            self.assertAlmostEqual(0.1, when)
            when = yield 0.1
            self.assertAlmostEqual(0.2, when)
            when = yield 0.1
            self.assertAlmostEqual(0.3, when)
            yield 0.1

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        x = 0
        waiters = []

        @tasks.coroutine
        def task():
            nonlocal x
            while x < 10:
                waiters.append(tasks.sleep(0.1, loop=loop))
                yield from waiters[-1]
                x += 1
                if x == 2:
                    loop.stop()

        t = tasks.Task(task(), loop=loop)
        self.assertRaises(RuntimeError, loop.run_until_complete, t)
        self.assertFalse(t.done())
        self.assertEqual(x, 2)
        self.assertAlmostEqual(0.3, loop.time())

        # close generators
        for w in waiters:
            w.close()
示例#18
0
    def test_cancel_task_ignoring(self):
        fut1 = futures.Future(loop=self.loop)
        fut2 = futures.Future(loop=self.loop)
        fut3 = futures.Future(loop=self.loop)

        @tasks.coroutine
        def task():
            yield from fut1
            try:
                yield from fut2
            except futures.CancelledError:
                pass
            res = yield from fut3
            return res

        t = tasks.Task(task(), loop=self.loop)
        test_utils.run_briefly(self.loop)
        self.assertIs(t._fut_waiter, fut1)  # White-box test.
        fut1.set_result(None)
        test_utils.run_briefly(self.loop)
        self.assertIs(t._fut_waiter, fut2)  # White-box test.
        t.cancel()
        self.assertTrue(fut2.cancelled())
        test_utils.run_briefly(self.loop)
        self.assertIs(t._fut_waiter, fut3)  # White-box test.
        fut3.set_result(42)
        res = self.loop.run_until_complete(t)
        self.assertEqual(res, 42)
        self.assertFalse(fut3.cancelled())
        self.assertFalse(t.cancelled())
示例#19
0
 def queue_get():
     loop.call_later(0.01, q.get_nowait)
     queue_put_task = tasks.Task(queue_put(), loop=loop)
     yield from started.wait()
     self.assertFalse(finished)
     yield from queue_put_task
     self.assertTrue(finished)
示例#20
0
            def handle_client_callback(self, client_reader, client_writer):
                task = tasks.Task(client_reader.readline(), loop=self.loop)

                def done(task):
                    client_writer.write(task.result())

                task.add_done_callback(done)
示例#21
0
    def test_coroutine_non_gen_function_return_future(self):
        fut = futures.Future(loop=self.loop)

        @tasks.coroutine
        def func():
            return fut

        @tasks.coroutine
        def coro():
            fut.set_result('test')

        t1 = tasks.Task(func(), loop=self.loop)
        t2 = tasks.Task(coro(), loop=self.loop)
        res = self.loop.run_until_complete(t1)
        self.assertEqual(res, 'test')
        self.assertIsNone(t2.result())
示例#22
0
    def test_clear_with_waiters(self):
        ev = locks.Event(loop=self.loop)
        result = []

        @tasks.coroutine
        def c1(result):
            if (yield from ev.wait()):
                result.append(1)
            return True

        t = tasks.Task(c1(result), loop=self.loop)
        test_utils.run_briefly(self.loop)
        self.assertEqual([], result)

        ev.set()
        ev.clear()
        self.assertFalse(ev.is_set())

        ev.set()
        ev.set()
        self.assertEqual(1, len(ev._waiters))

        test_utils.run_briefly(self.loop)
        self.assertEqual([1], result)
        self.assertEqual(0, len(ev._waiters))

        self.assertTrue(t.done())
        self.assertTrue(t.result())
示例#23
0
    def test_baseexception_during_cancel(self):
        def gen():
            when = yield
            self.assertAlmostEqual(10.0, when)
            yield 0

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        @tasks.coroutine
        def sleeper():
            yield from tasks.sleep(10, loop=loop)

        base_exc = BaseException()

        @tasks.coroutine
        def notmutch():
            try:
                yield from sleeper()
            except futures.CancelledError:
                raise base_exc

        task = tasks.Task(notmutch(), loop=loop)
        test_utils.run_briefly(loop)

        task.cancel()
        self.assertFalse(task.done())

        self.assertRaises(BaseException, test_utils.run_briefly, loop)

        self.assertTrue(task.done())
        self.assertFalse(task.cancelled())
        self.assertIs(task.exception(), base_exc)
示例#24
0
    def test_step_result_future(self):
        # If coroutine returns future, task waits on this future.

        class Fut(futures.Future):
            def __init__(self, *args, **kwds):
                self.cb_added = False
                super().__init__(*args, **kwds)

            def add_done_callback(self, fn):
                self.cb_added = True
                super().add_done_callback(fn)

        fut = Fut(loop=self.loop)
        result = None

        @tasks.coroutine
        def wait_for_future():
            nonlocal result
            result = yield from fut

        t = tasks.Task(wait_for_future(), loop=self.loop)
        test_utils.run_briefly(self.loop)
        self.assertTrue(fut.cb_added)

        res = object()
        fut.set_result(res)
        test_utils.run_briefly(self.loop)
        self.assertIs(res, result)
        self.assertTrue(t.done())
        self.assertIsNone(t.result())
示例#25
0
    def test_sleep_cancel(self):
        def gen():
            when = yield
            self.assertAlmostEqual(10.0, when)
            yield 0

        loop = test_utils.TestLoop(gen)
        self.addCleanup(loop.close)

        t = tasks.Task(tasks.sleep(10.0, 'yeah', loop=loop), loop=loop)

        handle = None
        orig_call_later = loop.call_later

        def call_later(self, delay, callback, *args):
            nonlocal handle
            handle = orig_call_later(self, delay, callback, *args)
            return handle

        loop.call_later = call_later
        test_utils.run_briefly(loop)

        self.assertFalse(handle._cancelled)

        t.cancel()
        test_utils.run_briefly(loop)
        self.assertTrue(handle._cancelled)
示例#26
0
    def test_cancel_race(self):
        # Several tasks:
        # - A acquires the lock
        # - B is blocked in aqcuire()
        # - C is blocked in aqcuire()
        #
        # Now, concurrently:
        # - B is cancelled
        # - A releases the lock
        #
        # If B's waiter is marked cancelled but not yet removed from
        # _waiters, A's release() call will crash when trying to set
        # B's waiter; instead, it should move on to C's waiter.

        # Setup: A has the lock, b and c are waiting.
        lock = locks.Lock(loop=self.loop)

        @tasks.coroutine
        def lockit(name, blocker):
            yield from lock.acquire()
            try:
                if blocker is not None:
                    yield from blocker
            finally:
                lock.release()

        fa = futures.Future(loop=self.loop)
        ta = tasks.Task(lockit('A', fa), loop=self.loop)
        test_utils.run_briefly(self.loop)
        self.assertTrue(lock.locked())
        tb = tasks.Task(lockit('B', None), loop=self.loop)
        test_utils.run_briefly(self.loop)
        self.assertEqual(len(lock._waiters), 1)
        tc = tasks.Task(lockit('C', None), loop=self.loop)
        test_utils.run_briefly(self.loop)
        self.assertEqual(len(lock._waiters), 2)

        # Create the race and check.
        # Without the fix this failed at the last assert.
        fa.set_result(None)
        tb.cancel()
        self.assertTrue(lock._waiters[0].cancelled())
        test_utils.run_briefly(self.loop)
        self.assertFalse(lock.locked())
        self.assertTrue(ta.done())
        self.assertTrue(tb.cancelled())
        self.assertTrue(tc.done())
示例#27
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)
示例#28
0
    def test_task_repr(self):
        @tasks.coroutine
        def notmuch():
            yield from []
            return 'abc'

        t = tasks.Task(notmuch(), loop=self.loop)
        t.add_done_callback(Dummy())
        self.assertEqual(repr(t), 'Task(<notmuch>)<PENDING, [Dummy()]>')
        t.cancel()  # Does not take immediate effect!
        self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLING, [Dummy()]>')
        self.assertRaises(futures.CancelledError, self.loop.run_until_complete,
                          t)
        self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLED>')
        t = tasks.Task(notmuch(), loop=self.loop)
        self.loop.run_until_complete(t)
        self.assertEqual(repr(t), "Task(<notmuch>)<result='abc'>")
示例#29
0
    def test_wait_cancel(self):
        ev = locks.Event(loop=self.loop)

        wait = tasks.Task(ev.wait(), loop=self.loop)
        self.loop.call_soon(wait.cancel)
        self.assertRaises(futures.CancelledError, self.loop.run_until_complete,
                          wait)
        self.assertFalse(ev._waiters)
示例#30
0
 def doit():
     sleeper = tasks.Task(sleep(5000), loop=loop)
     loop.call_later(0.1, sleeper.cancel)
     try:
         yield from sleeper
     except futures.CancelledError:
         return 'cancelled'
     else:
         return 'slept in'