Ejemplo n.º 1
0
    async def test_run_on_shutdown_registers_a_coroutine_to_be_executed_on_shutdown(
        self
    ):
        coro = CoroutineMock()

        self.app.run_on_shutdown(coro)
        self.assertIn(coro, self.app._on_shutdown)

        await self.app.shutdown()
        coro.assert_awaited_once_with(self.app)
Ejemplo n.º 2
0
    async def test_run_on_startup_registers_a_coroutine_to_be_executed_on_startup(
        self
    ):
        coro = CoroutineMock()

        self.app.run_on_startup(coro)

        self.assertEqual(coro, self.app._on_startup[-1])

        await self.app.startup()
        coro.assert_awaited_once_with(self.app)
Ejemplo n.º 3
0
    async def test_auth_guarded0(self):
        """ Assert the guarded coroutine is awaited when awaiting for the
            guarder
        """
        f = CoroutineMock()
        gf = module.auth_guarded(f)

        await gf(self.api, "args", kw="kwargs")

        self.api._auth_free.wait.assert_awaited_once_with()
        f.assert_awaited_once_with(self.api, "args", kw="kwargs")
Ejemplo n.º 4
0
    async def test_send(self):
        mock_ws = MagicMock()
        mock_send = CoroutineMock()
        mock_ws.send_packet = mock_send
        self._client._ws = mock_ws

        dest = "dest"
        payload = "payload"

        await self._client.send(dest, payload)

        mock_send.assert_awaited_once_with(dest, payload, ANY)
Ejemplo n.º 5
0
    async def test_auth_guarded1(self):
        """ Assert a non-401 http error is forwarded
        """
        e = module.aiohttp.ClientResponseError(
                "request_info", "history", status=400)
        f = CoroutineMock(side_effect=e)
        gf = module.auth_guarded(f)

        with self.assertRaises(type(e)):
            await gf(self.api, "args", kw="kwargs")

        self.api._auth_free.wait.assert_awaited_once_with()
        f.assert_awaited_once_with(self.api, "args", kw="kwargs")
Ejemplo n.º 6
0
    async def test_auth_guarded2(self):
        """ Assert an http error is forwarded if authentication is not enabled
        """
        e = module.aiohttp.ClientResponseError(
                "request_info", "history", status=401)
        self.api.auth_enabled.return_value = False
        f = CoroutineMock(side_effect=e)
        gf = module.auth_guarded(f)

        with self.assertRaises(type(e)):
            await gf(self.api, "args", kw="kwargs")

        self.api._auth_free.wait.assert_awaited_once_with()
        f.assert_awaited_once_with(self.api, "args", kw="kwargs")
Ejemplo n.º 7
0
 async def test_play_next_track_list(self, example_music_manager,
                                     monkeypatch):
     """
     The method `_play_next_track_list()` should look for the group index and track list of the track list with
     the name specified in the `next` attribute in the `current_track_list`. If the specified track list exists,
     the method `play_track_list()` should be called accordingly to start a task to play the next track list.
     """
     play_track_list_mock = CoroutineMock()
     monkeypatch.setattr(
         "src.music.music_manager.MusicManager.play_track_list",
         play_track_list_mock)
     track_list = example_music_manager.groups[0].track_lists[0]
     track_list.name = "Next Track List"
     track_list.next = "Next Track List"
     await example_music_manager._play_next_track_list(None, track_list)
     play_track_list_mock.assert_awaited_once_with(None, 0, 0)
