Skip to content

Commit

Permalink
Merge pull request #1174 from stripe/richardm-improve-http-client-test
Browse files Browse the repository at this point in the history
Improve `test_http_client.py`
  • Loading branch information
richardm-stripe authored Dec 14, 2023
2 parents 4435524 + cab0d52 commit 2e42cab
Showing 1 changed file with 32 additions and 18 deletions.
50 changes: 32 additions & 18 deletions tests/test_http_client.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from typing import Any
from typing_extensions import Type
import pytest
import json

import stripe
from stripe import _http_client
from stripe._encode import _api_encode
from stripe import APIConnectionError
import urllib3
from stripe import util
from stripe import _util

VALID_API_METHODS = ("get", "post", "delete")

Expand Down Expand Up @@ -72,26 +75,26 @@ def mock_max_delay(self, new_value):

def test_sleep_time_exponential_back_off(self):
client = _http_client.new_default_http_client()
client._add_jitter_time = lambda t: t
client._add_jitter_time = lambda sleep_seconds: sleep_seconds
with self.mock_max_delay(10):
self.assert_sleep_times(client, [])

def test_initial_delay_as_minimum(self):
client = _http_client.new_default_http_client()
client._add_jitter_time = lambda t: t * 0.001
client._add_jitter_time = lambda sleep_seconds: sleep_seconds * 0.001
initial_delay = _http_client.HTTPClient.INITIAL_DELAY
self.assert_sleep_times(client, [initial_delay] * 5)

def test_maximum_delay(self):
client = _http_client.new_default_http_client()
client._add_jitter_time = lambda t: t
client._add_jitter_time = lambda sleep_seconds: sleep_seconds
max_delay = _http_client.HTTPClient.MAX_DELAY
expected = [0.5, 1.0, max_delay, max_delay, max_delay]
self.assert_sleep_times(client, expected)

def test_retry_after_header(self):
client = _http_client.new_default_http_client()
client._add_jitter_time = lambda t: t
client._add_jitter_time = lambda sleep_seconds: sleep_seconds

# Prefer retry-after if it's bigger
assert 30 == client._sleep_time_seconds(
Expand All @@ -109,7 +112,9 @@ def test_retry_after_header(self):
def test_randomness_added(self):
client = _http_client.new_default_http_client()
random_value = 0.8
client._add_jitter_time = lambda t: t * random_value
client._add_jitter_time = (
lambda sleep_seconds: sleep_seconds * random_value
)
base_value = _http_client.HTTPClient.INITIAL_DELAY * random_value

with self.mock_max_delay(10):
Expand Down Expand Up @@ -240,6 +245,8 @@ class TestClient(_http_client.HTTPClient):


class ClientTestBase(object):
REQUEST_CLIENT: Type[_http_client.HTTPClient]

@pytest.fixture
def request_mock(self, request_mocks):
return request_mocks[self.REQUEST_CLIENT.name]
Expand Down Expand Up @@ -342,7 +349,7 @@ def test_request_stream(

def test_exception(self, request_mock, mock_error):
mock_error(request_mock)
with pytest.raises(stripe.error.APIConnectionError):
with pytest.raises(APIConnectionError):
self.make_request("get", self.valid_url, {}, None)


Expand All @@ -352,7 +359,9 @@ def __eq__(self, other):


class TestRequestsClient(StripeClientTestCase, ClientTestBase):
REQUEST_CLIENT = _http_client.RequestsClient
REQUEST_CLIENT: Type[
_http_client.RequestsClient
] = _http_client.RequestsClient

@pytest.fixture
def session(self, mocker, request_mocks):
Expand All @@ -366,7 +375,7 @@ def mock_response(mock, body, code):
result.status_code = code
result.headers = {}
result.raw = urllib3.response.HTTPResponse(
body=util.io.BytesIO(str.encode(body)),
body=_util.io.BytesIO(str.encode(body)),
preload_content=False,
status=code,
)
Expand Down Expand Up @@ -466,7 +475,7 @@ def response(code=200, headers={}):
result.status_code = code
result.headers = headers
result.raw = urllib3.response.HTTPResponse(
body=util.io.BytesIO(str.encode(result.content)),
body=_util.io.BytesIO(str.encode(result.content)),
preload_content=False,
status=code,
)
Expand Down Expand Up @@ -530,7 +539,7 @@ def make_client(self):
verify_ssl_certs=True, timeout=80, proxy="http://slap/"
)
# Override sleep time to speed up tests
client._sleep_time = lambda _: 0.0001
client._sleep_time_seconds = lambda num_retries, response=None: 0.0001
# Override configured max retries
client._max_network_retries = lambda: self.max_retries()
return client
Expand All @@ -557,14 +566,14 @@ def test_retry_error_until_exceeded(
self, mock_retry, response, check_call_numbers
):
mock_retry(retry_error_num=self.max_retries())
with pytest.raises(stripe.error.APIConnectionError):
with pytest.raises(APIConnectionError):
self.make_request()

check_call_numbers(self.max_retries())

def test_no_retry_error(self, mock_retry, response, check_call_numbers):
mock_retry(no_retry_error_num=self.max_retries())
with pytest.raises(stripe.error.APIConnectionError):
with pytest.raises(APIConnectionError):
self.make_request()
check_call_numbers(1)

Expand Down Expand Up @@ -594,7 +603,7 @@ def test_retry_request_stream_error_until_exceeded(
self, mock_retry, response, check_call_numbers
):
mock_retry(retry_error_num=self.max_retries())
with pytest.raises(stripe.error.APIConnectionError):
with pytest.raises(APIConnectionError):
self.make_request_stream()

check_call_numbers(self.max_retries(), is_streaming=True)
Expand All @@ -603,7 +612,7 @@ def test_no_retry_request_stream_error(
self, mock_retry, response, check_call_numbers
):
mock_retry(no_retry_error_num=self.max_retries())
with pytest.raises(stripe.error.APIConnectionError):
with pytest.raises(APIConnectionError):
self.make_request_stream()
check_call_numbers(1, is_streaming=True)

Expand All @@ -628,7 +637,7 @@ def connection_error(self, session):
client = self.REQUEST_CLIENT()

def connection_error(given_exception):
with pytest.raises(stripe.error.APIConnectionError) as error:
with pytest.raises(APIConnectionError) as error:
client._handle_request_error(given_exception)
return error.value

Expand Down Expand Up @@ -686,6 +695,7 @@ def mock_response(mock, body, code):
result.headers = {}

mock.fetch = mocker.Mock(return_value=result)
return result

return mock_response

Expand Down Expand Up @@ -715,7 +725,11 @@ def check_call(


class TestUrllib2Client(StripeClientTestCase, ClientTestBase):
REQUEST_CLIENT = _http_client.Urllib2Client
REQUEST_CLIENT: Type[
_http_client.Urllib2Client
] = _http_client.Urllib2Client

request_object: Any

def make_client(self, proxy):
self.client = self.REQUEST_CLIENT(verify_ssl_certs=True, proxy=proxy)
Expand Down Expand Up @@ -822,7 +836,7 @@ def make_request_stream(self, method, url, headers, post_data, proxy=None):


class TestPycurlClient(StripeClientTestCase, ClientTestBase):
REQUEST_CLIENT = _http_client.PycurlClient
REQUEST_CLIENT: Type[_http_client.PycurlClient] = _http_client.PycurlClient

def make_client(self, proxy):
self.client = self.REQUEST_CLIENT(verify_ssl_certs=True, proxy=proxy)
Expand Down

0 comments on commit 2e42cab

Please sign in to comment.