diff options
| author | Seth Michael Larson <sethmichaellarson@gmail.com> | 2019-06-05 08:43:06 -0500 |
|---|---|---|
| committer | Seth Michael Larson <sethmichaellarson@gmail.com> | 2019-06-05 08:43:06 -0500 |
| commit | cce19dcd3c29e93e490ef526dc87aad2255b9c99 (patch) | |
| tree | 4707723b7f9625b48f94afc0184af7c1c4fc92c9 /test | |
| parent | 02fd90adbb388de72e4fea0826f33dcd35298a6f (diff) | |
| parent | 728d9244665ef5b03103cb74d7b409ebe4f23b43 (diff) | |
| download | urllib3-delete-makefile.tar.gz | |
Merge branch 'master' of ssh://github.com/urllib3/urllib3 into delete-makefiledelete-makefile
Diffstat (limited to 'test')
| -rw-r--r-- | test/test_response.py | 8 | ||||
| -rw-r--r-- | test/test_retry.py | 70 | ||||
| -rw-r--r-- | test/test_util.py | 15 |
3 files changed, 74 insertions, 19 deletions
diff --git a/test/test_response.py b/test/test_response.py index 18b3e373..23a63be1 100644 --- a/test/test_response.py +++ b/test/test_response.py @@ -440,7 +440,7 @@ class TestResponse(object): def __init__(self, payload, payload_part_size): self.payloads = [ - payload[i * payload_part_size : (i + 1) * payload_part_size] # noqa + payload[i * payload_part_size : (i + 1) * payload_part_size] for i in range(NUMBER_OF_READS + 1) ] @@ -633,7 +633,7 @@ class TestResponse(object): data = compress.compress(b"foobar") data += compress.flush() for i in range(0, len(data), 2): - yield data[i : i + 2] # noqa + yield data[i : i + 2] fp = MockChunkedEncodingResponse(list(stream())) r = httplib.HTTPResponse(MockSock) @@ -801,7 +801,7 @@ class TestResponse(object): data = compress.compress(b"foo\nbar") data += compress.flush() for i in range(0, len(data), 2): - yield data[i : i + 2] # noqa + yield data[i : i + 2] fp = MockChunkedEncodingResponse(list(stream())) r = httplib.HTTPResponse(MockSock) @@ -862,7 +862,7 @@ class MockChunkedEncodingResponse(object): return b"" else: chunk_part = self.cur_chunk[: i + 2] - self.cur_chunk = self.cur_chunk[i + 2 :] # noqa + self.cur_chunk = self.cur_chunk[i + 2 :] return chunk_part elif amt <= -1: chunk_part = self.cur_chunk diff --git a/test/test_retry.py b/test/test_retry.py index 7b228d75..c36476f8 100644 --- a/test/test_retry.py +++ b/test/test_retry.py @@ -1,10 +1,15 @@ +import datetime +import mock import pytest +import time from urllib3.response import HTTPResponse +from urllib3.packages import six from urllib3.packages.six.moves import xrange from urllib3.util.retry import Retry, RequestHistory from urllib3.exceptions import ( ConnectTimeoutError, + InvalidHeader, MaxRetryError, ReadTimeoutError, ResponseError, @@ -271,3 +276,68 @@ class TestRetry(object): retry = Retry(remove_headers_on_redirect=["X-API-Secret"]) assert list(retry.remove_headers_on_redirect) == ["x-api-secret"] + + @pytest.mark.parametrize("value", ["-1", "+1", "1.0", six.u("\xb2")]) # \xb2 = ^2 + def test_parse_retry_after_invalid(self, value): + retry = Retry() + with pytest.raises(InvalidHeader): + retry.parse_retry_after(value) + + @pytest.mark.parametrize( + "value, expected", [("0", 0), ("1000", 1000), ("\t42 ", 42)] + ) + def test_parse_retry_after(self, value, expected): + retry = Retry() + assert retry.parse_retry_after(value) == expected + + @pytest.mark.parametrize("respect_retry_after_header", [True, False]) + def test_respect_retry_after_header_propagated(self, respect_retry_after_header): + + retry = Retry(respect_retry_after_header=respect_retry_after_header) + new_retry = retry.new() + assert new_retry.respect_retry_after_header == respect_retry_after_header + + @pytest.mark.parametrize( + "retry_after_header,respect_retry_after_header,sleep_duration", + [ + ("3600", True, 3600), + ("3600", False, None), + # Will sleep due to header is 1 hour in future + ("Mon, 3 Jun 2019 12:00:00 UTC", True, 3600), + # Won't sleep due to not respecting header + ("Mon, 3 Jun 2019 12:00:00 UTC", False, None), + # Won't sleep due to current time reached + ("Mon, 3 Jun 2019 11:00:00 UTC", True, None), + # Won't sleep due to current time reached + not respecting header + ("Mon, 3 Jun 2019 11:00:00 UTC", False, None), + ], + ) + def test_respect_retry_after_header_sleep( + self, retry_after_header, respect_retry_after_header, sleep_duration + ): + retry = Retry(respect_retry_after_header=respect_retry_after_header) + + # Date header syntax can specify an absolute date; compare this to the + # time in the parametrized inputs above. + current_time = mock.MagicMock( + return_value=time.mktime( + datetime.datetime(year=2019, month=6, day=3, hour=11).timetuple() + ) + ) + + with mock.patch("time.sleep") as sleep_mock, mock.patch( + "time.time", current_time + ): + # for the default behavior, it must be in RETRY_AFTER_STATUS_CODES + response = HTTPResponse( + status=503, headers={"Retry-After": retry_after_header} + ) + + retry.sleep(response) + + # The expected behavior is that we'll only sleep if respecting + # this header (since we won't have any backoff sleep attempts) + if respect_retry_after_header and sleep_duration is not None: + sleep_mock.assert_called_with(sleep_duration) + else: + sleep_mock.assert_not_called() diff --git a/test/test_util.py b/test/test_util.py index b2906f22..37c09ab2 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -13,7 +13,6 @@ import pytest from urllib3 import add_stderr_logger, disable_warnings from urllib3.util.request import make_headers, rewind_body, _FAILEDTELL from urllib3.util.response import assert_header_parsing -from urllib3.util.retry import Retry from urllib3.util.timeout import Timeout from urllib3.util.url import get_host, parse_url, split_first, Url from urllib3.util.ssl_ import ( @@ -27,7 +26,6 @@ from urllib3.exceptions import ( TimeoutStateError, InsecureRequestWarning, SNIMissingWarning, - InvalidHeader, UnrewindableBodyError, ) from urllib3.util.connection import allowed_gai_family, _has_ipv6 @@ -782,19 +780,6 @@ class TestUtil(object): with patch("urllib3.util.connection.HAS_IPV6", False): assert allowed_gai_family() == socket.AF_INET - @pytest.mark.parametrize("value", ["-1", "+1", "1.0", six.u("\xb2")]) # \xb2 = ^2 - def test_parse_retry_after_invalid(self, value): - retry = Retry() - with pytest.raises(InvalidHeader): - retry.parse_retry_after(value) - - @pytest.mark.parametrize( - "value, expected", [("0", 0), ("1000", 1000), ("\t42 ", 42)] - ) - def test_parse_retry_after(self, value, expected): - retry = Retry() - assert retry.parse_retry_after(value) == expected - @pytest.mark.parametrize("headers", [b"foo", None, object]) def test_assert_header_parsing_throws_typeerror_with_non_headers(self, headers): with pytest.raises(TypeError): |