Ejemplo n.º 8
0
 async def test_play_track_plays_the_track(self, example_music_manager,
                                           monkeypatch):
     """
     When a track is requested to be played, perform the following steps:
     - Get the path (url or file path) for the track
     - Create a MediaPlayer instance
     - Call the play() method on the media player
     - Wait for it to start playing
     - Set the volume with _set_master_volume()
     - While the media player is_playing(), wait
     """
     media_player_mock = MagicMock()
     is_playing_mock = MagicMock(side_effect=[True, True, False
                                              ])  # Only plays for 2 steps
     media_player_mock.is_playing = is_playing_mock
     get_track_path_mock = MagicMock(return_value="url")
     sleep_mock = CoroutineMock()
     wait_for_start_mock = CoroutineMock()
     set_master_volume_mock = CoroutineMock(
     )  # necessary because it will use asyncio.sleep and mess up the numbers
     monkeypatch.setattr("src.music.music_manager.vlc.MediaPlayer",
                         MagicMock(return_value=media_player_mock))
     monkeypatch.setattr("src.music.music_manager.utils.get_track_path",
                         get_track_path_mock)
     monkeypatch.setattr(
         "src.music.music_manager.MusicManager._wait_for_current_player_to_be_playing",
         wait_for_start_mock)
     monkeypatch.setattr(
         "src.music.music_manager.MusicManager._set_master_volume",
         set_master_volume_mock)
     monkeypatch.setattr("src.music.music_manager.asyncio.sleep",
                         sleep_mock)
     example_music_manager.volume = 55
     group = example_music_manager.groups[0]
     track_list = group.track_lists[0]
     track = track_list.tracks[0]
     await example_music_manager._play_track(group=group,
                                             track_list=track_list,
                                             track=track)
     get_track_path_mock.assert_called_once()
     media_player_mock.play.assert_called_once()
     wait_for_start_mock.assert_awaited_once()
     set_master_volume_mock.assert_awaited_once_with(
         example_music_manager.volume, set_global=False)
     assert is_playing_mock.call_count == 3  # is_playing becomes False at the 3rd call, so stop
     assert sleep_mock.await_count == 2  # Two times for while player is playing
Ejemplo n.º 9
0
    async def test_connect(self):
        wsaddr = "host"

        mock_jsonrpc = MagicMock()
        mock_getwsaddr = MagicMock(return_value=wsaddr)
        mock_jsonrpc.get_websocket_address = mock_getwsaddr
        self._client._jsonrpc = mock_jsonrpc

        mock_ws = MagicMock()
        mock_connect = CoroutineMock()
        mock_ws.connect = mock_connect
        self._client._ws = mock_ws

        await self._client.connect()

        mock_getwsaddr.assert_called_once()
        mock_connect.assert_awaited_once_with(wsaddr)
Ejemplo n.º 10
0
async def test_decorator_default():
    mock = CoroutineMock()

    @async_reduceable()
    async def foo(arg, *, kw):
        """My foo doc"""
        await mock(arg, kw=kw)

        return 'result {} {}'.format(arg, kw)

    assert foo.__name__ == 'foo'
    assert foo.__doc__ == 'My foo doc'

    coros = [foo('arg', kw='kw'), foo('arg', kw='kw')]
    results = await asyncio.gather(*coros)

    mock.assert_awaited_once_with('arg', kw='kw')
    assert all(res == 'result arg kw' for res in results)
Ejemplo n.º 11
0
    async def test_on_queue_message_bulk_size_one(self):
        class MyBucket(Bucket):
            def pop_all(self):
                return self._items;


        handler_mock = CoroutineMock()
        self.one_route_fixture['handler'] = handler_mock
        self.one_route_fixture['options']['bulk_size'] = 1

        consumer = Consumer(self.one_route_fixture, *self.connection_parameters, bucket_class=MyBucket)
        queue_mock = CoroutineMock(ack=CoroutineMock())

        await consumer.on_queue_message({"key": "value"}, delivery_tag=20, queue=queue_mock)
        handler_mock.assert_awaited_once_with(consumer.bucket._items)

        self.assertEqual([mock.call(delivery_tag=20)], queue_mock.ack.await_args_list)
        self.assertEqual(0, queue_mock.reject.call_count)
