コード例 #1
0
def fixture_datafeed_loop_v1(datafeed_api, session_service, auth_session,
                             config, datafeed_repository):
    df_loop = auto_stopping_datafeed_loop_v1(datafeed_api, session_service,
                                             auth_session, config,
                                             datafeed_repository)
    df_loop._retry_config = minimal_retry_config_with_attempts(1)
    return df_loop
コード例 #2
0
    async def test_unexpected_api_exception_is_raised(self):
        self._retry_config = minimal_retry_config_with_attempts(1)
        thing = NoApiExceptionAfterCount(2, status=404)
        with pytest.raises(ApiException):
            await self._retryable_coroutine(thing)

        assert thing.call_count == 1
コード例 #3
0
    async def test_unauthorized_error_refreshes_session_and_and_tries_again(self):
        self._retry_config = minimal_retry_config_with_attempts(2)
        self._auth_session = Mock()
        self._auth_session.refresh = AsyncMock()
        thing = NoApiExceptionAfterCount(1, status=401)

        value = await self._retryable_coroutine(thing)

        self._auth_session.refresh.assert_called_once()
        assert value is True
コード例 #4
0
    async def test_client_error_recreates_datafeed_and_and_tries_again(self):
        self._retry_config = minimal_retry_config_with_attempts(2)
        self._auth_session = Mock()
        self.recreate_datafeed = AsyncMock()
        thing = NoApiExceptionAfterCount(1, status=400)

        value = await self._retryable_coroutine(thing)

        self.recreate_datafeed.assert_called_once()
        assert value is True
async def test_400_should_call_recreate_df_and_retry(datafeed_loop, datafeed_api):
    datafeed_loop._retry_config = minimal_retry_config_with_attempts(2)
    datafeed_loop.recreate_datafeed = AsyncMock()
    datafeed_api.read_datafeed.side_effect = [ApiException(status=400), ApiException(status=500)]

    with pytest.raises(ApiException) as exception:
        await datafeed_loop.start()
        assert exception.value.status == 500

    datafeed_loop.recreate_datafeed.assert_called_once()
    assert datafeed_api.read_datafeed.call_count == 2
async def test_start_datafeed_stale_datafeed(datafeed_loop, datafeed_api, message_sent_event):
    datafeed_loop._retry_config = minimal_retry_config_with_attempts(2)
    datafeed_api.list_datafeed.return_value = [V5Datafeed(id="fault_datafeed_id")]
    datafeed_api.create_datafeed.return_value = V5Datafeed(id="test_id")

    # This is done this way because side_effect with a list containing coroutines is not behaving as expected
    async def raise_and_return_event(**kwargs):
        if raise_and_return_event.first:
            raise_and_return_event.first = False
            raise ApiException(400)
        await asyncio.sleep(SLEEP_SECONDS)  # to force the switching of tasks
        return message_sent_event

    raise_and_return_event.first = True

    datafeed_api.read_datafeed.side_effect = raise_and_return_event

    await datafeed_loop.start()

    datafeed_api.list_datafeed.assert_called_with(
        session_token="session_token",
        key_manager_token="km_token",
        tag=BOT_USER
    )

    datafeed_api.delete_datafeed.assert_called_with(
        session_token="session_token",
        key_manager_token="km_token",
        datafeed_id="fault_datafeed_id"
    )

    datafeed_api.create_datafeed.assert_called_with(
        session_token="session_token",
        key_manager_token="km_token",
        body=V5DatafeedCreateBody(tag=BOT_USER)
    )

    datafeed_api.read_datafeed.assert_has_calls([
        call(
            session_token="session_token",
            key_manager_token="km_token",
            datafeed_id="fault_datafeed_id",
            ack_id=AckId(ack_id="")
        ),
        call(
            session_token="session_token",
            key_manager_token="km_token",
            datafeed_id="test_id",
            ack_id=AckId(ack_id="")
        )
    ])

    assert datafeed_loop._datafeed_id == "test_id"
    assert datafeed_loop._ack_id == "ack_id"
