import math
import time


def test_query_retry_maxed_out(
    mini_sentry, relay_with_processing, outcomes_consumer, events_consumer
):
    """
    Assert that a query is not retried an infinite amount of times.

    This is not specific to processing or store, but here we have the outcomes
    consumer which we can use to assert that an event has been dropped.
    """

    request_count = 0

    outcomes_consumer = outcomes_consumer()
    events_consumer = events_consumer()

    @mini_sentry.app.endpoint("get_project_config")
    def get_project_config():
        nonlocal request_count
        request_count += 1
        print("RETRY", request_count)
        return "no", 500

    RETRIES = 1
    query_timeout = 0.5  # Initial grace period

    # Relay's exponential backoff: INITIAL_INTERVAL = 1s; DEFAULT_MULTIPLIER = 1.5;
    for retry in range(RETRIES):  # 1 retry
        query_timeout += 1 * 1.5 ** (retry + 1)

    relay = relay_with_processing(
        {"limits": {"query_timeout": math.ceil(query_timeout)}}
    )

    try:
        relay.send_event(42)
        time.sleep(query_timeout)

        outcomes_consumer.assert_dropped_internal()
        assert request_count == 1 + RETRIES

        for (_, error) in mini_sentry.test_failures[:-1]:
            assert isinstance(error, AssertionError)
            assert "error fetching project states" in str(error)

        _, last_error = mini_sentry.test_failures[-1]
        assert "failed to resolve project information" in str(last_error)
    finally:
        mini_sentry.test_failures.clear()