Ejemplo n.º 12
0
async def test_simultaneity(count, args, kwargs):
    result = object()
    mock = CoroutineMock(return_value=result)

    coros_1 = [async_reduce(mock(*args, **kwargs)) for _ in range(count)]

    results = await asyncio.gather(*coros_1)

    mock.assert_awaited_once_with(*args, **kwargs)
    assert all(res == result for res in results)

    coros_2 = [async_reduce(mock(*args, **kwargs)) for _ in range(count)]

    results = await asyncio.gather(*coros_2)

    mock.assert_any_await(*args, **kwargs)
    assert mock.await_count == 2
    assert all(res == result for res in results)
Ejemplo n.º 13
0
async def test_sending_through_connector(monkeypatch):

    mock_send = CoroutineMock()

    def mock_get_connector(module):
        return mock_send

    monkeypatch.setattr(pyuubin.mailer, "get_connector", mock_get_connector)

    mail = Mail(**{
        "to": ["*****@*****.**"],
        "subject": "test subject",
        "text": "yo"
    })
    templates = Templates({})
    await send_mail(mail, templates)

    mock_send.assert_awaited_once_with(mail, templates)
Ejemplo n.º 14
0
 async def test_play_track_list_starts_next_track_list_if_finishes_playing(
         self, example_music_manager, monkeypatch):
     """
     If `_play_track_list()` finishes playing a track_list, `_play_next_track_list()` should be called with the
     current request and the current track_list (that finished playing).
     """
     monkeypatch.setattr("src.music.music_manager.MusicManager._play_track",
                         CoroutineMock())
     play_next_track_list_mock = CoroutineMock()
     monkeypatch.setattr(
         "src.music.music_manager.MusicManager._play_next_track_list",
         play_next_track_list_mock)
     track_list = example_music_manager.groups[0].track_lists[0]
     track_list.loop = False
     track_list.next = "Next Track List"
     await example_music_manager._play_track_list(request=None,
                                                  group_index=0,
                                                  track_list_index=0)
     play_next_track_list_mock.assert_awaited_once_with(None, track_list)
Ejemplo n.º 15
0
    async def test_run_should_set_the_tick_event_everytime_an_interval_is_passed(
            self):
        event = Mock()
        with patch("asyncworker.time.asyncio.Event", return_value=event):

            async def tick_check(clock: ClockTicker):
                event.set.assert_called_once()
                event.clear.assert_not_called()
                await clock.stop()

            clock = ClockTicker(seconds=2)
            sleep = CoroutineMock(
                side_effect=lambda seconds: tick_check(clock))

            with patch("asyncworker.time.asyncio.sleep", sleep):
                clock._running = True
                task = self.loop.create_task(clock._run())
                await task
                event.clear.assert_called_once()
                sleep.assert_awaited_once_with(2)
Ejemplo n.º 16
0
    async def test_on_queue_message_bulk_size_one(self):
        class MyBucket(Bucket):
            def pop_all(self):
                return self._items

        handler_mock = CoroutineMock(__name__="handler")
        self.one_route_fixture["handler"] = handler_mock
        self.one_route_fixture["options"]["bulk_size"] = 1

        consumer = Consumer(
            self.one_route_fixture,
            *self.connection_parameters,
            bucket_class=MyBucket,
        )
        msg = self._make_msg(delivery_tag=20)
        await consumer.on_queue_message(msg=msg)
        handler_mock.assert_awaited_once_with(consumer.bucket._items)

        msg.ack.assert_awaited_once()
        msg.reject.assert_not_awaited()
Ejemplo n.º 17
0
async def test_decorator_default():
    mock = CoroutineMock()

    @async_reduceable()
    async def foo(arg, *, kw):
        """My foo doc"""
        await mock(arg, kw=kw)

        return 'result {} {}'.format(arg, kw)

    assert foo.__name__ == 'foo'
    assert foo.__doc__ == 'My foo doc'

    coros = [
        foo('arg', kw='kw'),
        foo('arg', kw='kw')
    ]
    done, pending = await asyncio.wait(coros)
    assert not pending
    mock.assert_awaited_once_with('arg', kw='kw')
    assert all(f.result() == 'result arg kw' for f in done)
