# Path: google/resumable_media/common.py
# _SLEEP_RETRY_ERROR_MSG = (
#     "At most one of `max_cumulative_retry` and `max_retries` " "can be specified."
# )
# UPLOAD_CHUNK_SIZE = 262144  # 256 * 1024
# PERMANENT_REDIRECT = http.client.PERMANENT_REDIRECT  # type: ignore
# TOO_MANY_REQUESTS = http.client.TOO_MANY_REQUESTS
# MAX_SLEEP = 64.0
# MAX_CUMULATIVE_RETRY = 600.0
# RETRYABLE = (
#     http.client.TOO_MANY_REQUESTS,  # 429
#     http.client.REQUEST_TIMEOUT,  # 408
#     http.client.INTERNAL_SERVER_ERROR,  # 500
#     http.client.BAD_GATEWAY,  # 502
#     http.client.SERVICE_UNAVAILABLE,  # 503
#     http.client.GATEWAY_TIMEOUT,  # 504
# )
# class InvalidResponse(Exception):
# class DataCorruption(Exception):
# class RetryStrategy(object):
#     def __init__(self, response, *args):
#     def __init__(self, response, *args):
#     def __init__(
#         self,
#         max_sleep=MAX_SLEEP,
#         max_cumulative_retry=None,
#         max_retries=None,
#         initial_delay=1.0,
#         multiplier=2.0,
#     ):
#     def retry_allowed(self, total_sleep, num_retries):


import http.client
import mock
import pytest  # type: ignore
from google._async_resumable_media import _helpers
from google.resumable_media import common
    async def test_success_no_retry(self):
        truthy = http.client.OK
        assert truthy not in common.RETRYABLE
        response = _make_response(truthy)

        func = mock.AsyncMock(return_value=response, spec=[])
        retry_strategy = common.RetryStrategy()
        ret_val = await _helpers.wait_and_retry(func, _get_status_code, retry_strategy)

        assert ret_val is response
        func.assert_called_once_with()

    @mock.patch("time.sleep")
    @mock.patch("random.randint")
    @pytest.mark.asyncio
    async def test_success_with_retry(self, randint_mock, sleep_mock):
        randint_mock.side_effect = [125, 625, 375]

        status_codes = (
            http.client.INTERNAL_SERVER_ERROR,
            http.client.BAD_GATEWAY,
            http.client.SERVICE_UNAVAILABLE,
            http.client.NOT_FOUND,
        )
        responses = [_make_response(status_code) for status_code in status_codes]
        func = mock.AsyncMock(side_effect=responses, spec=[])

        retry_strategy = common.RetryStrategy()
        ret_val = await _helpers.wait_and_retry(func, _get_status_code, retry_strategy)


# Path: google/resumable_media/common.py
# _SLEEP_RETRY_ERROR_MSG = (
#     "At most one of `max_cumulative_retry` and `max_retries` " "can be specified."
# )
# UPLOAD_CHUNK_SIZE = 262144  # 256 * 1024
# PERMANENT_REDIRECT = http.client.PERMANENT_REDIRECT  # type: ignore
# TOO_MANY_REQUESTS = http.client.TOO_MANY_REQUESTS
# MAX_SLEEP = 64.0
# MAX_CUMULATIVE_RETRY = 600.0
# RETRYABLE = (
#     http.client.TOO_MANY_REQUESTS,  # 429
#     http.client.REQUEST_TIMEOUT,  # 408
#     http.client.INTERNAL_SERVER_ERROR,  # 500
#     http.client.BAD_GATEWAY,  # 502
#     http.client.SERVICE_UNAVAILABLE,  # 503
#     http.client.GATEWAY_TIMEOUT,  # 504
# )
# class InvalidResponse(Exception):
# class DataCorruption(Exception):
# class RetryStrategy(object):
#     def __init__(self, response, *args):
#     def __init__(self, response, *args):
#     def __init__(
#         self,
#         max_sleep=MAX_SLEEP,
#         max_cumulative_retry=None,
#         max_retries=None,
#         initial_delay=1.0,
#         multiplier=2.0,
#     ):
#     def retry_allowed(self, total_sleep, num_retries):


# Path: tests_async/unit/test__helpers.py
import http.client
import mock
import pytest  # type: ignore
from google._async_resumable_media import _helpers
from google.resumable_media import common

    async def test_success_no_retry(self):
        truthy = http.client.OK
        assert truthy not in common.RETRYABLE
        response = _make_response(truthy)

        func = mock.AsyncMock(return_value=response, spec=[])
        retry_strategy = common.RetryStrategy()
        ret_val = await _helpers.wait_and_retry(func, _get_status_code, retry_strategy)

        assert ret_val is response
        func.assert_called_once_with()

    @mock.patch("time.sleep")
    @mock.patch("random.randint")
    @pytest.mark.asyncio
    async def test_success_with_retry(self, randint_mock, sleep_mock):
        randint_mock.side_effect = [125, 625, 375]

        status_codes = (
            http.client.INTERNAL_SERVER_ERROR,
            http.client.BAD_GATEWAY,
            http.client.SERVICE_UNAVAILABLE,
            http.client.NOT_FOUND,
        )
        responses = [_make_response(status_code) for status_code in status_codes]
        func = mock.AsyncMock(side_effect=responses, spec=[])

        retry_strategy = common.RetryStrategy()
        ret_val = await _helpers.wait_and_retry(func, _get_status_code, retry_strategy)


        assert ret_val == responses[-1]