Esempio n. 1
0
async def test__iter_messages(mocker, event_loop):
    # arrange
    queue = mocker.Mock(spec=asynqp.Queue)
    queue.consume.return_value = future()

    consumer = get_consumer(callback=simple_callback, prefetch_count=0)
    mocker.patch.object(consumer, '_queue', new=queue)

    queue = mocker.patch('asynqp_consumer.consumer.asyncio.Queue').return_value
    queue.get.side_effect = iter([
        future(Message(mock.Mock(spec=asynqp.IncomingMessage))),
        future(Message(mock.Mock(spec=asynqp.IncomingMessage))),
        future(exception=SomeException),
    ])

    # act
    result = []
    with pytest.raises(SomeException):
        messages_iterator = await consumer._get_messages_iterator(
            loop=event_loop)
        async for message in messages_iterator:
            result.append(message)

    # assert
    assert len(result) == 2
    assert isinstance(result[0], Message)
    assert isinstance(result[1], Message)
Esempio n. 2
0
    async def test_run__func_raised_exception__reject_all_messages(
            self, mocker):
        # arrange
        message1 = Message(
            body='message1',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        mocker.patch.object(message1, 'reject', return_value=future())
        message2 = Message(
            body='message2',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        mocker.patch.object(
            message2,
            'reject',
            return_value=future(exception=MessageAlreadyResolved()))

        middleware = ProcessBulk(
            lambda messages: future(exception=Exception()))
        inp = make_iterator([[message1, message2]])

        # act
        out = middleware(inp)

        # assert
        assert await collect_iterator(out) == [None]
        message1.reject.assert_called_once_with()
        message2.reject.assert_called_once_with()
Esempio n. 3
0
async def test_connect_and_open_channel(mocker):
    # arrange
    transport = mocker.Mock(spec=asyncio.Transport)
    channel = mocker.Mock(spec=Channel)
    protocol = mocker.Mock(spec=aioamqp.AmqpProtocol)
    protocol.channel.return_value = future(channel)
    mocker.patch.object(aioamqp,
                        'connect',
                        return_value=future((transport, protocol)),
                        auto_spec=True)

    connection_params = ConnectionParams()

    # act
    result = await connect_and_open_channel(
        connection_params=connection_params,
        on_error=mocker.sentinel.on_error,
    )

    # assert
    assert result == (transport, protocol, channel)
    aioamqp.connect.assert_called_once_with(
        host=connection_params.host,
        port=connection_params.port,
        login=connection_params.username,
        password=connection_params.password,
        virtualhost=connection_params.virtual_host,
        on_error=mocker.sentinel.on_error,
        loop=asyncio.get_event_loop(),
    )
    protocol.channel.assert_called_once_with()
async def test_queue_to_iterator(mocker):
    # arrange
    queue = mocker.Mock(spec=asyncio.Queue)
    queue.get.side_effect = [future(1), future(2), future(exception=Cancelled())]

    # act
    result = []
    with pytest.raises(Cancelled):
        async for item in queue_to_iterator(queue):
            result.append(item)

    # assert
    assert result == [1, 2]
Esempio n. 5
0
    async def test__connect(self, mocker, event_loop):
        # arrange
        consumer = Consumer(
            middleware=Process(lambda _: future(None)),
            queue=mocker.sentinel.queue,
            connection_params=[mocker.sentinel.connection_params],
            prefetch_count=mocker.sentinel.prefetch_count,
            default_reconnect_timeout=3.0,
            max_reconnect_timeout=5.0,
        )

        channel = mocker.Mock(spec=Channel)
        channel.basic_qos.return_value = future()

        connect_and_open_channel = mocker.patch(
            'aioamqp_consumer_best.consumer.connect_and_open_channel',
            return_value=future((
                mocker.sentinel.transport,
                mocker.sentinel.protocol,
                channel
            )),
        )

        declare_queue = mocker.patch('aioamqp_consumer_best.consumer.declare_queue', return_value=future())

        connection_closed_future = asyncio.Future()

        # act
        await consumer._connect(
            connection_closed_future=connection_closed_future,
            loop=event_loop,
        )

        # assert
        on_error_arg = Arg()
        connect_and_open_channel.assert_called_once_with(
            connection_params=mocker.sentinel.connection_params,
            on_error=on_error_arg,
            loop=event_loop,
        )

        exc = Exception()
        await on_error_arg.value(exc)
        await on_error_arg.value(exc)
        assert connection_closed_future.done()
        assert connection_closed_future.exception() is exc

        channel.basic_qos.assert_called_once_with(prefetch_count=mocker.sentinel.prefetch_count)

        declare_queue.assert_called_once_with(channel=channel, queue=mocker.sentinel.queue)
async def test_connect__integer_heartbeat_interval__passed_to_aioamqp(mocker):
    # arrange
    transport = mocker.Mock(spec=asyncio.BaseTransport)
    protocol = mocker.Mock(spec=aioamqp.AmqpProtocol)
    protocol.wait_closed.return_value = future()
    mocker.patch.object(aioamqp,
                        'connect',
                        return_value=future((transport, protocol)))

    # act
    async with connect(ConnectionParams(), heartbeat_interval=30):
        pass

    # assert
    assert aioamqp.connect.call_args[1]['heartbeat'] == 30
Esempio n. 7
0
async def test_load_json(mocker, event_loop):
    # arrange
    message1 = Message(
        body='{"hello": "world"}',
        channel=mocker.sentinel.channel,
        envelope=mocker.sentinel.envelope,
        properties=mocker.sentinel.properties,
    )
    message2 = Message(
        body='invalid json',
        channel=mocker.sentinel.channel,
        envelope=mocker.sentinel.envelope,
        properties=mocker.sentinel.properties,
    )
    mocker.patch.object(message2, 'reject', return_value=future())
    inp = make_iterator([message1, message2])

    # act
    out = load_json.func(inp, event_loop)

    # assert
    result = await collect_iterator(out)
    message_arg = Arg()
    assert result == [message_arg]
    assert message_arg.value.body == {'hello': 'world'}

    message2.reject.assert_called_once_with(requeue=False)
Esempio n. 8
0
async def test__disconnect_ok(mocker):
    # arrange
    consumer = get_consumer(callback=simple_callback)

    connection = mocker.patch.object(consumer, '_connection', autospec=True)
    connection.close.return_value = future()

    channel = mocker.patch.object(consumer, '_channel', autospec=True)
    channel.close.return_value = future()

    # act
    await consumer._disconnect()

    # assert
    consumer._connection.close.assert_called_once_with()
    consumer._channel.close.assert_called_once_with()
Esempio n. 9
0
async def test__process_queue__ack_message_when_json_is_invalid(
        mocker, event_loop, capsys):
    # arrange
    consumer = get_consumer(callback=simple_callback,
                            prefetch_count=1,
                            reject_invalid_json=False)

    message = asynqp.IncomingMessage(
        body="Invalid JSON",
        sender=None,
        delivery_tag=None,
        exchange_name=None,
        routing_key=None,
    )
    mocker.patch.object(message, 'ack', autospec=True)
    mocker.patch.object(consumer,
                        '_get_messages_iterator',
                        return_value=future(AsyncIter([message])))
    logger_exception = mocker.patch(
        'asynqp_consumer.consumer.logger.exception')

    # act
    await consumer._process_queue(loop=event_loop)

    # assert
    assert consumer._messages == []
    message.ack.assert_called_once_with()
    logger_exception.assert_called_once_with(
        'Failed to parse message body: %s', b'Invalid JSON')
Esempio n. 10
0
async def test_connect_and_open_channel(mocker, event_loop):
    # arrange
    connection = mocker.Mock(spec=asynqp.Connection)

    channel = mocker.Mock(spec=asynqp.Channel)

    asynqp_connect_and_open_channel = mocker.patch(
        'asynqp_consumer.connect.asynqp.connect_and_open_channel',
        autospec=True,
        return_value=future((connection, channel)))

    # act
    result = await connect_and_open_channel(ConnectionParams(), event_loop)

    # assert
    assert result == (connection, channel)

    asynqp_connect_and_open_channel.assert_called_once_with(
        host='localhost',
        port=5672,
        username='******',
        password='******',
        virtual_host='/',
        loop=event_loop,
    )
Esempio n. 11
0
class TestProcess:
    @pytest.mark.parametrize('ack_result', [
        future(None),
        future(exception=MessageAlreadyResolved()),
    ])
    async def test_run__success__ack_message(self, mocker, ack_result):
        # arrange
        message = Message(
            body='message',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        mocker.patch.object(message, 'ack', return_value=ack_result)
        inp = make_iterator([message])
        middleware = Process(lambda _: future(None))

        # act
        out = middleware(inp)

        # assert
        assert await collect_iterator(out) == [None]
        message.ack.assert_called_once_with()

    @pytest.mark.parametrize('reject_result', [
        future(None),
        future(exception=MessageAlreadyResolved()),
    ])
    async def test_run__callback_raised_exception__reject_message(
            self, mocker, reject_result):
        # arrange
        message = Message(
            body='message',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        mocker.patch.object(message, 'reject', return_value=reject_result)
        inp = make_iterator([message])
        middleware = Process(lambda _: future(exception=Exception()))

        # act
        out = middleware(inp)

        # assert
        assert await collect_iterator(out) == [None]
        message.reject.assert_called_once_with()
Esempio n. 12
0
async def test_declare_queue(mocker):
    # arrange
    asynqp_queue = mocker.Mock(spec=asynqp.Queue)
    asynqp_queue.bind.return_value = future()

    asynqp_exchange = mocker.Mock(spec=asynqp.Exchange)

    channel = mocker.Mock(spec=asynqp.Channel)
    channel.declare_queue.return_value = future(asynqp_queue)
    channel.declare_exchange.return_value = future(asynqp_exchange)

    # act
    result = await declare_queue(
        channel,
        Queue(name='test-queue',
              bindings=[
                  QueueBinding(
                      exchange=Exchange('test-exchange'),
                      routing_key='test-routing-key',
                  )
              ]))

    # assert
    assert result is asynqp_queue

    channel.declare_queue.assert_called_once_with(
        name='test-queue',
        durable=True,
        exclusive=False,
        auto_delete=False,
        arguments=None,
    )

    channel.declare_exchange.assert_called_once_with(
        name='test-exchange',
        type='topic',
        durable=True,
        auto_delete=False,
        arguments=None,
    )

    asynqp_queue.bind.assert_called_once_with(
        exchange=asynqp_exchange,
        routing_key='test-routing-key',
        arguments=None,
    )
async def test__process_queue__when_prefetch_count_is_not_0(mocker, event_loop):
    # arrange
    consumer = get_consumer(callback=simple_callback, prefetch_count=1)
    mocker.patch.object(consumer, '_get_messages_iterator', return_value=future(AsyncIter([
        mock.Mock(spec=asynqp.IncomingMessage),
        mock.Mock(spec=asynqp.IncomingMessage),
    ])))
    mocker.patch.object(consumer, '_process_bulk', side_effect=iter([future(), future()]))

    # act
    await consumer._process_queue(loop=event_loop)

    # assert
    assert len(consumer._messages) == 2
    assert isinstance(consumer._messages[0], Message)
    assert isinstance(consumer._messages[1], Message)
    consumer._process_bulk.mock_calls == [mocker.call(), mocker.call()]
Esempio n. 14
0
async def test__connect__ok(mocker, event_loop):
    # arrange
    connection = mocker.Mock(spec=asynqp.Connection)

    channel = mocker.Mock(spec=asynqp.Channel)
    channel.set_qos.return_value = future()

    connect_and_open_channel = mocker.patch(
        'asynqp_consumer.consumer.connect_and_open_channel', autospec=True)
    connect_and_open_channel.return_value = future((connection, channel))

    asynqp_queue = mocker.Mock(spec=asynqp.Queue)

    declare_queue = mocker.patch('asynqp_consumer.consumer.declare_queue',
                                 autospec=True)
    declare_queue.return_value = future(asynqp_queue)

    consumer = get_consumer(callback=simple_callback)

    # act
    await consumer._connect(loop=event_loop)

    # assert
    connect_and_open_channel.assert_called_once_with(
        ConnectionParams(
            host='test_host',
            port=1234,
            username='******',
            password='******',
            virtual_host='test_virtual_host',
        ), event_loop)

    declare_queue.assert_called_once_with(
        channel,
        Queue(name='test_queue',
              bindings=[
                  QueueBinding(exchange=Exchange('test_exchange'),
                               routing_key='test_routing_key')
              ]))

    channel.set_qos.assert_called_once_with(prefetch_count=0)

    assert consumer._connection is connection
    assert consumer._channel is channel
    assert consumer._queue is asynqp_queue
async def test_start__two_attempts(mocker, event_loop):
    # arrange
    consumer = get_consumer(callback=simple_callback)

    mocker.patch.object(consumer, '_connect', side_effect=iter([OSError, future()]))
    mocker.patch.object(consumer, '_disconnect', return_value=future())
    mocker.patch.object(consumer, '_process_queue', return_value=future())
    mocker.patch.object(consumer, '_check_bulk', return_value=future())

    consumer._connection = mocker.Mock(spec=asynqp.Connection)
    consumer._connection.closed = asyncio.Future(loop=event_loop)

    mocker.patch('asynqp_consumer.consumer.gather', autospec=True, return_value=future())
    Future = mocker.patch('asynqp_consumer.consumer.asyncio.Future', autospec=True)
    Future.return_value.done.side_effect = iter([False, False, True])
    Future.return_value._loop = event_loop

    consumer._connection.closed.set_exception(ConsumerCloseException)

    sleep = mocker.patch('asynqp_consumer.consumer.asyncio.sleep', return_value=future())

    # act
    await consumer.start(loop=event_loop)

    # assert
    assert consumer._connect.mock_calls == [
        mocker.call(loop=event_loop),
        mocker.call(loop=event_loop),
    ]
    consumer._disconnect.assert_called_once_with()
    consumer._process_queue.assert_called_once_with(loop=event_loop)
    consumer._check_bulk.assert_called_once_with(loop=event_loop)
    sleep.assert_called_once_with(3, loop=event_loop)
async def test_declare_queue(mocker):
    # arrange
    channel = mocker.Mock(spec=Channel)
    channel.queue_declare.return_value = future()
    channel.exchange_declare.return_value = future()
    channel.queue_bind.return_value = future()

    exchange = Exchange('exchange')
    queue_binding = QueueBinding(
        exchange=exchange,
        routing_key='routing-key',
    )
    queue = Queue(name='queue-name', bindings=[queue_binding])

    # act
    await declare_queue(channel=channel, queue=queue)

    # assert
    channel.queue_declare.assert_called_once_with(
        queue_name=queue.name,
        durable=queue.durable,
        exclusive=queue.exclusive,
        auto_delete=queue.auto_delete,
        arguments=queue.arguments,
    )

    channel.exchange_declare.assert_called_once_with(
        exchange_name=exchange.name,
        type_name=exchange.type.value,
        auto_delete=exchange.auto_delete,
        durable=exchange.durable,
        arguments=exchange.arguments,
    )

    channel.queue_bind.assert_called_once_with(
        queue_name=queue.name,
        exchange_name=exchange.name,
        routing_key=queue_binding.routing_key,
        arguments=exchange.arguments,
    )
Esempio n. 17
0
    async def test_run__callback_cancelled__should_cancel(self, mocker):
        # arrange
        message = Message(
            body='message',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        inp = make_iterator([message])
        middleware = Process(
            lambda _: future(exception=asyncio.CancelledError()))

        # act
        with pytest.raises(asyncio.CancelledError):
            await collect_iterator(middleware(inp))
async def test__consume_with_arguments(mocker, event_loop):
    # arrange
    queue = mocker.Mock(spec=asynqp.Queue)
    queue.consume.return_value = future()

    consume_arguments = {'x-priority': 100}
    consumer = get_consumer(callback=simple_callback, prefetch_count=0, consume_arguments=consume_arguments)
    mocker.patch.object(consumer, '_queue', new=queue)
    asyncio_queue = mocker.patch('asynqp_consumer.consumer.asyncio.Queue').return_value

    # act
    await consumer._get_messages_iterator(loop=event_loop)

    # assert
    queue.consume.assert_called_once_with(callback=asyncio_queue.put_nowait, arguments=consume_arguments)
async def test__process_queue__when_message_is_invalid_json(mocker, event_loop):
    # arrange
    consumer = get_consumer(callback=simple_callback, prefetch_count=1)

    message = mock.Mock(spec=asynqp.IncomingMessage)
    message.json.side_effect = json.JSONDecodeError('message', '', 0)
    message.body = 'Error json'

    mocker.patch.object(consumer, '_get_messages_iterator', return_value=future(AsyncIter([message])))

    # act
    await consumer._process_queue(loop=event_loop)

    # assert
    assert consumer._messages == []
Esempio n. 20
0
    async def test__disconnect(self, mocker):
        # arrange
        consumer = Consumer(
            middleware=Process(lambda _: future(None)),
            queue=mocker.sentinel.queue,
            connection_params=[mocker.sentinel.connection_params],
            prefetch_count=mocker.sentinel.prefetch_count,
            default_reconnect_timeout=3.0,
            max_reconnect_timeout=5.0,
        )

        channel = mocker.Mock(spec=Channel)
        channel.is_open = True
        channel.close.return_value = future()
        consumer._channel = channel

        protocol = mocker.Mock(spec=Channel)
        protocol.state = aioamqp.protocol.OPEN
        protocol.close.return_value = future()
        consumer._protocol = protocol

        transport = mocker.Mock(spec=Channel)
        consumer._transport = transport

        # act
        await consumer._disconnect()

        # assert
        assert consumer._channel is None
        channel.close.assert_called_once_with()

        assert consumer._protocol is None
        protocol.close.assert_called_once_with()

        assert consumer._transport is None
        transport.close.assert_called_once_with()
Esempio n. 21
0
    async def test_start__expected_right_reconnect_timeouts_and_calls(self, mocker, event_loop):
        # arrange
        consumer = Consumer(
            middleware=Process(lambda _: future(None)),
            queue=mocker.sentinel.queue,
            connection_params=[mocker.sentinel.connection_params],
            prefetch_count=1,
            default_reconnect_timeout=3.0,
            max_reconnect_timeout=5.0,
        )
        mocker.patch.object(consumer, '_connect', side_effect=[
            future(),
            future(exception=aioamqp.AioamqpException()),
            future(),
        ])
        mocker.patch.object(consumer, '_disconnect', return_value=future())
        mocker.patch.object(consumer, '_process_queue', side_effect=[
            future(exception=aioamqp.AioamqpException()),
            future(exception=_ConsumerCloseException()),
        ])
        mocker.patch.object(asyncio, 'sleep', return_value=future())

        # act
        await consumer.start(event_loop)

        # assert
        connection_closed_future_arg = Arg()
        assert consumer._connect.call_count == 3
        consumer._connect.assert_called_with(
            connection_closed_future=connection_closed_future_arg,
            loop=event_loop,
        )
        assert isinstance(connection_closed_future_arg.value, asyncio.Future)

        consumer._disconnect.assert_called_once_with()

        assert consumer._process_queue.call_count == 2
        consumer._process_queue.assert_called_with(loop=event_loop)

        assert asyncio.sleep.call_args_list == [
            mocker.call(3.0, loop=event_loop),
            mocker.call(5.0, loop=event_loop),
        ]
Esempio n. 22
0
async def test_logout__delete_user__deletes_user_and_logs_out(mocker):
    # arrange
    m_get_user = mocker.patch.object(auth,
                                     'get_user_id_from_cookie',
                                     return_value=1)
    m_delete_user = mocker.patch.object(auth,
                                        '_delete_user',
                                        return_value=future())
    m_response = mocker.Mock()
    m_response.delete_cookie = mocker.Mock()

    # act
    await auth.logout(cookie='test', response=m_response, delete_user=True)

    # assert
    m_get_user.assert_called_once_with('test')
    m_delete_user.assert_called_once_with(1)
    m_response.delete_cookie.assert_called_once_with('fastapi_auth')
Esempio n. 23
0
    async def test_run__success__ack_message(self, mocker, ack_result):
        # arrange
        message = Message(
            body='message',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        mocker.patch.object(message, 'ack', return_value=ack_result)
        inp = make_iterator([message])
        middleware = Process(lambda _: future(None))

        # act
        out = middleware(inp)

        # assert
        assert await collect_iterator(out) == [None]
        message.ack.assert_called_once_with()
Esempio n. 24
0
    async def test_run__callback_raised_exception__reject_message(
            self, mocker, reject_result):
        # arrange
        message = Message(
            body='message',
            channel=mocker.sentinel.channel,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        mocker.patch.object(message, 'reject', return_value=reject_result)
        inp = make_iterator([message])
        middleware = Process(lambda _: future(exception=Exception()))

        # act
        out = middleware(inp)

        # assert
        assert await collect_iterator(out) == [None]
        message.reject.assert_called_once_with()
Esempio n. 25
0
    async def test_reject(self, mocker):
        # arrange
        channel = mocker.Mock(spec=Channel)
        channel.basic_reject.return_value = future()

        message = self._make_message(mocker, channel)

        # act
        await message.reject()

        # assert
        with pytest.raises(MessageAlreadyResolved):
            await message.ack()

        with pytest.raises(MessageAlreadyResolved):
            await message.reject()

        channel.basic_reject.assert_called_once_with(
            delivery_tag=mocker.sentinel.delivery_tag, requeue=True)

        assert not channel.basic_client_ack.called
Esempio n. 26
0
    async def test_close(self, mocker):
        # arrange
        consumer = Consumer(
            middleware=Process(lambda _: future(None)),
            queue=mocker.sentinel.queue,
            connection_params=[mocker.sentinel.connection_params],
            prefetch_count=1,
            default_reconnect_timeout=3.0,
            max_reconnect_timeout=5.0,
        )
        consumer._closed_future = asyncio.Future()
        consumer._closed_ok = asyncio.Event()
        consumer._closed_ok.set()
        mocker.spy(consumer._closed_ok, 'wait')

        # act
        await consumer.close()

        # assert
        assert consumer._closed_future.done()
        assert isinstance(consumer._closed_future.exception(), _ConsumerCloseException)
        consumer._closed_ok.wait.assert_called_once_with()
Esempio n. 27
0
    async def test__process_queue(self, mocker, event_loop):
        # arrange
        consumer = Consumer(
            middleware=Process(lambda _: future(None)),
            queue=Queue('queue_name'),
            connection_params=[mocker.sentinel.connection_params],
            prefetch_count=mocker.sentinel.prefetch_count,
            default_reconnect_timeout=3.0,
            max_reconnect_timeout=5.0,
            tag='tag',
        )

        consumer._middleware = mocker.Mock(spec=Middleware)
        consumer._middleware.return_value = make_iterator([])

        consumer._channel = mocker.Mock(spec=Channel)
        consumer._channel.basic_consume.return_value = future()

        queue_to_iterator_mock = mocker.patch(
            'aioamqp_consumer_best.consumer.queue_to_iterator',
            autospec=True,
            return_value=mocker.sentinel.inp,
        )

        Message = mocker.patch('aioamqp_consumer_best.consumer.Message')

        # act
        await consumer._process_queue(loop=event_loop)

        # assert
        callback_arg = Arg()
        consumer._channel.basic_consume.assert_called_once_with(
            callback=callback_arg,
            queue_name='queue_name',
            consumer_tag='tag',
        )

        arg = Arg()
        queue_to_iterator_mock.assert_called_once_with(arg)
        input_queue = arg.value
        assert isinstance(input_queue, asyncio.Queue)

        consumer._middleware.assert_called_once_with(
            inp=mocker.sentinel.inp,
            loop=event_loop,
        )

        await callback_arg.value(
            channel=mocker.sentinel.channel,
            body=mocker.sentinel.body,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )
        message = input_queue.get_nowait()
        assert message is Message.return_value
        Message.assert_called_once_with(
            channel=mocker.sentinel.channel,
            body=mocker.sentinel.body,
            envelope=mocker.sentinel.envelope,
            properties=mocker.sentinel.properties,
        )