Ejemplo n.º 18
0
async def test_subscribe_rid(sm: SubscriptionManager):
    send_mock = CoroutineMock()
    send_mock.return_value = 'some return value'
    sm._ds.send_message = send_mock

    sm._sub_payload = Mock()
    sub_payload_value = 'some value'
    sm._sub_payload.return_value = sub_payload_value

    sub = Subscription(category=Category.MARKET,
                       events=[MarketEvents.CANCELS, MarketEvents.ORDERS],
                       topics=['ETH_AURA', 'ETH_ZRX'])

    result = await sm.subscribe(sub, 'some rid')

    sm._sub_payload.assert_called_once_with(Action.SUBSCRIBE,
                                            topics=sub.topics,
                                            events=sub.events)
    send_mock.assert_awaited_once_with(sub.category.value, sub_payload_value,
                                       'some rid')
    assert result == 'some return value'
Ejemplo n.º 19
0
    async def test_bulk_flushes_on_timeout_even_with_bucket_not_full(self):
        class MyBucket(Bucket):
            def pop_all(self):
                global items
                items = self._items
                self._items = []
                return items

        handler_mock = CoroutineMock(__name__="handler")
        self.one_route_fixture["handler"] = handler_mock
        self.one_route_fixture["options"]["bulk_size"] = 3

        consumer = Consumer(
            self.one_route_fixture,
            *self.connection_parameters,
            bucket_class=MyBucket,
        )

        msgs = [
            self._make_msg(delivery_tag=10),
            self._make_msg(delivery_tag=11),
        ]
        await consumer.on_queue_message(msgs[0])
        handler_mock.assert_not_awaited()

        await consumer.on_queue_message(msgs[1])
        handler_mock.assert_not_awaited()

        self.loop.create_task(consumer._flush_clocked())
        # Realizando sleep para devolver o loop para o clock
        await asyncio.sleep(0.1)

        handler_mock.assert_awaited_once_with(items)

        msgs[0].ack.assert_awaited_once()
        msgs[1].ack.assert_awaited_once()

        msgs[0].reject.assert_not_awaited()
        msgs[1].reject.assert_not_awaited()
Ejemplo n.º 20
0
async def test_simultaneity_raise(count, error):
    mock = CoroutineMock(side_effect=error('test error'))

    coros_1 = [async_reduce(mock()) for _ in range(count)]

    results = await asyncio.gather(*coros_1, return_exceptions=True)

    mock.assert_awaited_once_with()
    for res in results:
        assert isinstance(res, error)
        if not isinstance(res, asyncio.CancelledError):
            assert str(res) == 'test error'

    coros_2 = [async_reduce(mock()) for _ in range(count)]

    results = await asyncio.gather(*coros_2, return_exceptions=True)

    mock.assert_any_await()
    assert mock.await_count == 2
    for res in results:
        assert isinstance(res, error)
        if not isinstance(res, asyncio.CancelledError):
            assert str(res) == 'test error'
Ejemplo n.º 21
0
async def test_simultaneity(count, args, kwargs):
    result = object()
    mock = CoroutineMock(return_value=result)

    coros_1 = [
        async_reduce(mock(*args, **kwargs))
        for _ in range(count)
    ]

    done_1, pending_1 = await asyncio.wait(coros_1)
    assert not pending_1
    mock.assert_awaited_once_with(*args, **kwargs)
    assert all(f.result() == result for f in done_1)

    coros_2 = [
        async_reduce(mock(*args, **kwargs))
        for _ in range(count)
    ]

    done_2, pending_2 = await asyncio.wait(coros_2)
    assert not pending_2
    mock.assert_any_await(*args, **kwargs)
    assert mock.await_count == 2
    assert all(f.result() == result for f in done_2)
