Example #1
0
def test_wait_generator_based_task_blocked():
    from asyncio import coroutine, DefaultEventLoopPolicy, set_event_loop, Event

    async def native_coro_part():
        await wait_all_tasks_blocked()
        assert not gen_task._coro.gi_running
        if sys.version_info < (3, 7):
            assert gen_task._coro.gi_yieldfrom.gi_code.co_name == 'wait'
        else:
            assert gen_task._coro.gi_yieldfrom.cr_code.co_name == 'wait'

        event.set()

    @coroutine
    def generator_part():
        yield from event.wait()

    loop = DefaultEventLoopPolicy().new_event_loop()
    try:
        set_event_loop(loop)
        event = Event()
        gen_task = loop.create_task(generator_part())
        loop.run_until_complete(native_coro_part())
    finally:
        set_event_loop(None)
        loop.close()
Example #2
0
 def __init__(self):
     self._lifecycle = None
     self._default_loop = None
     self._watcher_lock = threading.Lock()
     self._watcher = None
     self._policy = DefaultEventLoopPolicy()
     self._policy.new_event_loop = self.new_event_loop
     self.get_event_loop = self._policy.get_event_loop
     self.set_event_loop = self._policy.set_event_loop
Example #3
0
 def test_newSelectorEventLoopFromDefaultEventLoopPolicy(self):
     """
     If we use the L{asyncio.DefaultLoopPolicy} to create a new event loop,
     and then pass that event loop to a new L{AsyncioSelectorReactor},
     this reactor should work properly with L{asyncio.Future}.
     """
     event_loop = DefaultEventLoopPolicy().new_event_loop()
     reactor = AsyncioSelectorReactor(event_loop)
     set_event_loop(event_loop)
     self.assertReactorWorksWithAsyncioFuture(reactor)
     set_event_loop_policy(None)
