diff --git a/setup.py b/setup.py index 0a512e6e..75ad1345 100755 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ # httpretty >= 1.1 duplicates requests in `httpretty.latest_requests` # https://github.com/gabrielfalcao/HTTPretty/issues/425 "httpretty < 1.1", + "responses>=0.24.1,<1", "pytest", "pytest-runner", "pre-commit", diff --git a/tests/unit/oauth_test_utils.py b/tests/unit/oauth_test_utils.py index 956fee78..f80b3b0e 100644 --- a/tests/unit/oauth_test_utils.py +++ b/tests/unit/oauth_test_utils.py @@ -14,7 +14,7 @@ import uuid from collections import namedtuple -import httpretty +import responses from trino import constants @@ -91,14 +91,14 @@ def __call__(self, request, uri, response_headers): def _get_token_requests(challenge_id): return list(filter( - lambda r: r.method == "GET" and r.path == f"/{TOKEN_PATH}/{challenge_id}", - httpretty.latest_requests())) + lambda r: r.method == "GET" and r.url == f"{TOKEN_RESOURCE}/{challenge_id}", + responses.calls)) def _post_statement_requests(): return list(filter( - lambda r: r.method == "POST" and r.path == constants.URL_STATEMENT_PATH, - httpretty.latest_requests())) + lambda r: r.method == "POST" and r.url == f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + responses.calls)) class MultithreadedTokenServer: @@ -111,15 +111,15 @@ def __init__(self, sample_post_response_data, attempts=1): self.attempts = attempts # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + responses.add( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", body=self.post_statement_callback) # bind get token - httpretty.register_uri( - method=httpretty.GET, - uri=re.compile(rf"{TOKEN_RESOURCE}/.*"), + responses.add( + method=responses.GET, + url=re.compile(rf"{TOKEN_RESOURCE}/.*"), body=self.get_token_callback) # noinspection PyUnusedLocal diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 653423a0..187eed8d 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -24,11 +24,10 @@ from zoneinfo import ZoneInfoNotFoundError import gssapi -import httpretty import keyring import pytest import requests -from httpretty import httprettified +import responses from requests_gssapi.exceptions import SPNEGOExchangeError from requests_kerberos.exceptions import KerberosExchangeError from tzlocal import get_localzone_name # type: ignore @@ -347,9 +346,9 @@ def long_call(request, uri, headers): time.sleep(timeout * 2) return (200, headers, "delayed success") - httpretty.enable() - for method in [httpretty.POST, httpretty.GET]: - httpretty.register_uri(method, url, body=long_call) + responses.start() + for method in [responses.POST, responses.GET]: + responses.add_callback(method, url, callback=long_call) # timeout without retry for request_timeout in [timeout, (timeout, timeout)]: @@ -370,12 +369,12 @@ def long_call(request, uri, headers): with pytest.raises(requests.exceptions.Timeout): req.post("select 1") - httpretty.disable() - httpretty.reset() + responses.stop() + responses.reset() @pytest.mark.parametrize("attempts", [1, 3, 5]) -@httprettified +@responses.activate def test_oauth2_authentication_flow(attempts, sample_post_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -386,17 +385,17 @@ def test_oauth2_authentication_flow(attempts, sample_post_response_data): post_statement_callback = PostStatementCallback(redirect_server, token_server, [token], sample_post_response_data) # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", - body=post_statement_callback) + responses.add_callback( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + callback=post_statement_callback) # bind get token get_token_callback = GetTokenCallback(token_server, token, attempts) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, - body=get_token_callback) + responses.add_callback( + method=responses.GET, + url=token_server, + callback=get_token_callback) redirect_handler = RedirectHandler() @@ -417,7 +416,7 @@ def test_oauth2_authentication_flow(attempts, sample_post_response_data): assert len(_get_token_requests(challenge_id)) == attempts -@httprettified +@responses.activate def test_oauth2_refresh_token_flow(sample_post_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -427,17 +426,17 @@ def test_oauth2_refresh_token_flow(sample_post_response_data): post_statement_callback = PostStatementCallback(None, token_server, [token], sample_post_response_data) # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", - body=post_statement_callback) + responses.add_callback( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + callback=post_statement_callback) # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, - body=get_token_callback) + responses.add_callback( + method=responses.GET, + url=token_server, + callback=get_token_callback) redirect_handler = RedirectHandlerWithException( trino.exceptions.TrinoAuthError( @@ -460,7 +459,7 @@ def test_oauth2_refresh_token_flow(sample_post_response_data): @pytest.mark.parametrize("attempts", [6, 10]) -@httprettified +@responses.activate def test_oauth2_exceed_max_attempts(attempts, sample_post_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -471,17 +470,17 @@ def test_oauth2_exceed_max_attempts(attempts, sample_post_response_data): post_statement_callback = PostStatementCallback(redirect_server, token_server, [token], sample_post_response_data) # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", - body=post_statement_callback) + responses.add_callback( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + callback=post_statement_callback) # bind get token get_token_callback = GetTokenCallback(token_server, token, attempts) - httpretty.register_uri( - method=httpretty.GET, - uri=f"{TOKEN_RESOURCE}/{challenge_id}", - body=get_token_callback) + responses.add_callback( + method=responses.GET, + url=f"{TOKEN_RESOURCE}/{challenge_id}", + callback=get_token_callback) redirect_handler = RedirectHandler() @@ -509,13 +508,13 @@ def test_oauth2_exceed_max_attempts(attempts, sample_post_response_data): ('x_redirect_server="redirect_server", x_token_server="token_server"', 'Error: header info didn\'t match x_redirect_server="redirect_server", x_token_server="token_server"'), # noqa: E501 ('Bearer x_redirect_server="redirect_server"', 'Error: header info didn\'t have x_token_server'), ]) -@httprettified +@responses.activate def test_oauth2_authentication_missing_headers(header, error): # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", - adding_headers={'WWW-Authenticate': header}, + responses.add( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + headers={'WWW-Authenticate': header}, status=401) request = TrinoRequest( @@ -543,7 +542,7 @@ def test_oauth2_authentication_missing_headers(header, error): 'x_token_server="{token_server}"' 'Bearer x_redirect_server="{redirect_server}",x_token_server="{token_server}",additional_challenge', ]) -@httprettified +@responses.activate def test_oauth2_header_parsing(header, sample_post_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -560,17 +559,17 @@ def post_statement(request, uri, response_headers): 'Basic realm': '"Trino"'}, ""] # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", - body=post_statement) + responses.add_callback( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + callback=post_statement) # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, - body=get_token_callback) + responses.add_callback( + method=responses.GET, + url=token_server, + callback=get_token_callback) redirect_handler = RedirectHandler() @@ -591,8 +590,7 @@ def post_statement(request, uri, response_headers): assert len(_get_token_requests(challenge_id)) == 1 -@pytest.mark.parametrize("http_status", [400, 401, 500]) -@httprettified +@responses.activate def test_oauth2_authentication_fail_token_server(http_status, sample_post_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -603,16 +601,18 @@ def test_oauth2_authentication_fail_token_server(http_status, sample_post_respon post_statement_callback = PostStatementCallback(redirect_server, token_server, [token], sample_post_response_data) # bind post statement - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", - body=post_statement_callback) - - httpretty.register_uri( - method=httpretty.GET, - uri=f"{TOKEN_RESOURCE}/{challenge_id}", + responses.add( + method=responses.POST, + url=f"{SERVER_ADDRESS}{constants.URL_STATEMENT_PATH}", + json=post_statement_callback, + ) + + responses.add( + method=responses.GET, + url=f"{TOKEN_RESOURCE}/{challenge_id}", status=http_status, - body="error") + body="error", + ) redirect_handler = RedirectHandler() @@ -623,7 +623,8 @@ def test_oauth2_authentication_fail_token_server(http_status, sample_post_respon user="test", ), http_scheme=constants.HTTPS, - auth=trino.auth.OAuth2Authentication(redirect_auth_url_handler=redirect_handler)) + auth=trino.auth.OAuth2Authentication(redirect_auth_url_handler=redirect_handler), + ) with pytest.raises(trino.exceptions.TrinoAuthError) as exp: request.post("select 1") @@ -634,7 +635,7 @@ def test_oauth2_authentication_fail_token_server(http_status, sample_post_respon assert len(_get_token_requests(challenge_id)) == 1 -@httprettified +@responses.activate def test_multithreaded_oauth2_authentication_flow(sample_post_response_data): redirect_handler = RedirectHandler() auth = trino.auth.OAuth2Authentication(redirect_auth_url_handler=redirect_handler) diff --git a/tests/unit/test_dbapi.py b/tests/unit/test_dbapi.py index ccd44d10..d98c5779 100644 --- a/tests/unit/test_dbapi.py +++ b/tests/unit/test_dbapi.py @@ -13,8 +13,7 @@ import uuid from unittest.mock import patch -import httpretty -from httpretty import httprettified +import responses from requests import Session from tests.unit.oauth_test_utils import _get_token_requests @@ -57,7 +56,7 @@ def test_http_session_is_defaulted_when_not_specified(mock_client): assert mock_client.TrinoRequest.http.Session.return_value in request_args -@httprettified +@responses.activate def test_token_retrieved_once_per_auth_instance(sample_post_response_data, sample_get_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -69,22 +68,22 @@ def test_token_retrieved_once_per_auth_instance(sample_post_response_data, sampl get_statement_callback = PostStatementCallback(redirect_server, token_server, [token], sample_get_response_data) # bind post statement to submit query - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}", + responses.add( + method=responses.POST, + url=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}", body=post_statement_callback) # bind get statement for result retrieval - httpretty.register_uri( - method=httpretty.GET, - uri=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}/20210817_140827_00000_arvdv/1", + responses.add( + method=responses.GET, + url=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}/20210817_140827_00000_arvdv/1", body=get_statement_callback) # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, + responses.add( + method=responses.GET, + url=token_server, body=get_token_callback) redirect_handler = RedirectHandler() @@ -101,9 +100,9 @@ def test_token_retrieved_once_per_auth_instance(sample_post_response_data, sampl # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, + responses.add( + method=responses.GET, + url=token_server, body=get_token_callback) redirect_handler = RedirectHandler() @@ -121,7 +120,7 @@ def test_token_retrieved_once_per_auth_instance(sample_post_response_data, sampl assert len(_get_token_requests(challenge_id)) == 1 -@httprettified +@responses.activate def test_token_retrieved_once_when_authentication_instance_is_shared(sample_post_response_data, sample_get_response_data): token = str(uuid.uuid4()) @@ -134,22 +133,22 @@ def test_token_retrieved_once_when_authentication_instance_is_shared(sample_post get_statement_callback = PostStatementCallback(redirect_server, token_server, [token], sample_get_response_data) # bind post statement to submit query - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}", + responses.add( + method=responses.POST, + url=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}", body=post_statement_callback) # bind get statement for result retrieval - httpretty.register_uri( - method=httpretty.GET, - uri=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}/20210817_140827_00000_arvdv/1", + responses.add( + method=responses.GET, + url=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}/20210817_140827_00000_arvdv/1", body=get_statement_callback) # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, + responses.add( + method=responses.GET, + url=token_server, body=get_token_callback) redirect_handler = RedirectHandler() @@ -168,9 +167,9 @@ def test_token_retrieved_once_when_authentication_instance_is_shared(sample_post # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, + responses.add( + method=responses.GET, + url=token_server, body=get_token_callback) with connect( @@ -187,7 +186,7 @@ def test_token_retrieved_once_when_authentication_instance_is_shared(sample_post assert len(_get_token_requests(challenge_id)) == 1 -@httprettified +@responses.activate def test_token_retrieved_once_when_multithreaded(sample_post_response_data, sample_get_response_data): token = str(uuid.uuid4()) challenge_id = str(uuid.uuid4()) @@ -199,24 +198,23 @@ def test_token_retrieved_once_when_multithreaded(sample_post_response_data, samp get_statement_callback = PostStatementCallback(redirect_server, token_server, [token], sample_get_response_data) # bind post statement to submit query - httpretty.register_uri( - method=httpretty.POST, - uri=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}", + responses.add( + method=responses.POST, + url=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}", body=post_statement_callback) # bind get statement for result retrieval - httpretty.register_uri( - method=httpretty.GET, - uri=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}/20210817_140827_00000_arvdv/1", + responses.add( + method=responses.GET, + url=f"{SERVER_ADDRESS}:8080{constants.URL_STATEMENT_PATH}/20210817_140827_00000_arvdv/1", body=get_statement_callback) # bind get token get_token_callback = GetTokenCallback(token_server, token) - httpretty.register_uri( - method=httpretty.GET, - uri=token_server, + responses.add( + method=responses.GET, + url=token_server, body=get_token_callback) - redirect_handler = RedirectHandler() authentication = OAuth2Authentication(redirect_auth_url_handler=redirect_handler)