class TestHandleErrorsDecoratorTestCase(TestCase):
    def setUp(self):
        self.dummy_coro = CoroutineMock(__name__="coro")
        self.handler_mock = Mock(set_status=Mock(), write=Mock())

    async def test_no_errors(self):
        await handle_errors(self.dummy_coro)(self.handler_mock)

        self.dummy_coro.assert_awaited_once_with(self.handler_mock)
        self.handler_mock.set_status.assert_not_called()
        self.handler_mock.write.assert_not_called()

    async def test_validation_error(self):
        self.dummy_coro.side_effect = ValidationError("Expected str not int")

        await handle_errors(self.dummy_coro)(self.handler_mock)

        self.dummy_coro.assert_awaited_once_with(self.handler_mock)
        self.handler_mock.set_status.assert_called_once_with(400)
        self.handler_mock.write.assert_called_once_with(
            {"error": "Expected str not int"}
        )

    async def test_unsupported_format(self):
        self.dummy_coro.side_effect = UnsupportedFormatError("Expected JSON")

        await handle_errors(self.dummy_coro)(self.handler_mock)

        self.dummy_coro.assert_awaited_once_with(self.handler_mock)
        self.handler_mock.set_status.assert_called_once_with(415)
        self.handler_mock.write.assert_called_once_with({"error": "Expected JSON"})

    async def test_server_error(self):
        self.dummy_coro.side_effect = ValueError("It didn't work")

        await handle_errors(self.dummy_coro)(self.handler_mock)

        self.dummy_coro.assert_awaited_once_with(self.handler_mock)
        self.handler_mock.set_status.assert_called_once_with(500)
        self.handler_mock.write.assert_called_once_with({"error": "It didn't work"})
Ejemplo n.º 23
0
    async def test_call_syntaxes(self):
        _set_limits = CoroutineMock()
        _show_limits = CoroutineMock()
        self.patch(RateLimitCmd,
                   _set_limits=_set_limits,
                   _show_limits=_show_limits)

        await self.execute(RateLimitCmd, 'up', '1Mb', 'limit-rate-up<1k')
        _set_limits.assert_awaited_once_with(['limit-rate-up<1k'], ('up', ),
                                             '1Mb',
                                             adjust=False,
                                             quiet=False)
        _show_limits.assert_not_awaited()
        _set_limits.reset_mock()
        _show_limits.reset_mock()

        await self.execute(RateLimitCmd, 'up', '1Mb')
        _set_limits.assert_awaited_once_with([], ('up', ),
                                             '1Mb',
                                             adjust=False,
                                             quiet=False)
        _show_limits.assert_not_awaited()
        _set_limits.reset_mock()
        _show_limits.reset_mock()

        await self.execute(RateLimitCmd, 'up')
        _set_limits.assert_not_awaited()
        _show_limits.assert_awaited_once_with([], ('up', ))
        _set_limits.reset_mock()
        _show_limits.reset_mock()

        await self.execute(RateLimitCmd, 'up', 'show', 'limit-rate-up<1k')
        _set_limits.assert_not_awaited()
        _show_limits.assert_awaited_once_with(['limit-rate-up<1k'], ('up', ))
        _set_limits.reset_mock()
        _show_limits.reset_mock()
Ejemplo n.º 24
0
class TestHandleErrors(TestCase):
    def setUp(self):
        self._coro = CoroutineMock(__name__="Test coro")
        self.test_coro = handle_errors(self._coro)
        self._self = MagicMock()

    async def test_no_error(self):
        self._coro.return_value = "Test"

        self.assertEqual("Test", await self.test_coro(self._self, 1, 2))

        self._coro.assert_awaited_once_with(self._self, 1, 2)
        self._self.write.assert_not_called()
        self._self.loader.load.assert_not_called()

    async def test_validation_error(self):
        self._coro.side_effect = Invalid("Not an int")

        await self.test_coro(self._self, 1, 2)

        self._coro.assert_awaited_once_with(self._self, 1, 2)
        self._self.write.assert_called_once_with(
            self._self.loader.load.return_value.generate.return_value)
        self._self.loader.load.assert_called_once_with("error.html")
        self._self.loader.load.return_value.generate.assert_called_once_with(
            error="Not an int")

    async def test_error(self):
        self._coro.side_effect = ValueError("Not an int")

        await self.test_coro(self._self, 1, 2)

        self._coro.assert_awaited_once_with(self._self, 1, 2)
        self._self.write.assert_called_once_with(
            self._self.loader.load.return_value.generate.return_value)
        self._self.loader.load.assert_called_once_with("error.html")
        self._self.loader.load.return_value.generate.assert_called_once_with()