Example #4
0
class AsyncioSelectorReactorTests(ReactorBuilder, SynchronousTestCase):
    """
    L{AsyncioSelectorReactor} tests.
    """

    _defaultEventLoop = DefaultEventLoopPolicy().new_event_loop()
    _defaultEventLoopIsSelector = isinstance(_defaultEventLoop,
                                             SelectorEventLoop)

    def assertReactorWorksWithAsyncioFuture(self, reactor):
        """
        Ensure that C{reactor} has an event loop that works
        properly with L{asyncio.Future}.
        """
        future = Future()
        result = []

        def completed(future):
            result.append(future.result())
            reactor.stop()

        future.add_done_callback(completed)
        future.set_result(True)

        self.assertEqual(result, [])
        self.runReactor(reactor, timeout=1)
        self.assertEqual(result, [True])

    @skipIf(
        not _defaultEventLoopIsSelector,
        "default event loop: {}\nis not of type SelectorEventLoop "
        "on Python {}.{} ({})".format(
            type(_defaultEventLoop),
            sys.version_info.major,
            sys.version_info.minor,
            platform.getType(),
        ),
    )
    def test_defaultSelectorEventLoopFromGlobalPolicy(self):
        """
        L{AsyncioSelectorReactor} wraps the global policy's event loop
        by default.  This ensures that L{asyncio.Future}s and
        coroutines created by library code that uses
        L{asyncio.get_event_loop} are bound to the same loop.
        """
        reactor = AsyncioSelectorReactor()
        self.assertReactorWorksWithAsyncioFuture(reactor)

    @skipIf(
        not _defaultEventLoopIsSelector,
        "default event loop: {}\nis not of type SelectorEventLoop "
        "on Python {}.{} ({})".format(
            type(_defaultEventLoop),
            sys.version_info.major,
            sys.version_info.minor,
            platform.getType(),
        ),
    )
    def test_newSelectorEventLoopFromDefaultEventLoopPolicy(self):
        """
        If we use the L{asyncio.DefaultLoopPolicy} to create a new event loop,
        and then pass that event loop to a new L{AsyncioSelectorReactor},
        this reactor should work properly with L{asyncio.Future}.
        """
        event_loop = DefaultEventLoopPolicy().new_event_loop()
        reactor = AsyncioSelectorReactor(event_loop)
        set_event_loop(event_loop)
        self.assertReactorWorksWithAsyncioFuture(reactor)
        set_event_loop_policy(None)

    @skipIf(
        _defaultEventLoopIsSelector,
        "default event loop: {}\nis of type SelectorEventLoop "
        "on Python {}.{} ({})".format(
            type(_defaultEventLoop),
            sys.version_info.major,
            sys.version_info.minor,
            platform.getType(),
        ),
    )
    def test_defaultNotASelectorEventLoopFromGlobalPolicy(self):
        """
        On Windows Python 3.5 to 3.7, L{get_event_loop()} returns a
        L{WindowsSelectorEventLoop} by default.
        On Windows Python 3.8+, L{get_event_loop()} returns a
        L{WindowsProactorEventLoop} by default.
        L{AsyncioSelectorReactor} should raise a
        L{TypeError} if the default event loop is not a
        L{WindowsSelectorEventLoop}.
        """
        self.assertRaises(TypeError, AsyncioSelectorReactor)

    @skipIf(not hasWindowsProactorEventLoopPolicy,
            "WindowsProactorEventLoop not available")
    def test_WindowsProactorEventLoop(self):
        """
        L{AsyncioSelectorReactor} will raise a L{TypeError}
        if instantiated with a L{asyncio.WindowsProactorEventLoop}
        """
        event_loop = WindowsProactorEventLoopPolicy().new_event_loop()
        self.assertRaises(TypeError, AsyncioSelectorReactor, event_loop)

    @skipIf(
        not hasWindowsSelectorEventLoopPolicy,
        "WindowsSelectorEventLoop only on Windows",
    )
    def test_WindowsSelectorEventLoop(self):
        """
        L{WindowsSelectorEventLoop} works with L{AsyncioSelectorReactor}
        """
        event_loop = WindowsSelectorEventLoopPolicy().new_event_loop()
        reactor = AsyncioSelectorReactor(event_loop)
        set_event_loop(event_loop)
        self.assertReactorWorksWithAsyncioFuture(reactor)
        set_event_loop_policy(None)

    @skipIf(
        not hasWindowsProactorEventLoopPolicy,
        "WindowsProactorEventLoopPolicy only on Windows",
    )
    def test_WindowsProactorEventLoopPolicy(self):
        """
        L{AsyncioSelectorReactor} will raise a L{TypeError}
        if L{asyncio.WindowsProactorEventLoopPolicy} is default.
        """
        set_event_loop_policy(WindowsProactorEventLoopPolicy())
        with self.assertRaises(TypeError):
            AsyncioSelectorReactor()
        set_event_loop_policy(None)

    @skipIf(
        not hasWindowsSelectorEventLoopPolicy,
        "WindowsSelectorEventLoopPolicy only on Windows",
    )
    def test_WindowsSelectorEventLoopPolicy(self):
        """
        L{AsyncioSelectorReactor} will work if
        if L{asyncio.WindowsSelectorEventLoopPolicy} is default.
        """
        set_event_loop_policy(WindowsSelectorEventLoopPolicy())
        reactor = AsyncioSelectorReactor()
        self.assertReactorWorksWithAsyncioFuture(reactor)
        set_event_loop_policy(None)

    def test_seconds(self):
        """L{seconds} should return a plausible epoch time."""
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(WindowsSelectorEventLoopPolicy())
        reactor = AsyncioSelectorReactor()
        result = reactor.seconds()

        # greater than 2020-01-01
        self.assertGreater(result, 1577836800)

        # less than 2120-01-01
        self.assertLess(result, 4733510400)
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(None)

    def test_delayedCallResetToLater(self):
        """
        L{DelayedCall.reset()} properly reschedules timer to later time
        """
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(WindowsSelectorEventLoopPolicy())

        reactor = AsyncioSelectorReactor()

        timer_called_at = [None]

        def on_timer():
            timer_called_at[0] = reactor.seconds()

        start_time = reactor.seconds()
        dc = reactor.callLater(0, on_timer)
        dc.reset(0.5)
        reactor.callLater(1, reactor.stop)
        reactor.run()

        self.assertIsNotNone(timer_called_at[0])
        self.assertGreater(timer_called_at[0] - start_time, 0.4)
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(None)

    def test_delayedCallResetToEarlier(self):
        """
        L{DelayedCall.reset()} properly reschedules timer to earlier time
        """
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(WindowsSelectorEventLoopPolicy())
        reactor = AsyncioSelectorReactor()

        timer_called_at = [None]

        def on_timer():
            timer_called_at[0] = reactor.seconds()

        start_time = reactor.seconds()
        dc = reactor.callLater(0.5, on_timer)
        dc.reset(0)
        reactor.callLater(1, reactor.stop)

        import io
        from contextlib import redirect_stderr

        stderr = io.StringIO()
        with redirect_stderr(stderr):
            reactor.run()

        self.assertEqual(stderr.getvalue(), "")
        self.assertIsNotNone(timer_called_at[0])
        self.assertLess(timer_called_at[0] - start_time, 0.4)
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(None)

    def test_noCycleReferencesInCallLater(self):
        """
        L{AsyncioSelectorReactor.callLater()} doesn't leave cyclic references
        """
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(WindowsSelectorEventLoopPolicy())
        gc_was_enabled = gc.isenabled()
        gc.disable()
        try:
            objects_before = len(gc.get_objects())
            timer_count = 1000

            reactor = AsyncioSelectorReactor()
            for _ in range(timer_count):
                reactor.callLater(0, lambda: None)
            reactor.runUntilCurrent()

            objects_after = len(gc.get_objects())
            self.assertLess((objects_after - objects_before) / timer_count, 1)
        finally:
            if gc_was_enabled:
                gc.enable()
        if hasWindowsSelectorEventLoopPolicy:
            set_event_loop_policy(None)
Example #5
0
 def get_event_loop_policy(self) -> AbstractEventLoopPolicy:
     return DefaultEventLoopPolicy()