コード例 #7
0
async def test_should_retry():
    strategies = [TestAuthenticationStrategy(), TestRefreshSessionStrategy(), TestReadDatafeedStrategy()]
    connection_key = Mock()
    connection_key.ssl = "ssl"
    exception_from_a_timeout = ClientConnectorError(connection_key, TimeoutError())
    exception_from_a_timeout.__cause__ = TimeoutError()
    thing = FixedChainedExceptions([ApiException(429), ApiException(500), exception_from_a_timeout])

    for s in strategies:
        s._retry_config = minimal_retry_config_with_attempts(4)

        value = await s._retryable_coroutine(thing)

        assert value is True
        assert thing.call_count == 4
        thing.reset()  # Reset the counters
コード例 #8
0
class TestRefreshSessionStrategy:
    """Testing refresh_session_if_unauthorized strategy"""
    _retry_config = minimal_retry_config_with_attempts(2)

    @retry(retry=strategy.refresh_session_if_unauthorized)
    async def _retryable_coroutine(self, thing):
        await asyncio.sleep(0.00001)
        return thing.go()

    @pytest.mark.asyncio
    async def test_unauthorized_error_refreshes_session_and_tries_again(self):
        self._auth_session = Mock()
        self._auth_session.refresh = AsyncMock()
        thing = NoApiExceptionAfterCount(1, status=401)

        value = await self._retryable_coroutine(thing)

        self._auth_session.refresh.assert_called_once()
        assert value is True
async def test_400_should_call_recreate_df_return_and_retry(datafeed_loop, datafeed_api, message_sent_event):
    async def read_df(**kwargs):
        if read_df.first_time:
            read_df.first_time = False
            raise ApiException(status=400, reason="")
        await asyncio.sleep(0.00001)  # to force the switching of tasks
        return message_sent_event

    read_df.first_time = True

    datafeed_api.read_datafeed.side_effect = read_df
    datafeed_loop._retry_config = minimal_retry_config_with_attempts(2)
    datafeed_loop.prepare_datafeed = AsyncMock()
    datafeed_loop.recreate_datafeed = AsyncMock()

    await datafeed_loop.start()

    datafeed_loop.recreate_datafeed.assert_called_once()
    assert datafeed_api.read_datafeed.call_count >= 2
コード例 #10
0
class TestAuthenticationStrategy:
    """Testing authentication_retry strategy"""
    _retry_config = minimal_retry_config_with_attempts(1)

    @retry(retry=strategy.authentication_retry)
    async def _retryable_coroutine(self, thing):
        await asyncio.sleep(0.00001)
        return thing.go()

    @pytest.mark.asyncio
    async def test_unauthorized_is_raised(self):
        thing = NoApiExceptionAfterCount(2, status=401)
        with pytest.raises(AuthUnauthorizedError):
            await self._retryable_coroutine(thing)

        assert thing.call_count == 1

    @pytest.mark.asyncio
    async def test_unexpected_api_exception_is_raised(self):
        thing = NoApiExceptionAfterCount(2, status=404)
        with pytest.raises(ApiException):
            await self._retryable_coroutine(thing)

        assert thing.call_count == 1
コード例 #11
0
class TestDecoratorWrapper:
    """Testing the default decorator configuration taken from the class attribute _retry_config"""
    _retry_config = minimal_retry_config_with_attempts(10)

    @retry
    async def _retryable_coroutine(self, thing):
        await asyncio.sleep(0.00001)
        return thing.go()

    @retry(retry=tenacity.retry_if_result(lambda x: False))
    async def _non_retryable_coroutine(self, thing):
        return thing.go()

    @retry(stop=tenacity.stop_after_attempt(2))
    async def _retryable_coroutine_with_2_attempts(self, thing):
        await asyncio.sleep(0.00001)
        thing.go()

    @pytest.mark.asyncio
    async def test_max_attempts_reached_should_fail(self):
        thing = NoApiExceptionAfterCount(11, status=500)

        with pytest.raises(ApiException):
            await self._retryable_coroutine(thing)

        assert thing.counter == 10
        assert thing.call_count == 10

    @pytest.mark.asyncio
    async def test_exception_not_matching_default_predicate_should_fail(self):
        thing = NoApiExceptionAfterCount(1, status=400)
        with pytest.raises(ApiException):
            await self._retryable_coroutine(thing)

        assert thing.counter == 1
        assert thing.call_count == 1