Ejemplo n.º 25
0
class ScheduledTaskRunnerTests(asynctest.TestCase):
    async def setUp(self):
        reload(task_runners)
        self.task = CoroutineMock()
        self.app = asynctest.Mock(spec=App)
        self.seconds = 10
        self.max_concurrency = 2

        self.task_runner = ScheduledTaskRunner(
            seconds=self.seconds,
            task=self.task,
            app=self.app,
            max_concurrency=self.max_concurrency,
        )

    async def test_it_can_dispatch_a_new_task_if_running_tasks_doesnt_exceed_max_concurrency(
        self
    ):
        self.task_runner.running_tasks = {CoroutineMock()}

        self.assertTrue(await self.task_runner.can_dispatch_task())

    async def test_it_waits_for_a_task_to_be_completed_before_dispatching_a_new_task_if_running_tasks_reached_max_concurrency(
        self
    ):
        self.task_runner.running_tasks = {CoroutineMock(), CoroutineMock()}

        with patch.object(self.task_runner.task_is_done_event, "wait") as wait:
            self.assertTrue(await self.task_runner.can_dispatch_task())
            wait.assert_awaited_once()

    async def test_wrapped_task_awaits_for_the_task(self):
        wrapped_task = asyncio.ensure_future(self.task_runner._wrapped_task())

        self.task_runner.running_tasks.add(wrapped_task)
        await wrapped_task

        self.task.assert_awaited_once_with(self.app)

    async def test_wrapped_task_unregisters_itself_from_the_running_tasks(self):
        wrapped_task = asyncio.ensure_future(self.task_runner._wrapped_task())

        self.task_runner.running_tasks.add(wrapped_task)
        await wrapped_task
        self.assertEqual(len(self.task_runner.running_tasks), 0)

    async def test_wrapped_task_emits_the_task_is_done_event_if_task_finishes_successfully(
        self
    ):
        with patch.object(self.task_runner.task_is_done_event, "set") as set:
            wrapped_task = asyncio.ensure_future(
                self.task_runner._wrapped_task()
            )

            self.task_runner.running_tasks.add(wrapped_task)
            await wrapped_task
            set.assert_called_once()

    async def test_wrapped_task_emits_the_task_is_done_event_if_task_raises_an_error(
        self
    ):
        with patch.object(self.task_runner.task_is_done_event, "set") as set:
            self.task.side_effect = error = ConnectionError
            wrapped_task = asyncio.ensure_future(
                self.task_runner._wrapped_task()
            )

            self.task_runner.running_tasks.add(wrapped_task)
            with self.assertRaises(error):
                await wrapped_task

            set.assert_called_once()

    async def test_start_creates_a_background_task_for_run(self):
        self.assertFalse(self.task_runner._started)

        with patch.object(self.task_runner, "_run") as _run, patch(
            "asyncworker.task_runners.asyncio.ensure_future"
        ) as ensure_future:
            await self.task_runner.start(self.app)

            self.assertTrue(self.task_runner._started)
            _run.assert_called_once()
            ensure_future.assert_called_once()

    async def test_stop_stops_the_underlying_clock_ticker(self):
        with patch.object(self.task_runner.clock, "stop") as clock_stop:
            await self.task_runner.stop(self.app)
            clock_stop.assert_awaited_once()

    async def test_stop_awaits_for_the_currently_running_tasks_to_end(self):
        t1, t2 = CoroutineMock(), CoroutineMock()
        self.task_runner.running_tasks = {t1(), t2()}
        with patch.object(self.task_runner.clock, "stop"):
            await self.task_runner.stop(self.app)

            t1.assert_awaited_once()
            t2.assert_awaited_once()

    async def test_run_follows_the_clock_tick(self):
        clock = asynctest.MagicMock()
        clock.__aiter__.return_value = range(3)

        with patch.multiple(
            self.task_runner,
            clock=clock,
            can_dispatch_task=CoroutineMock(return_value=False),
        ):
            await self.task_runner._run()
            self.task_runner.can_dispatch_task.assert_has_awaits(
                [call(), call(), call()]
            )

    async def test_current_task_compatiple_with_py36_plus(self):
        async def _task(app: App):
            return None

        task_runner = ScheduledTaskRunner(
            seconds=self.seconds,
            task=_task,
            app=self.app,
            max_concurrency=self.max_concurrency,
        )

        def _current_task():
            return _task

        with patch.object(
            asyncio, "current_task", _current_task, create=True
        ), patch.object(sys, "version_info", (3, 8)):
            reload(task_runners)
            task_runner.running_tasks.add(_task)
            await task_runner._wrapped_task()
            self.assertTrue(_task not in task_runner.running_tasks)

    async def test_current_task_compatiple_with_py36(self):
        async def _task(app: App):
            return None

        task_runner = ScheduledTaskRunner(
            seconds=self.seconds,
            task=_task,
            app=self.app,
            max_concurrency=self.max_concurrency,
        )

        def _current_task():
            return _task

        with patch.object(
            asyncio, "Task", _current_task
        ) as Task_mock, patch.object(sys, "version_info", (3, 6)):
            Task_mock.current_task = _current_task
            reload(task_runners)
            task_runner.running_tasks.add(_task)
            await task_runner._wrapped_task()
            self.assertTrue(_task not in task_runner.running_tasks)

    async def test_run_dispatches_a_new_task_for_each_valid_clock_tick(self):
        clock = asynctest.MagicMock()
        clock.__aiter__.return_value = range(3)
        wrapped_task = Mock()
        with patch.multiple(
            self.task_runner,
            clock=clock,
            _wrapped_task=wrapped_task,
            can_dispatch_task=CoroutineMock(side_effect=[True, False, True]),
        ), patch(
            "asyncworker.task_runners.asyncio.ensure_future"
        ) as ensure_future:
            await self.task_runner._run()
            self.assertEqual(
                ensure_future.call_args_list,
                [
                    call(wrapped_task.return_value),
                    call(wrapped_task.return_value),
                ],
            )

    async def test_run_emits_a_task_i_done_event_for_each_valid_clock_tick(
        self
    ):
        clock = asynctest.MagicMock()
        clock.__aiter__.return_value = range(3)
        wrapped_task = Mock()
        with patch.multiple(
            self.task_runner,
            clock=clock,
            _wrapped_task=wrapped_task,
            task_is_done_event=Mock(),
            can_dispatch_task=CoroutineMock(side_effect=[True, False, True]),
        ), patch("asyncworker.task_runners.asyncio.ensure_future"):
            await self.task_runner._run()

            self.task_runner.task_is_done_event.clear.assert_has_calls(
                [call(), call()]
            )

    async def test_run_adds_the_new_task_for_each_valid_clock_tick(self):
        clock = asynctest.MagicMock()
        clock.__aiter__.return_value = range(3)
        wrapped_task = Mock()
        with patch.multiple(
            self.task_runner,
            clock=clock,
            _wrapped_task=wrapped_task,
            running_tasks=Mock(spec=set),
            can_dispatch_task=CoroutineMock(side_effect=[True, False, True]),
        ), patch(
            "asyncworker.task_runners.asyncio.ensure_future"
        ) as ensure_future:
            await self.task_runner._run()

            self.task_runner.running_tasks.add.assert_has_calls(
                [
                    call(ensure_future.return_value),
                    call(ensure_future.return_value),
                ]
            )