From 0ab3cdaef33622b9dbb6170b330b566c415548b5 Mon Sep 17 00:00:00 2001 From: Xiang Yan Date: Wed, 25 Aug 2021 13:57:04 -0700 Subject: [PATCH] make core tests offline (#19986) * make core tests offline * clean up * use localhost instead of 127.0.0.1 * update * update * update --- .../async_tests/conftest.py | 0 .../async_tests/rest_client_async.py | 2 +- .../async_tests/test_basic_transport_async.py | 12 +- .../test_http_logging_policy_async.py | 28 +- .../tests/async_tests/test_pipeline_async.py | 21 +- .../tests/async_tests/test_request_asyncio.py | 11 +- .../tests/async_tests/test_request_trio.py | 8 +- .../test_rest_asyncio_transport.py | 8 +- .../test_rest_context_manager_async.py | 2 +- .../async_tests/test_rest_headers_async.py | 2 +- .../test_rest_http_request_async.py | 3 +- .../test_rest_http_response_async.py | 0 .../test_rest_stream_responses_async.py | 3 - .../async_tests/test_rest_trio_transport.py | 6 +- .../async_tests/test_retry_policy_async.py | 18 +- .../test_stream_generator_async.py | 4 +- .../async_tests/test_testserver_async.py | 2 +- .../test_tracing_decorator_async.py | 2 +- .../async_tests/test_universal_http_async.py | 26 +- sdk/core/azure-core/tests/conftest.py | 61 ++ .../{testserver_tests => }/rest_client.py | 2 +- .../azure-core/tests/test_base_polling.py | 3 - .../azure-core/tests/test_basic_transport.py | 24 +- .../tests/test_connection_string_parsing.py | 1 - .../tests/test_custom_hook_policy.py | 37 +- sdk/core/azure-core/tests/test_exceptions.py | 8 +- .../tests/test_http_logging_policy.py | 28 +- sdk/core/azure-core/tests/test_pipeline.py | 622 +++++++++--------- sdk/core/azure-core/tests/test_polling.py | 2 - .../tests/test_request_id_policy.py | 4 +- .../tests/test_requests_universal.py | 6 +- .../test_rest_context_manager.py | 0 .../test_rest_headers.py | 0 .../test_rest_http_request.py | 7 +- .../test_rest_http_response.py | 0 .../{testserver_tests => }/test_rest_query.py | 2 +- .../test_rest_stream_responses.py | 0 .../azure-core/tests/test_retry_policy.py | 18 +- .../azure-core/tests/test_stream_generator.py | 4 +- sdk/core/azure-core/tests/test_streaming.py | 1 - .../{testserver_tests => }/test_testserver.py | 1 - .../tests/test_tracing_decorator.py | 3 +- .../azure-core/tests/test_tracing_policy.py | 17 +- .../tests/test_universal_pipeline.py | 10 +- .../tests/test_user_agent_policy.py | 4 +- .../tests/testserver_tests/conftest.py | 92 --- .../coretestserver/test_routes/basic.py | 19 +- .../coretestserver/test_routes/helpers.py | 153 ++++- .../coretestserver/test_routes/structures.py | 19 + 49 files changed, 708 insertions(+), 598 deletions(-) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/conftest.py (100%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/rest_client_async.py (98%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_asyncio_transport.py (83%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_context_manager_async.py (97%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_headers_async.py (98%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_http_request_async.py (98%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_http_response_async.py (100%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_stream_responses_async.py (99%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_rest_trio_transport.py (82%) rename sdk/core/azure-core/tests/{testserver_tests => }/async_tests/test_testserver_async.py (97%) rename sdk/core/azure-core/tests/{testserver_tests => }/rest_client.py (99%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_rest_context_manager.py (100%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_rest_headers.py (100%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_rest_http_request.py (98%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_rest_http_response.py (100%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_rest_query.py (99%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_rest_stream_responses.py (100%) rename sdk/core/azure-core/tests/{testserver_tests => }/test_testserver.py (99%) delete mode 100644 sdk/core/azure-core/tests/testserver_tests/conftest.py create mode 100644 sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/structures.py diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/conftest.py b/sdk/core/azure-core/tests/async_tests/conftest.py similarity index 100% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/conftest.py rename to sdk/core/azure-core/tests/async_tests/conftest.py diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/rest_client_async.py b/sdk/core/azure-core/tests/async_tests/rest_client_async.py similarity index 98% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/rest_client_async.py rename to sdk/core/azure-core/tests/async_tests/rest_client_async.py index 1f2e3568bb02..2ad83c2dea4c 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/rest_client_async.py +++ b/sdk/core/azure-core/tests/async_tests/rest_client_async.py @@ -66,4 +66,4 @@ async def __aenter__(self): return self async def __aexit__(self, *exc_details) -> None: - await self._client.__aexit__(*exc_details) \ No newline at end of file + await self._client.__aexit__(*exc_details) diff --git a/sdk/core/azure-core/tests/async_tests/test_basic_transport_async.py b/sdk/core/azure-core/tests/async_tests/test_basic_transport_async.py index 90dbfc0ec6e6..1ae80db6f60c 100644 --- a/sdk/core/azure-core/tests/async_tests/test_basic_transport_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_basic_transport_async.py @@ -3,14 +3,6 @@ # Licensed under the MIT License. See LICENSE.txt in the project root for # license information. # ------------------------------------------------------------------------- -from six.moves.http_client import HTTPConnection -import time - -try: - from unittest import mock -except ImportError: - import mock - from azure.core.pipeline.transport import HttpRequest, AsyncHttpResponse, AsyncHttpTransport, AioHttpTransport from azure.core.pipeline.policies import HeadersPolicy from azure.core.pipeline import AsyncPipeline @@ -42,9 +34,9 @@ def body(self): @pytest.mark.asyncio -async def test_basic_options_aiohttp(): +async def test_basic_options_aiohttp(port): - request = HttpRequest("OPTIONS", "https://httpbin.org") + request = HttpRequest("OPTIONS", "http://localhost:{}/basic/string".format(port)) async with AsyncPipeline(AioHttpTransport(), policies=[]) as pipeline: response = await pipeline.run(request) diff --git a/sdk/core/azure-core/tests/async_tests/test_http_logging_policy_async.py b/sdk/core/azure-core/tests/async_tests/test_http_logging_policy_async.py index 13ed07d67af6..0c4e931bc4e2 100644 --- a/sdk/core/azure-core/tests/async_tests/test_http_logging_policy_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_http_logging_policy_async.py @@ -41,7 +41,7 @@ def emit(self, record): policy = HttpLoggingPolicy(logger=logger) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') http_response = HttpResponse(universal_request, None) http_response.status_code = 202 request = PipelineRequest(universal_request, PipelineContext(None)) @@ -54,7 +54,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' @@ -75,13 +75,13 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 12 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' assert mock_handler.messages[4].message == 'Response status: 202' assert mock_handler.messages[5].message == 'Response headers:' - assert mock_handler.messages[6].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[6].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[7].message == "Request method: 'GET'" assert mock_handler.messages[8].message == 'Request headers:' assert mock_handler.messages[9].message == 'No body was attached to the request' @@ -102,7 +102,7 @@ def emit(self, record): "Content-Type": "Caramel", "HateToo": "Chocolat", } - universal_request.url = "http://127.0.0.1/?country=france&city=aix" + universal_request.url = "http://localhost/?country=france&city=aix" policy.on_request(request) response = PipelineResponse(request, http_response, request.context) @@ -110,7 +110,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 10 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/?country=france&city=REDACTED'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/?country=france&city=REDACTED'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == "Request headers:" # Dict not ordered in Python, exact logging order doesn't matter @@ -156,7 +156,7 @@ def emit(self, record): policy = HttpLoggingPolicy() kwargs={'logger': logger} - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') http_response = HttpResponse(universal_request, None) http_response.status_code = 202 request = PipelineRequest(universal_request, PipelineContext(None, **kwargs)) @@ -169,7 +169,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' @@ -192,13 +192,13 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 12 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' assert mock_handler.messages[4].message == 'Response status: 202' assert mock_handler.messages[5].message == 'Response headers:' - assert mock_handler.messages[6].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[6].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[7].message == "Request method: 'GET'" assert mock_handler.messages[8].message == 'Request headers:' assert mock_handler.messages[9].message == 'No body was attached to the request' @@ -226,7 +226,7 @@ def emit(self, record): policy = HttpLoggingPolicy(logger=logger) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') universal_request.body = "testbody" http_response = HttpResponse(universal_request, None) http_response.status_code = 202 @@ -238,7 +238,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'A body is sent with the request' @@ -267,7 +267,7 @@ def emit(self, record): policy = HttpLoggingPolicy(logger=logger) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') mock = Mock() mock.__class__ = types.AsyncGeneratorType universal_request.body = mock @@ -281,7 +281,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'File upload' diff --git a/sdk/core/azure-core/tests/async_tests/test_pipeline_async.py b/sdk/core/azure-core/tests/async_tests/test_pipeline_async.py index ee3a97b953ff..a84d53093ca3 100644 --- a/sdk/core/azure-core/tests/async_tests/test_pipeline_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_pipeline_async.py @@ -88,11 +88,10 @@ def on_exception(self, requests, **kwargs): with pytest.raises(NotImplementedError): await pipeline.run(req) - @pytest.mark.asyncio -async def test_basic_aiohttp(): +async def test_basic_aiohttp(port): - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) policies = [ UserAgentPolicy("myusergant"), AsyncRedirectPolicy() @@ -105,10 +104,10 @@ async def test_basic_aiohttp(): assert isinstance(response.http_response.status_code, int) @pytest.mark.asyncio -async def test_basic_aiohttp_separate_session(): +async def test_basic_aiohttp_separate_session(port): session = aiohttp.ClientSession() - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) policies = [ UserAgentPolicy("myusergant"), AsyncRedirectPolicy() @@ -124,9 +123,9 @@ async def test_basic_aiohttp_separate_session(): await transport.session.close() @pytest.mark.asyncio -async def test_basic_async_requests(): +async def test_basic_async_requests(port): - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) policies = [ UserAgentPolicy("myusergant"), AsyncRedirectPolicy() @@ -186,9 +185,9 @@ def test_pass_in_http_logging_policy(): assert http_logging_policy.allowed_header_names == HttpLoggingPolicy.DEFAULT_HEADERS_WHITELIST.union({"x-ms-added-header"}) @pytest.mark.asyncio -async def test_conf_async_requests(): +async def test_conf_async_requests(port): - request = HttpRequest("GET", "https://bing.com/") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) policies = [ UserAgentPolicy("myusergant"), AsyncRedirectPolicy() @@ -198,10 +197,10 @@ async def test_conf_async_requests(): assert isinstance(response.http_response.status_code, int) -def test_conf_async_trio_requests(): +def test_conf_async_trio_requests(port): async def do(): - request = HttpRequest("GET", "https://bing.com/") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) policies = [ UserAgentPolicy("myusergant"), AsyncRedirectPolicy() diff --git a/sdk/core/azure-core/tests/async_tests/test_request_asyncio.py b/sdk/core/azure-core/tests/async_tests/test_request_asyncio.py index 92097a2265d8..55856ae6ca94 100644 --- a/sdk/core/azure-core/tests/async_tests/test_request_asyncio.py +++ b/sdk/core/azure-core/tests/async_tests/test_request_asyncio.py @@ -11,7 +11,7 @@ @pytest.mark.asyncio -async def test_async_gen_data(): +async def test_async_gen_data(port): class AsyncGen: def __init__(self): self._range = iter([b"azerty"]) @@ -26,14 +26,13 @@ async def __anext__(self): raise StopAsyncIteration async with AsyncioRequestsTransport() as transport: - req = HttpRequest('GET', 'http://httpbin.org/anything', data=AsyncGen()) + req = HttpRequest('GET', 'http://localhost:{}/basic/anything'.format(port), data=AsyncGen()) response = await transport.send(req) assert json.loads(response.text())['data'] == "azerty" @pytest.mark.asyncio -async def test_send_data(): +async def test_send_data(port): async with AsyncioRequestsTransport() as transport: - req = HttpRequest('PUT', 'http://httpbin.org/anything', data=b"azerty") + req = HttpRequest('PUT', 'http://localhost:{}/basic/anything'.format(port), data=b"azerty") response = await transport.send(req) - - assert json.loads(response.text())['data'] == "azerty" \ No newline at end of file + assert json.loads(response.text())['data'] == "azerty" diff --git a/sdk/core/azure-core/tests/async_tests/test_request_trio.py b/sdk/core/azure-core/tests/async_tests/test_request_trio.py index 2ab07bd5aa61..11a0058404f5 100644 --- a/sdk/core/azure-core/tests/async_tests/test_request_trio.py +++ b/sdk/core/azure-core/tests/async_tests/test_request_trio.py @@ -11,7 +11,7 @@ @pytest.mark.trio -async def test_async_gen_data(): +async def test_async_gen_data(port): class AsyncGen: def __init__(self): self._range = iter([b"azerty"]) @@ -26,14 +26,14 @@ async def __anext__(self): raise StopAsyncIteration async with TrioRequestsTransport() as transport: - req = HttpRequest('GET', 'http://httpbin.org/anything', data=AsyncGen()) + req = HttpRequest('GET', 'http://localhost:{}/basic/anything'.format(port), data=AsyncGen()) response = await transport.send(req) assert json.loads(response.text())['data'] == "azerty" @pytest.mark.trio -async def test_send_data(): +async def test_send_data(port): async with TrioRequestsTransport() as transport: - req = HttpRequest('PUT', 'http://httpbin.org/anything', data=b"azerty") + req = HttpRequest('PUT', 'http://localhost:{}/basic/anything'.format(port), data=b"azerty") response = await transport.send(req) assert json.loads(response.text())['data'] == "azerty" \ No newline at end of file diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_asyncio_transport.py b/sdk/core/azure-core/tests/async_tests/test_rest_asyncio_transport.py similarity index 83% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_asyncio_transport.py rename to sdk/core/azure-core/tests/async_tests/test_rest_asyncio_transport.py index 126487f92aa7..9f5052cdb4bd 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_asyncio_transport.py +++ b/sdk/core/azure-core/tests/async_tests/test_rest_asyncio_transport.py @@ -3,8 +3,6 @@ # Licensed under the MIT License. See LICENSE.txt in the project root for # license information. # ------------------------------------------------------------------------- -import json - from azure.core.pipeline.transport import AsyncioRequestsTransport from azure.core.rest import HttpRequest from rest_client_async import AsyncTestRestClient @@ -29,7 +27,7 @@ async def __anext__(self): async with AsyncioRequestsTransport() as transport: client = AsyncTestRestClient(port, transport=transport) - request = HttpRequest('GET', 'http://httpbin.org/anything', content=AsyncGen()) + request = HttpRequest('GET', 'http://localhost:{}/basic/anything'.format(port), content=AsyncGen()) response = await client.send_request(request) assert response.json()['data'] == "azerty" @@ -37,7 +35,7 @@ async def __anext__(self): async def test_send_data(port): async with AsyncioRequestsTransport() as transport: client = AsyncTestRestClient(port, transport=transport) - request = HttpRequest('PUT', 'http://httpbin.org/anything', content=b"azerty") + request = HttpRequest('PUT', 'http://localhost:{}/basic/anything'.format(port), content=b"azerty") response = await client.send_request(request) - assert response.json()['data'] == "azerty" \ No newline at end of file + assert response.json()['data'] == "azerty" diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_context_manager_async.py b/sdk/core/azure-core/tests/async_tests/test_rest_context_manager_async.py similarity index 97% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_context_manager_async.py rename to sdk/core/azure-core/tests/async_tests/test_rest_context_manager_async.py index 70ca63685b84..6866baa41f42 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_context_manager_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_rest_context_manager_async.py @@ -4,7 +4,7 @@ # Licensed under the MIT License. See LICENSE.txt in the project root for # license information. # ------------------------------------------------------------------------- -from azure.core.exceptions import HttpResponseError, ResponseNotReadError +from azure.core.exceptions import ResponseNotReadError import pytest from azure.core.rest import HttpRequest from rest_client_async import AsyncTestRestClient diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_headers_async.py b/sdk/core/azure-core/tests/async_tests/test_rest_headers_async.py similarity index 98% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_headers_async.py rename to sdk/core/azure-core/tests/async_tests/test_rest_headers_async.py index 4452e326126d..c7c3373fb583 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_headers_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_rest_headers_async.py @@ -33,4 +33,4 @@ async def test_response_headers_case_insensitive(client): response.headers["cAMeLCaSE-hEadER"] == "camelCase" ) - return response \ No newline at end of file + return response diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_http_request_async.py b/sdk/core/azure-core/tests/async_tests/test_rest_http_request_async.py similarity index 98% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_http_request_async.py rename to sdk/core/azure-core/tests/async_tests/test_rest_http_request_async.py index 67f9d419fb31..0d58b9cb36df 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_http_request_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_rest_http_request_async.py @@ -8,7 +8,6 @@ # Thank you httpx for your wonderful tests! import pytest from azure.core.rest import HttpRequest -from typing import AsyncGenerator import collections.abc @pytest.fixture @@ -87,4 +86,4 @@ async def content(): request = HttpRequest("POST", "http://example.org", content=content()) await assert_aiterator_body(request, b"test 123") # in this case, request._data is what we end up passing to the requests transport - assert isinstance(request._data, collections.abc.AsyncIterable) \ No newline at end of file + assert isinstance(request._data, collections.abc.AsyncIterable) diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_http_response_async.py b/sdk/core/azure-core/tests/async_tests/test_rest_http_response_async.py similarity index 100% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_http_response_async.py rename to sdk/core/azure-core/tests/async_tests/test_rest_http_response_async.py diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_stream_responses_async.py b/sdk/core/azure-core/tests/async_tests/test_rest_stream_responses_async.py similarity index 99% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_stream_responses_async.py rename to sdk/core/azure-core/tests/async_tests/test_rest_stream_responses_async.py index 19cd093222e1..d94f4748f90c 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_stream_responses_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_rest_stream_responses_async.py @@ -4,9 +4,6 @@ # license information. # ------------------------------------------------------------------------- from azure.core.exceptions import HttpResponseError, ServiceRequestError -import functools -import os -import json import pytest from azure.core.rest import HttpRequest from azure.core.exceptions import StreamClosedError, StreamConsumedError, ResponseNotReadError diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_trio_transport.py b/sdk/core/azure-core/tests/async_tests/test_rest_trio_transport.py similarity index 82% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_trio_transport.py rename to sdk/core/azure-core/tests/async_tests/test_rest_trio_transport.py index 7e563ca3d6c5..ba9981df6697 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_rest_trio_transport.py +++ b/sdk/core/azure-core/tests/async_tests/test_rest_trio_transport.py @@ -27,15 +27,15 @@ async def __anext__(self): async with TrioRequestsTransport() as transport: client = AsyncTestRestClient(port, transport=transport) - request = HttpRequest('GET', 'http://httpbin.org/anything', content=AsyncGen()) + request = HttpRequest('GET', 'http://localhost:{}/basic/anything'.format(port), content=AsyncGen()) response = await client.send_request(request) assert response.json()['data'] == "azerty" @pytest.mark.trio async def test_send_data(port): async with TrioRequestsTransport() as transport: - request = HttpRequest('PUT', 'http://httpbin.org/anything', content=b"azerty") + request = HttpRequest('PUT', 'http://localhost:{}/basic/anything'.format(port), content=b"azerty") client = AsyncTestRestClient(port, transport=transport) response = await client.send_request(request) - assert response.json()['data'] == "azerty" \ No newline at end of file + assert response.json()['data'] == "azerty" diff --git a/sdk/core/azure-core/tests/async_tests/test_retry_policy_async.py b/sdk/core/azure-core/tests/async_tests/test_retry_policy_async.py index e23a1a35ee46..faa0944e6399 100644 --- a/sdk/core/azure-core/tests/async_tests/test_retry_policy_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_retry_policy_async.py @@ -62,7 +62,7 @@ def test_retry_types(): @pytest.mark.parametrize("retry_after_input", [('0'), ('800'), ('1000'), ('1200')]) def test_retry_after(retry_after_input): retry_policy = AsyncRetryPolicy() - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost") response = HttpResponse(request, None) response.headers["retry-after-ms"] = retry_after_input pipeline_response = PipelineResponse(request, response, None) @@ -80,7 +80,7 @@ def test_retry_after(retry_after_input): @pytest.mark.parametrize("retry_after_input", [('0'), ('800'), ('1000'), ('1200')]) def test_x_ms_retry_after(retry_after_input): retry_policy = AsyncRetryPolicy() - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost") response = HttpResponse(request, None) response.headers["x-ms-retry-after-ms"] = retry_after_input pipeline_response = PipelineResponse(request, response, None) @@ -113,7 +113,7 @@ async def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> Pipe response.status_code = 429 return response - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') http_retry = AsyncRetryPolicy(retry_total = 1) transport = MockTransport() pipeline = AsyncPipeline(transport, [http_retry]) @@ -140,7 +140,7 @@ async def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> Pipe response.headers = headers return response - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') http_retry = AsyncRetryPolicy(retry_total = 1) transport = MockTransport() pipeline = AsyncPipeline(transport, [http_retry]) @@ -171,7 +171,7 @@ async def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> Pipe return response data = BytesIO(b"Lots of dataaaa") - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') http_request.set_streamed_data_body(data) http_retry = AsyncRetryPolicy(retry_total = 1) pipeline = AsyncPipeline(MockTransport(), [http_retry]) @@ -209,7 +209,7 @@ async def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> Pipe file = tempfile.NamedTemporaryFile(delete=False) file.write(b'Lots of dataaaa') file.close() - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') headers = {'Content-Type': "multipart/form-data"} http_request.headers = headers with open(file.name, 'rb') as f: @@ -241,7 +241,7 @@ def send(request, **kwargs): pipeline = AsyncPipeline(transport, [AsyncRetryPolicy(timeout=timeout)]) with pytest.raises(ServiceResponseTimeoutError): - await pipeline.run(HttpRequest("GET", "http://127.0.0.1/")) + await pipeline.run(HttpRequest("GET", "http://localhost/")) @pytest.mark.asyncio @@ -262,7 +262,7 @@ async def send(request, **kwargs): ) pipeline = AsyncPipeline(transport, [AsyncRetryPolicy()]) - await pipeline.run(HttpRequest("GET", "http://127.0.0.1/")) + await pipeline.run(HttpRequest("GET", "http://localhost/")) assert transport.send.call_count == 1, "policy should not retry: its first send succeeded" @@ -284,6 +284,6 @@ async def test_does_not_sleep_after_timeout(transport_error, expected_timeout_er pipeline = AsyncPipeline(transport, [AsyncRetryPolicy(timeout=timeout)]) with pytest.raises(expected_timeout_error): - await pipeline.run(HttpRequest("GET", "http://127.0.0.1/")) + await pipeline.run(HttpRequest("GET", "http://localhost/")) assert transport.sleep.call_count == 1 diff --git a/sdk/core/azure-core/tests/async_tests/test_stream_generator_async.py b/sdk/core/azure-core/tests/async_tests/test_stream_generator_async.py index de7bc894e42d..d90b5b15b4c9 100644 --- a/sdk/core/azure-core/tests/async_tests/test_stream_generator_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_stream_generator_async.py @@ -38,7 +38,7 @@ async def open(self): pass async def send(self, request, **kwargs): - request = HttpRequest('GET', 'http://127.0.0.1/') + request = HttpRequest('GET', 'http://localhost/') response = AsyncHttpResponse(request, None) response.status_code = 200 return response @@ -65,7 +65,7 @@ class AsyncMock(mock.MagicMock): async def __call__(self, *args, **kwargs): return super(AsyncMock, self).__call__(*args, **kwargs) - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') pipeline = AsyncPipeline(MockTransport()) http_response = AsyncHttpResponse(http_request, None) http_response.internal_response = MockInternalResponse() diff --git a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_testserver_async.py b/sdk/core/azure-core/tests/async_tests/test_testserver_async.py similarity index 97% rename from sdk/core/azure-core/tests/testserver_tests/async_tests/test_testserver_async.py rename to sdk/core/azure-core/tests/async_tests/test_testserver_async.py index 623033080bd1..4501e2dc3887 100644 --- a/sdk/core/azure-core/tests/testserver_tests/async_tests/test_testserver_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_testserver_async.py @@ -34,4 +34,4 @@ async def test_smoke(port): response = await sender.send(request) response.raise_for_status() await response.load_body() - assert response.text() == "Hello, world!" \ No newline at end of file + assert response.text() == "Hello, world!" diff --git a/sdk/core/azure-core/tests/async_tests/test_tracing_decorator_async.py b/sdk/core/azure-core/tests/async_tests/test_tracing_decorator_async.py index fa251d96e770..62b606218a0e 100644 --- a/sdk/core/azure-core/tests/async_tests/test_tracing_decorator_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_tracing_decorator_async.py @@ -31,7 +31,7 @@ class MockClient: @distributed_trace def __init__(self, policies=None, assert_current_span=False): time.sleep(0.001) - self.request = HttpRequest("GET", "https://bing.com") + self.request = HttpRequest("GET", "http://localhost") if policies is None: policies = [] policies.append(mock.Mock(spec=HTTPPolicy, send=self.verify_request)) diff --git a/sdk/core/azure-core/tests/async_tests/test_universal_http_async.py b/sdk/core/azure-core/tests/async_tests/test_universal_http_async.py index 64f003ad783b..fa65fc3353c5 100644 --- a/sdk/core/azure-core/tests/async_tests/test_universal_http_async.py +++ b/sdk/core/azure-core/tests/async_tests/test_universal_http_async.py @@ -23,13 +23,10 @@ # THE SOFTWARE. # #-------------------------------------------------------------------------- -import sys - from azure.core.pipeline.transport import ( HttpRequest, AioHttpTransport, AioHttpTransportResponse, - AsyncHttpTransport, AsyncioRequestsTransport, TrioRequestsTransport) @@ -37,13 +34,12 @@ import trio import pytest -from unittest import mock @pytest.mark.asyncio -async def test_basic_aiohttp(): +async def test_basic_aiohttp(port): - request = HttpRequest("GET", "https://www.bing.com/") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) async with AioHttpTransport() as sender: response = await sender.send(request) assert response.body() is not None @@ -52,18 +48,18 @@ async def test_basic_aiohttp(): assert isinstance(response.status_code, int) @pytest.mark.asyncio -async def test_aiohttp_auto_headers(): +async def test_aiohttp_auto_headers(port): - request = HttpRequest("POST", "https://www.bing.com/") + request = HttpRequest("POST", "http://localhost:{}/basic/string".format(port)) async with AioHttpTransport() as sender: response = await sender.send(request) auto_headers = response.internal_response.request_info.headers assert 'Content-Type' not in auto_headers @pytest.mark.asyncio -async def test_basic_async_requests(): +async def test_basic_async_requests(port): - request = HttpRequest("GET", "https://www.bing.com/") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) async with AsyncioRequestsTransport() as sender: response = await sender.send(request) assert response.body() is not None @@ -71,19 +67,19 @@ async def test_basic_async_requests(): assert isinstance(response.status_code, int) @pytest.mark.asyncio -async def test_conf_async_requests(): +async def test_conf_async_requests(port): - request = HttpRequest("GET", "https://www.bing.com/") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) async with AsyncioRequestsTransport() as sender: response = await sender.send(request) assert response.body() is not None assert isinstance(response.status_code, int) -def test_conf_async_trio_requests(): +def test_conf_async_trio_requests(port): async def do(): - request = HttpRequest("GET", "https://www.bing.com/") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) async with TrioRequestsTransport() as sender: return await sender.send(request) assert response.body() is not None @@ -169,4 +165,4 @@ def test_repr(): ) res.content_type = "text/plain" - assert repr(res) == "" \ No newline at end of file + assert repr(res) == "" diff --git a/sdk/core/azure-core/tests/conftest.py b/sdk/core/azure-core/tests/conftest.py index 0c5e14c094c7..fed8afda91d6 100644 --- a/sdk/core/azure-core/tests/conftest.py +++ b/sdk/core/azure-core/tests/conftest.py @@ -23,6 +23,14 @@ # IN THE SOFTWARE. # # -------------------------------------------------------------------------- +import time +import pytest +import signal +import os +import subprocess +import random +from six.moves import urllib +from rest_client import TestRestClient import sys # Ignore collection of async tests for Python 2 @@ -39,3 +47,56 @@ Tracer() except ImportError: pass + +def is_port_available(port_num): + req = urllib.request.Request("http://localhost:{}/health".format(port_num)) + try: + return urllib.request.urlopen(req).code != 200 + except Exception as e: + return True + +def get_port(): + count = 3 + for _ in range(count): + port_num = random.randrange(3000, 5000) + if is_port_available(port_num): + return port_num + raise TypeError("Tried {} times, can't find an open port".format(count)) + +@pytest.fixture +def port(): + return os.environ["FLASK_PORT"] + +def start_testserver(): + port = get_port() + os.environ["FLASK_APP"] = "coretestserver" + os.environ["FLASK_PORT"] = str(port) + cmd = "flask run -p {}".format(port) + if os.name == 'nt': #On windows, subprocess creation works without being in the shell + child_process = subprocess.Popen(cmd, env=dict(os.environ)) + else: + #On linux, have to set shell=True + child_process = subprocess.Popen(cmd, shell=True, preexec_fn=os.setsid, env=dict(os.environ)) + count = 5 + for _ in range(count): + if not is_port_available(port): + return child_process + time.sleep(1) + raise ValueError("Didn't start!") + +def terminate_testserver(process): + if os.name == 'nt': + process.kill() + else: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) # Send the signal to all the process groups + +@pytest.fixture(autouse=True, scope="package") +def testserver(): + """Start the Autorest testserver.""" + server = start_testserver() + yield + terminate_testserver(server) + +@pytest.fixture +def client(port): + return TestRestClient(port) diff --git a/sdk/core/azure-core/tests/testserver_tests/rest_client.py b/sdk/core/azure-core/tests/rest_client.py similarity index 99% rename from sdk/core/azure-core/tests/testserver_tests/rest_client.py rename to sdk/core/azure-core/tests/rest_client.py index 2d896ac3b6aa..0589ab1bf6bd 100644 --- a/sdk/core/azure-core/tests/testserver_tests/rest_client.py +++ b/sdk/core/azure-core/tests/rest_client.py @@ -80,4 +80,4 @@ def send_request(self, request, **kwargs): """ request_copy = deepcopy(request) request_copy.url = self._client.format_url(request_copy.url) - return self._client.send_request(request_copy, **kwargs) \ No newline at end of file + return self._client.send_request(request_copy, **kwargs) diff --git a/sdk/core/azure-core/tests/test_base_polling.py b/sdk/core/azure-core/tests/test_base_polling.py index 5ad08aa2334a..f5c1db343302 100644 --- a/sdk/core/azure-core/tests/test_base_polling.py +++ b/sdk/core/azure-core/tests/test_base_polling.py @@ -30,7 +30,6 @@ import types import pickle import platform -import unittest import six try: from unittest import mock @@ -41,8 +40,6 @@ from requests import Request, Response -from msrest import Deserializer - from azure.core.polling import LROPoller from azure.core.exceptions import DecodeError, HttpResponseError from azure.core import PipelineClient diff --git a/sdk/core/azure-core/tests/test_basic_transport.py b/sdk/core/azure-core/tests/test_basic_transport.py index d08feda5493f..7c57f53dfeee 100644 --- a/sdk/core/azure-core/tests/test_basic_transport.py +++ b/sdk/core/azure-core/tests/test_basic_transport.py @@ -5,9 +5,7 @@ # ------------------------------------------------------------------------- from six.moves.http_client import HTTPConnection from collections import OrderedDict -import time import sys -import json try: from unittest import mock @@ -96,12 +94,12 @@ def test_url_join(): assert _urljoin('devstoreaccount1/', 'testdir/') == 'devstoreaccount1/testdir/' -def test_http_client_response(): +def test_http_client_response(port): # Create a core request - request = HttpRequest("GET", "www.httpbin.org") + request = HttpRequest("GET", "http://localhost:{}".format(port)) # Fake a transport based on http.client - conn = HTTPConnection("www.httpbin.org") + conn = HTTPConnection("localhost", port) conn.request("GET", "/get") r1 = conn.getresponse() @@ -1108,10 +1106,11 @@ def test_close_unopened_transport(): transport = RequestsTransport() transport.close() -def test_timeout(caplog): + +def test_timeout(caplog, port): transport = RequestsTransport() - request = HttpRequest("GET", "https://www.bing.com") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) with caplog.at_level(logging.WARNING, logger="azure.core.pipeline.transport"): with Pipeline(transport) as pipeline: @@ -1119,10 +1118,11 @@ def test_timeout(caplog): assert "Tuple timeout setting is deprecated" not in caplog.text -def test_tuple_timeout(caplog): + +def test_tuple_timeout(caplog, port): transport = RequestsTransport() - request = HttpRequest("GET", "https://www.bing.com") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) with caplog.at_level(logging.WARNING, logger="azure.core.pipeline.transport"): with Pipeline(transport) as pipeline: @@ -1130,15 +1130,17 @@ def test_tuple_timeout(caplog): assert "Tuple timeout setting is deprecated" in caplog.text -def test_conflict_timeout(caplog): + +def test_conflict_timeout(caplog, port): transport = RequestsTransport() - request = HttpRequest("GET", "https://www.bing.com") + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) with pytest.raises(ValueError): with Pipeline(transport) as pipeline: pipeline.run(request, connection_timeout=(100, 100), read_timeout = 100) + @pytest.mark.skipif(sys.version_info < (3, 10), reason="Loop parameter is deprecated since Python 3.10") def test_aiohttp_loop(): import asyncio diff --git a/sdk/core/azure-core/tests/test_connection_string_parsing.py b/sdk/core/azure-core/tests/test_connection_string_parsing.py index 1decf6ce45a5..fe194c7766f4 100644 --- a/sdk/core/azure-core/tests/test_connection_string_parsing.py +++ b/sdk/core/azure-core/tests/test_connection_string_parsing.py @@ -1,4 +1,3 @@ -import sys import pytest from azure.core.utils import parse_connection_string diff --git a/sdk/core/azure-core/tests/test_custom_hook_policy.py b/sdk/core/azure-core/tests/test_custom_hook_policy.py index 3103025bd349..e553ca5a9811 100644 --- a/sdk/core/azure-core/tests/test_custom_hook_policy.py +++ b/sdk/core/azure-core/tests/test_custom_hook_policy.py @@ -3,23 +3,27 @@ # Licensed under the MIT License. # ------------------------------------ """Tests for the custom hook policy.""" +try: + from unittest import mock +except ImportError: + import mock from azure.core import PipelineClient from azure.core.pipeline.policies import CustomHookPolicy, UserAgentPolicy -from azure.core.pipeline.transport import HttpRequest -from azure.core.pipeline import PipelineRequest, PipelineContext +from azure.core.pipeline.transport import HttpTransport import pytest def test_response_hook_policy_in_init(): def test_callback(response): raise ValueError() - url = "https://bing.com" + transport = mock.MagicMock(spec=HttpTransport) + url = "http://localhost" custom_hook_policy = CustomHookPolicy(raw_response_hook=test_callback) policies = [ UserAgentPolicy("myuseragent"), custom_hook_policy ] - client = PipelineClient(base_url=url, policies=policies) + client = PipelineClient(base_url=url, policies=policies, transport=transport) request = client.get(url) with pytest.raises(ValueError): client._pipeline.run(request) @@ -28,13 +32,14 @@ def test_response_hook_policy_in_request(): def test_callback(response): raise ValueError() - url = "https://bing.com" + transport = mock.MagicMock(spec=HttpTransport) + url = "http://localhost" custom_hook_policy = CustomHookPolicy() policies = [ UserAgentPolicy("myuseragent"), custom_hook_policy ] - client = PipelineClient(base_url=url, policies=policies) + client = PipelineClient(base_url=url, policies=policies, transport=transport) request = client.get(url) with pytest.raises(ValueError): client._pipeline.run(request, raw_response_hook=test_callback) @@ -46,13 +51,14 @@ def test_callback(response): def test_callback_request(response): raise TypeError() - url = "https://bing.com" + transport = mock.MagicMock(spec=HttpTransport) + url = "http://localhost" custom_hook_policy = CustomHookPolicy(raw_response_hook=test_callback) policies = [ UserAgentPolicy("myuseragent"), custom_hook_policy ] - client = PipelineClient(base_url=url, policies=policies) + client = PipelineClient(base_url=url, policies=policies, transport=transport) request = client.get(url) with pytest.raises(TypeError): client._pipeline.run(request, raw_response_hook=test_callback_request) @@ -61,13 +67,14 @@ def test_request_hook_policy_in_init(): def test_callback(response): raise ValueError() - url = "https://bing.com" + transport = mock.MagicMock(spec=HttpTransport) + url = "http://localhost" custom_hook_policy = CustomHookPolicy(raw_request_hook=test_callback) policies = [ UserAgentPolicy("myuseragent"), custom_hook_policy ] - client = PipelineClient(base_url=url, policies=policies) + client = PipelineClient(base_url=url, policies=policies, transport=transport) request = client.get(url) with pytest.raises(ValueError): client._pipeline.run(request) @@ -76,13 +83,14 @@ def test_request_hook_policy_in_request(): def test_callback(response): raise ValueError() - url = "https://bing.com" + transport = mock.MagicMock(spec=HttpTransport) + url = "http://localhost" custom_hook_policy = CustomHookPolicy() policies = [ UserAgentPolicy("myuseragent"), custom_hook_policy ] - client = PipelineClient(base_url=url, policies=policies) + client = PipelineClient(base_url=url, policies=policies, transport=transport) request = client.get(url) with pytest.raises(ValueError): client._pipeline.run(request, raw_request_hook=test_callback) @@ -94,13 +102,14 @@ def test_callback(response): def test_callback_request(response): raise TypeError() - url = "https://bing.com" + transport = mock.MagicMock(spec=HttpTransport) + url = "http://localhost" custom_hook_policy = CustomHookPolicy(raw_request_hook=test_callback) policies = [ UserAgentPolicy("myuseragent"), custom_hook_policy ] - client = PipelineClient(base_url=url, policies=policies) + client = PipelineClient(base_url=url, policies=policies, transport=transport) request = client.get(url) with pytest.raises(TypeError): client._pipeline.run(request, raw_request_hook=test_callback_request) diff --git a/sdk/core/azure-core/tests/test_exceptions.py b/sdk/core/azure-core/tests/test_exceptions.py index 399c559cf944..a5d494e559b7 100644 --- a/sdk/core/azure-core/tests/test_exceptions.py +++ b/sdk/core/azure-core/tests/test_exceptions.py @@ -24,11 +24,7 @@ # # -------------------------------------------------------------------------- import json -import logging -import os - import requests -import pytest try: from unittest.mock import Mock except ImportError: @@ -159,8 +155,8 @@ def test_deserialized_httpresponse_error_message(self): assert isinstance(error.model, FakeErrorTwo) assert isinstance(error.error, ODataV4Format) - def test_httpresponse_error_with_response(self): - response = requests.get("https://bing.com") + def test_httpresponse_error_with_response(self, port): + response = requests.get("http://localhost:{}/basic/string".format(port)) http_response = RequestsTransportResponse(None, response) error = HttpResponseError(response=http_response) diff --git a/sdk/core/azure-core/tests/test_http_logging_policy.py b/sdk/core/azure-core/tests/test_http_logging_policy.py index bd427bdc3e79..c69b8b5f0e7c 100644 --- a/sdk/core/azure-core/tests/test_http_logging_policy.py +++ b/sdk/core/azure-core/tests/test_http_logging_policy.py @@ -42,7 +42,7 @@ def emit(self, record): policy = HttpLoggingPolicy(logger=logger) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') http_response = HttpResponse(universal_request, None) http_response.status_code = 202 request = PipelineRequest(universal_request, PipelineContext(None)) @@ -55,7 +55,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' @@ -76,13 +76,13 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 12 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' assert mock_handler.messages[4].message == 'Response status: 202' assert mock_handler.messages[5].message == 'Response headers:' - assert mock_handler.messages[6].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[6].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[7].message == "Request method: 'GET'" assert mock_handler.messages[8].message == 'Request headers:' assert mock_handler.messages[9].message == 'No body was attached to the request' @@ -103,7 +103,7 @@ def emit(self, record): "Content-Type": "Caramel", "HateToo": "Chocolat", } - universal_request.url = "http://127.0.0.1/?country=france&city=aix" + universal_request.url = "http://localhost/?country=france&city=aix" policy.on_request(request) response = PipelineResponse(request, http_response, request.context) @@ -111,7 +111,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 10 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/?country=france&city=REDACTED'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/?country=france&city=REDACTED'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == "Request headers:" # Dict not ordered in Python, exact logging order doesn't matter @@ -157,7 +157,7 @@ def emit(self, record): policy = HttpLoggingPolicy() kwargs={'logger': logger} - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') http_response = HttpResponse(universal_request, None) http_response.status_code = 202 request = PipelineRequest(universal_request, PipelineContext(None, **kwargs)) @@ -170,7 +170,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' @@ -193,13 +193,13 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 12 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'No body was attached to the request' assert mock_handler.messages[4].message == 'Response status: 202' assert mock_handler.messages[5].message == 'Response headers:' - assert mock_handler.messages[6].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[6].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[7].message == "Request method: 'GET'" assert mock_handler.messages[8].message == 'Request headers:' assert mock_handler.messages[9].message == 'No body was attached to the request' @@ -227,7 +227,7 @@ def emit(self, record): policy = HttpLoggingPolicy(logger=logger) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') universal_request.body = "testbody" http_response = HttpResponse(universal_request, None) http_response.status_code = 202 @@ -239,7 +239,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'A body is sent with the request' @@ -267,7 +267,7 @@ def emit(self, record): policy = HttpLoggingPolicy(logger=logger) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') mock = Mock() mock.__class__ = types.GeneratorType universal_request.body = mock @@ -281,7 +281,7 @@ def emit(self, record): assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 6 - assert mock_handler.messages[0].message == "Request URL: 'http://127.0.0.1/'" + assert mock_handler.messages[0].message == "Request URL: 'http://localhost/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'File upload' diff --git a/sdk/core/azure-core/tests/test_pipeline.py b/sdk/core/azure-core/tests/test_pipeline.py index f4bbfc6636c3..6d260c07e9fe 100644 --- a/sdk/core/azure-core/tests/test_pipeline.py +++ b/sdk/core/azure-core/tests/test_pipeline.py @@ -26,22 +26,13 @@ import json import requests -import datetime -from enum import Enum -import unittest try: from io import BytesIO except ImportError: from cStringIO import StringIO as BytesIO - -try: - from unittest import mock -except ImportError: - import mock import xml.etree.ElementTree as ET import sys -import requests import pytest from azure.core.configuration import Configuration @@ -117,322 +108,313 @@ def on_exception(self, requests, **kwargs): with pytest.raises(NotImplementedError): pipeline.run(req) -class TestRequestsTransport(unittest.TestCase): +def test_requests_socket_timeout(): + conf = Configuration() + request = HttpRequest("GET", "https://bing.com") + policies = [ + UserAgentPolicy("myusergant"), + RedirectPolicy() + ] + # Sometimes this will raise a read timeout, sometimes a socket timeout depending on timing. + # Either way, the error should always be wrapped as an AzureError to ensure it's caught + # by the retry policy. + with pytest.raises(AzureError): + with Pipeline(RequestsTransport(), policies=policies) as pipeline: + response = pipeline.run(request, connection_timeout=0.000001, read_timeout=0.000001) + +def test_format_url_basic(): + client = PipelineClientBase("https://bing.com") + formatted = client.format_url("/{foo}", foo="bar") + assert formatted == "https://bing.com/bar" - def test_basic_requests(self): +def test_format_url_with_query(): + client = PipelineClientBase("https://bing.com/path?query=testvalue&x=2ndvalue") + formatted = client.format_url("/{foo}", foo="bar") + assert formatted == "https://bing.com/path/bar?query=testvalue&x=2ndvalue" - conf = Configuration() - request = HttpRequest("GET", "https://bing.com") - policies = [ - UserAgentPolicy("myusergant"), - RedirectPolicy() - ] - with Pipeline(RequestsTransport(), policies=policies) as pipeline: - response = pipeline.run(request) +def test_format_url_missing_param_values(): + client = PipelineClientBase("https://bing.com/path") + formatted = client.format_url("/{foo}") + assert formatted == "https://bing.com/path" - assert pipeline._transport.session is None - assert isinstance(response.http_response.status_code, int) +def test_format_url_missing_param_values_with_query(): + client = PipelineClientBase("https://bing.com/path?query=testvalue&x=2ndvalue") + formatted = client.format_url("/{foo}") + assert formatted == "https://bing.com/path?query=testvalue&x=2ndvalue" - def test_basic_options_requests(self): +def test_format_url_extra_path(): + client = PipelineClientBase("https://bing.com/path") + formatted = client.format_url("/subpath/{foo}", foo="bar") + assert formatted == "https://bing.com/path/subpath/bar" - request = HttpRequest("OPTIONS", "https://httpbin.org") - policies = [ - UserAgentPolicy("myusergant"), - RedirectPolicy() - ] - with Pipeline(RequestsTransport(), policies=policies) as pipeline: - response = pipeline.run(request) - - assert pipeline._transport.session is None - assert isinstance(response.http_response.status_code, int) - - def test_requests_socket_timeout(self): - conf = Configuration() - request = HttpRequest("GET", "https://bing.com") - policies = [ - UserAgentPolicy("myusergant"), - RedirectPolicy() - ] - # Sometimes this will raise a read timeout, sometimes a socket timeout depending on timing. - # Either way, the error should always be wrapped as an AzureError to ensure it's caught - # by the retry policy. - with pytest.raises(AzureError): - with Pipeline(RequestsTransport(), policies=policies) as pipeline: - response = pipeline.run(request, connection_timeout=0.000001, read_timeout=0.000001) - - def test_basic_requests_separate_session(self): - - session = requests.Session() - request = HttpRequest("GET", "https://bing.com") - policies = [ - UserAgentPolicy("myusergant"), - RedirectPolicy() - ] - transport = RequestsTransport(session=session, session_owner=False) - with Pipeline(transport, policies=policies) as pipeline: - response = pipeline.run(request) - - assert transport.session - assert isinstance(response.http_response.status_code, int) - transport.close() - assert transport.session - transport.session.close() - -class TestClientPipelineURLFormatting(unittest.TestCase): - - def test_format_url_basic(self): - client = PipelineClientBase("https://bing.com") - formatted = client.format_url("/{foo}", foo="bar") - assert formatted == "https://bing.com/bar" - - def test_format_url_with_query(self): - client = PipelineClientBase("https://bing.com/path?query=testvalue&x=2ndvalue") - formatted = client.format_url("/{foo}", foo="bar") - assert formatted == "https://bing.com/path/bar?query=testvalue&x=2ndvalue" - - def test_format_url_missing_param_values(self): - client = PipelineClientBase("https://bing.com/path") - formatted = client.format_url("/{foo}") - assert formatted == "https://bing.com/path" - - def test_format_url_missing_param_values_with_query(self): - client = PipelineClientBase("https://bing.com/path?query=testvalue&x=2ndvalue") - formatted = client.format_url("/{foo}") - assert formatted == "https://bing.com/path?query=testvalue&x=2ndvalue" - - def test_format_url_extra_path(self): - client = PipelineClientBase("https://bing.com/path") - formatted = client.format_url("/subpath/{foo}", foo="bar") - assert formatted == "https://bing.com/path/subpath/bar" - - def test_format_url_complex_params(self): - client = PipelineClientBase("https://bing.com/path") - formatted = client.format_url("/subpath/{a}/{b}/foo/{c}/bar", a="X", c="Y") - assert formatted == "https://bing.com/path/subpath/X/foo/Y/bar" - - def test_format_url_extra_path_missing_values(self): - client = PipelineClientBase("https://bing.com/path") - formatted = client.format_url("/subpath/{foo}") - assert formatted == "https://bing.com/path/subpath" - - def test_format_url_extra_path_missing_values_with_query(self): - client = PipelineClientBase("https://bing.com/path?query=testvalue&x=2ndvalue") - formatted = client.format_url("/subpath/{foo}") - assert formatted == "https://bing.com/path/subpath?query=testvalue&x=2ndvalue" - - def test_format_url_full_url(self): - client = PipelineClientBase("https://bing.com/path") - formatted = client.format_url("https://google.com/subpath/{foo}", foo="bar") - assert formatted == "https://google.com/subpath/bar" - - def test_format_url_no_base_url(self): - client = PipelineClientBase(None) - formatted = client.format_url("https://google.com/subpath/{foo}", foo="bar") - assert formatted == "https://google.com/subpath/bar" - - def test_format_incorrect_endpoint(self): - # https://github.com/Azure/azure-sdk-for-python/pull/12106 - client = PipelineClientBase('{Endpoint}/text/analytics/v3.0') - with pytest.raises(ValueError) as exp: - client.format_url("foo/bar") - assert str(exp.value) == "The value provided for the url part Endpoint was incorrect, and resulted in an invalid url" - -class TestClientRequest(unittest.TestCase): - def test_request_json(self): - - request = HttpRequest("GET", "/") - data = "Lots of dataaaa" - request.set_json_body(data) - - self.assertEqual(request.data, json.dumps(data)) - self.assertEqual(request.headers.get("Content-Length"), "17") - - def test_request_data(self): - - request = HttpRequest("GET", "/") - data = "Lots of dataaaa" - request.set_bytes_body(data) - - self.assertEqual(request.data, data) - self.assertEqual(request.headers.get("Content-Length"), "15") - - def test_request_stream(self): - request = HttpRequest("GET", "/") - - data = b"Lots of dataaaa" - request.set_streamed_data_body(data) - self.assertEqual(request.data, data) - - def data_gen(): - for i in range(10): - yield i - data = data_gen() - request.set_streamed_data_body(data) - self.assertEqual(request.data, data) - - data = BytesIO(b"Lots of dataaaa") - request.set_streamed_data_body(data) - self.assertEqual(request.data, data) - - - def test_request_xml(self): - request = HttpRequest("GET", "/") - data = ET.Element("root") - request.set_xml_body(data) - - assert request.data == b"\n" - - def test_request_url_with_params(self): - - request = HttpRequest("GET", "/") - request.url = "a/b/c?t=y" - request.format_parameters({"g": "h"}) - - self.assertIn(request.url, ["a/b/c?g=h&t=y", "a/b/c?t=y&g=h"]) - - def test_request_url_with_params_as_list(self): - - request = HttpRequest("GET", "/") - request.url = "a/b/c?t=y" - request.format_parameters({"g": ["h","i"]}) - - self.assertIn(request.url, ["a/b/c?g=h&g=i&t=y", "a/b/c?t=y&g=h&g=i"]) - - def test_request_url_with_params_with_none_in_list(self): - - request = HttpRequest("GET", "/") - request.url = "a/b/c?t=y" - with pytest.raises(ValueError): - request.format_parameters({"g": ["h",None]}) - - def test_request_url_with_params_with_none(self): - - request = HttpRequest("GET", "/") - request.url = "a/b/c?t=y" - with pytest.raises(ValueError): - request.format_parameters({"g": None}) - - - def test_request_text(self): - client = PipelineClientBase('http://example.org') - request = client.get( - "/", - content="foo" - ) - - # In absence of information, everything is JSON (double quote added) - assert request.data == json.dumps("foo") - - request = client.post( - "/", - headers={'content-type': 'text/whatever'}, - content="foo" - ) - - # We want a direct string - assert request.data == "foo" - - def test_repr(self): - request = HttpRequest("GET", "hello.com") - assert repr(request) == "" - - def test_add_custom_policy(self): - class BooPolicy(HTTPPolicy): - def send(*args): - raise AzureError('boo') - - class FooPolicy(HTTPPolicy): - def send(*args): - raise AzureError('boo') - - config = Configuration() - retry_policy = RetryPolicy() - config.retry_policy = retry_policy - boo_policy = BooPolicy() - foo_policy = FooPolicy() - client = PipelineClient(base_url="test", config=config, per_call_policies=boo_policy) - policies = client._pipeline._impl_policies - assert boo_policy in policies - pos_boo = policies.index(boo_policy) - pos_retry = policies.index(retry_policy) - assert pos_boo < pos_retry - - client = PipelineClient(base_url="test", config=config, per_call_policies=[boo_policy]) - policies = client._pipeline._impl_policies - assert boo_policy in policies - pos_boo = policies.index(boo_policy) - pos_retry = policies.index(retry_policy) - assert pos_boo < pos_retry - - client = PipelineClient(base_url="test", config=config, per_retry_policies=boo_policy) - policies = client._pipeline._impl_policies - assert boo_policy in policies - pos_boo = policies.index(boo_policy) - pos_retry = policies.index(retry_policy) - assert pos_boo > pos_retry - - client = PipelineClient(base_url="test", config=config, per_retry_policies=[boo_policy]) - policies = client._pipeline._impl_policies - assert boo_policy in policies - pos_boo = policies.index(boo_policy) - pos_retry = policies.index(retry_policy) - assert pos_boo > pos_retry - - client = PipelineClient(base_url="test", config=config, per_call_policies=boo_policy, per_retry_policies=foo_policy) - policies = client._pipeline._impl_policies - assert boo_policy in policies - assert foo_policy in policies - pos_boo = policies.index(boo_policy) - pos_foo = policies.index(foo_policy) - pos_retry = policies.index(retry_policy) - assert pos_boo < pos_retry - assert pos_foo > pos_retry - - client = PipelineClient(base_url="test", config=config, per_call_policies=[boo_policy], - per_retry_policies=[foo_policy]) - policies = client._pipeline._impl_policies - assert boo_policy in policies - assert foo_policy in policies - pos_boo = policies.index(boo_policy) - pos_foo = policies.index(foo_policy) - pos_retry = policies.index(retry_policy) - assert pos_boo < pos_retry - assert pos_foo > pos_retry - - policies = [UserAgentPolicy(), - RetryPolicy(), - DistributedTracingPolicy()] - client = PipelineClient(base_url="test", policies=policies, per_call_policies=boo_policy) - actual_policies = client._pipeline._impl_policies - assert boo_policy == actual_policies[0] - client = PipelineClient(base_url="test", policies=policies, per_call_policies=[boo_policy]) - actual_policies = client._pipeline._impl_policies - assert boo_policy == actual_policies[0] +def test_format_url_complex_params(): + client = PipelineClientBase("https://bing.com/path") + formatted = client.format_url("/subpath/{a}/{b}/foo/{c}/bar", a="X", c="Y") + assert formatted == "https://bing.com/path/subpath/X/foo/Y/bar" + +def test_format_url_extra_path_missing_values(): + client = PipelineClientBase("https://bing.com/path") + formatted = client.format_url("/subpath/{foo}") + assert formatted == "https://bing.com/path/subpath" + +def test_format_url_extra_path_missing_values_with_query(): + client = PipelineClientBase("https://bing.com/path?query=testvalue&x=2ndvalue") + formatted = client.format_url("/subpath/{foo}") + assert formatted == "https://bing.com/path/subpath?query=testvalue&x=2ndvalue" + +def test_format_url_full_url(): + client = PipelineClientBase("https://bing.com/path") + formatted = client.format_url("https://google.com/subpath/{foo}", foo="bar") + assert formatted == "https://google.com/subpath/bar" + +def test_format_url_no_base_url(): + client = PipelineClientBase(None) + formatted = client.format_url("https://google.com/subpath/{foo}", foo="bar") + assert formatted == "https://google.com/subpath/bar" + +def test_format_incorrect_endpoint(): + # https://github.com/Azure/azure-sdk-for-python/pull/12106 + client = PipelineClientBase('{Endpoint}/text/analytics/v3.0') + with pytest.raises(ValueError) as exp: + client.format_url("foo/bar") + assert str(exp.value) == "The value provided for the url part Endpoint was incorrect, and resulted in an invalid url" + +def test_request_json(): + + request = HttpRequest("GET", "/") + data = "Lots of dataaaa" + request.set_json_body(data) + + assert request.data == json.dumps(data) + assert request.headers.get("Content-Length") == "17" + +def test_request_data(): + + request = HttpRequest("GET", "/") + data = "Lots of dataaaa" + request.set_bytes_body(data) + + assert request.data == data + assert request.headers.get("Content-Length") == "15" + +def test_request_stream(): + request = HttpRequest("GET", "/") + + data = b"Lots of dataaaa" + request.set_streamed_data_body(data) + assert request.data == data + + def data_gen(): + for i in range(10): + yield i + data = data_gen() + request.set_streamed_data_body(data) + assert request.data == data + + data = BytesIO(b"Lots of dataaaa") + request.set_streamed_data_body(data) + assert request.data == data + + +def test_request_xml(): + request = HttpRequest("GET", "/") + data = ET.Element("root") + request.set_xml_body(data) + + assert request.data == b"\n" +def test_request_url_with_params(): + + request = HttpRequest("GET", "/") + request.url = "a/b/c?t=y" + request.format_parameters({"g": "h"}) + + assert request.url in ["a/b/c?g=h&t=y", "a/b/c?t=y&g=h"] + +def test_request_url_with_params_as_list(): + + request = HttpRequest("GET", "/") + request.url = "a/b/c?t=y" + request.format_parameters({"g": ["h","i"]}) + + assert request.url in ["a/b/c?g=h&g=i&t=y", "a/b/c?t=y&g=h&g=i"] + +def test_request_url_with_params_with_none_in_list(): + + request = HttpRequest("GET", "/") + request.url = "a/b/c?t=y" + with pytest.raises(ValueError): + request.format_parameters({"g": ["h",None]}) + +def test_request_url_with_params_with_none(): + + request = HttpRequest("GET", "/") + request.url = "a/b/c?t=y" + with pytest.raises(ValueError): + request.format_parameters({"g": None}) + +def test_repr(): + request = HttpRequest("GET", "hello.com") + assert repr(request) == "" + +def test_add_custom_policy(): + class BooPolicy(HTTPPolicy): + def send(*args): + raise AzureError('boo') + + class FooPolicy(HTTPPolicy): + def send(*args): + raise AzureError('boo') + + config = Configuration() + retry_policy = RetryPolicy() + config.retry_policy = retry_policy + boo_policy = BooPolicy() + foo_policy = FooPolicy() + client = PipelineClient(base_url="test", config=config, per_call_policies=boo_policy) + policies = client._pipeline._impl_policies + assert boo_policy in policies + pos_boo = policies.index(boo_policy) + pos_retry = policies.index(retry_policy) + assert pos_boo < pos_retry + + client = PipelineClient(base_url="test", config=config, per_call_policies=[boo_policy]) + policies = client._pipeline._impl_policies + assert boo_policy in policies + pos_boo = policies.index(boo_policy) + pos_retry = policies.index(retry_policy) + assert pos_boo < pos_retry + + client = PipelineClient(base_url="test", config=config, per_retry_policies=boo_policy) + policies = client._pipeline._impl_policies + assert boo_policy in policies + pos_boo = policies.index(boo_policy) + pos_retry = policies.index(retry_policy) + assert pos_boo > pos_retry + + client = PipelineClient(base_url="test", config=config, per_retry_policies=[boo_policy]) + policies = client._pipeline._impl_policies + assert boo_policy in policies + pos_boo = policies.index(boo_policy) + pos_retry = policies.index(retry_policy) + assert pos_boo > pos_retry + + client = PipelineClient(base_url="test", config=config, per_call_policies=boo_policy, per_retry_policies=foo_policy) + policies = client._pipeline._impl_policies + assert boo_policy in policies + assert foo_policy in policies + pos_boo = policies.index(boo_policy) + pos_foo = policies.index(foo_policy) + pos_retry = policies.index(retry_policy) + assert pos_boo < pos_retry + assert pos_foo > pos_retry + + client = PipelineClient(base_url="test", config=config, per_call_policies=[boo_policy], + per_retry_policies=[foo_policy]) + policies = client._pipeline._impl_policies + assert boo_policy in policies + assert foo_policy in policies + pos_boo = policies.index(boo_policy) + pos_foo = policies.index(foo_policy) + pos_retry = policies.index(retry_policy) + assert pos_boo < pos_retry + assert pos_foo > pos_retry + + policies = [UserAgentPolicy(), + RetryPolicy(), + DistributedTracingPolicy()] + client = PipelineClient(base_url="test", policies=policies, per_call_policies=boo_policy) + actual_policies = client._pipeline._impl_policies + assert boo_policy == actual_policies[0] + client = PipelineClient(base_url="test", policies=policies, per_call_policies=[boo_policy]) + actual_policies = client._pipeline._impl_policies + assert boo_policy == actual_policies[0] + + client = PipelineClient(base_url="test", policies=policies, per_retry_policies=foo_policy) + actual_policies = client._pipeline._impl_policies + assert foo_policy == actual_policies[2] + client = PipelineClient(base_url="test", policies=policies, per_retry_policies=[foo_policy]) + actual_policies = client._pipeline._impl_policies + assert foo_policy == actual_policies[2] + + client = PipelineClient(base_url="test", policies=policies, per_call_policies=boo_policy, + per_retry_policies=foo_policy) + actual_policies = client._pipeline._impl_policies + assert boo_policy == actual_policies[0] + assert foo_policy == actual_policies[3] + client = PipelineClient(base_url="test", policies=policies, per_call_policies=[boo_policy], + per_retry_policies=[foo_policy]) + actual_policies = client._pipeline._impl_policies + assert boo_policy == actual_policies[0] + assert foo_policy == actual_policies[3] + + policies = [UserAgentPolicy(), + DistributedTracingPolicy()] + with pytest.raises(ValueError): client = PipelineClient(base_url="test", policies=policies, per_retry_policies=foo_policy) - actual_policies = client._pipeline._impl_policies - assert foo_policy == actual_policies[2] + with pytest.raises(ValueError): client = PipelineClient(base_url="test", policies=policies, per_retry_policies=[foo_policy]) - actual_policies = client._pipeline._impl_policies - assert foo_policy == actual_policies[2] - - client = PipelineClient(base_url="test", policies=policies, per_call_policies=boo_policy, - per_retry_policies=foo_policy) - actual_policies = client._pipeline._impl_policies - assert boo_policy == actual_policies[0] - assert foo_policy == actual_policies[3] - client = PipelineClient(base_url="test", policies=policies, per_call_policies=[boo_policy], - per_retry_policies=[foo_policy]) - actual_policies = client._pipeline._impl_policies - assert boo_policy == actual_policies[0] - assert foo_policy == actual_policies[3] - - policies = [UserAgentPolicy(), - DistributedTracingPolicy()] - with pytest.raises(ValueError): - client = PipelineClient(base_url="test", policies=policies, per_retry_policies=foo_policy) - with pytest.raises(ValueError): - client = PipelineClient(base_url="test", policies=policies, per_retry_policies=[foo_policy]) - -if __name__ == "__main__": - unittest.main() + +def test_basic_requests(port): + + conf = Configuration() + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) + policies = [ + UserAgentPolicy("myusergant"), + RedirectPolicy() + ] + with Pipeline(RequestsTransport(), policies=policies) as pipeline: + response = pipeline.run(request) + + assert pipeline._transport.session is None + assert isinstance(response.http_response.status_code, int) + +def test_basic_options_requests(port): + + request = HttpRequest("OPTIONS", "http://localhost:{}/basic/string".format(port)) + policies = [ + UserAgentPolicy("myusergant"), + RedirectPolicy() + ] + with Pipeline(RequestsTransport(), policies=policies) as pipeline: + response = pipeline.run(request) + + assert pipeline._transport.session is None + assert isinstance(response.http_response.status_code, int) + +def test_basic_requests_separate_session(port): + + session = requests.Session() + request = HttpRequest("GET", "http://localhost:{}/basic/string".format(port)) + policies = [ + UserAgentPolicy("myusergant"), + RedirectPolicy() + ] + transport = RequestsTransport(session=session, session_owner=False) + with Pipeline(transport, policies=policies) as pipeline: + response = pipeline.run(request) + + assert transport.session + assert isinstance(response.http_response.status_code, int) + transport.close() + assert transport.session + transport.session.close() + +def test_request_text(port): + client = PipelineClientBase("http://localhost:{}".format(port)) + request = client.get( + "/", + content="foo" + ) + + # In absence of information, everything is JSON (double quote added) + assert request.data == json.dumps("foo") + + request = client.post( + "/", + headers={'content-type': 'text/whatever'}, + content="foo" + ) + + # We want a direct string + assert request.data == "foo" diff --git a/sdk/core/azure-core/tests/test_polling.py b/sdk/core/azure-core/tests/test_polling.py index 0eda477be5c7..6bdfc4686657 100644 --- a/sdk/core/azure-core/tests/test_polling.py +++ b/sdk/core/azure-core/tests/test_polling.py @@ -39,8 +39,6 @@ LROBasePolling, LocationPolling ) from msrest.serialization import Model -from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import HttpResponse @pytest.fixture diff --git a/sdk/core/azure-core/tests/test_request_id_policy.py b/sdk/core/azure-core/tests/test_request_id_policy.py index a118128ece1c..7da467b467c2 100644 --- a/sdk/core/azure-core/tests/test_request_id_policy.py +++ b/sdk/core/azure-core/tests/test_request_id_policy.py @@ -30,7 +30,7 @@ def test_request_id_policy(auto_request_id, request_id_init, request_id_set, req request_id_policy = RequestIdPolicy(**kwargs) if request_id_set != "_unset": request_id_policy.set_request_id(request_id_set) - request = HttpRequest('GET', 'http://127.0.0.1/') + request = HttpRequest('GET', 'http://localhost/') pipeline_request = PipelineRequest(request, PipelineContext(None)) if request_id_req != "_unset": pipeline_request.context.options['request_id'] = request_id_req @@ -58,7 +58,7 @@ def test_request_id_policy(auto_request_id, request_id_init, request_id_set, req def test_request_id_already_exists(): """Test policy with no other policy and happy path""" request_id_policy = RequestIdPolicy() - request = HttpRequest('GET', 'http://127.0.0.1/') + request = HttpRequest('GET', 'http://localhost/') request.headers["x-ms-client-request-id"] = "VALUE" pipeline_request = PipelineRequest(request, PipelineContext(None)) request_id_policy.on_request(pipeline_request) diff --git a/sdk/core/azure-core/tests/test_requests_universal.py b/sdk/core/azure-core/tests/test_requests_universal.py index 5a0f778a6b10..b965d4fd3d69 100644 --- a/sdk/core/azure-core/tests/test_requests_universal.py +++ b/sdk/core/azure-core/tests/test_requests_universal.py @@ -24,11 +24,9 @@ # # -------------------------------------------------------------------------- import concurrent.futures -import pytest import requests.utils from azure.core.pipeline.transport import HttpRequest, RequestsTransport, RequestsTransportResponse -from azure.core.configuration import Configuration def test_threading_basic_requests(): @@ -46,8 +44,8 @@ def thread_body(local_sender): future = executor.submit(thread_body, sender) assert future.result() -def test_requests_auto_headers(): - request = HttpRequest("POST", "https://www.bing.com/") +def test_requests_auto_headers(port): + request = HttpRequest("POST", "http://localhost:{}/basic/string".format(port)) with RequestsTransport() as sender: response = sender.send(request) auto_headers = response.internal_response.request.headers diff --git a/sdk/core/azure-core/tests/testserver_tests/test_rest_context_manager.py b/sdk/core/azure-core/tests/test_rest_context_manager.py similarity index 100% rename from sdk/core/azure-core/tests/testserver_tests/test_rest_context_manager.py rename to sdk/core/azure-core/tests/test_rest_context_manager.py diff --git a/sdk/core/azure-core/tests/testserver_tests/test_rest_headers.py b/sdk/core/azure-core/tests/test_rest_headers.py similarity index 100% rename from sdk/core/azure-core/tests/testserver_tests/test_rest_headers.py rename to sdk/core/azure-core/tests/test_rest_headers.py diff --git a/sdk/core/azure-core/tests/testserver_tests/test_rest_http_request.py b/sdk/core/azure-core/tests/test_rest_http_request.py similarity index 98% rename from sdk/core/azure-core/tests/testserver_tests/test_rest_http_request.py rename to sdk/core/azure-core/tests/test_rest_http_request.py index a7fe2d30a8b8..2c43f2b9b0bf 100644 --- a/sdk/core/azure-core/tests/testserver_tests/test_rest_http_request.py +++ b/sdk/core/azure-core/tests/test_rest_http_request.py @@ -11,7 +11,6 @@ import pytest import sys import collections -from typing import Generator from azure.core.rest import HttpRequest @pytest.fixture @@ -204,7 +203,7 @@ def test_multipart_invalid_key(key): files = {"file": io.BytesIO(b"")} with pytest.raises(TypeError) as e: HttpRequest( - url="http://127.0.0.1:8000/", + url="http://localhost:8000/", method="POST", data=data, files=files, @@ -221,7 +220,7 @@ def test_multipart_invalid_key_binary_string(): files = {"file": io.BytesIO(b"")} with pytest.raises(TypeError) as e: HttpRequest( - url="http://127.0.0.1:8000/", + url="http://localhost:8000/", method="POST", data=data, files=files, @@ -235,7 +234,7 @@ def test_multipart_invalid_value(value): data = {"text": value} files = {"file": io.BytesIO(b"")} with pytest.raises(TypeError) as e: - HttpRequest("POST", "http://127.0.0.1:8000/", data=data, files=files) + HttpRequest("POST", "http://localhost:8000/", data=data, files=files) assert "Invalid type for data value" in str(e.value) def test_empty_request(): diff --git a/sdk/core/azure-core/tests/testserver_tests/test_rest_http_response.py b/sdk/core/azure-core/tests/test_rest_http_response.py similarity index 100% rename from sdk/core/azure-core/tests/testserver_tests/test_rest_http_response.py rename to sdk/core/azure-core/tests/test_rest_http_response.py diff --git a/sdk/core/azure-core/tests/testserver_tests/test_rest_query.py b/sdk/core/azure-core/tests/test_rest_query.py similarity index 99% rename from sdk/core/azure-core/tests/testserver_tests/test_rest_query.py rename to sdk/core/azure-core/tests/test_rest_query.py index 7933e998f1e6..7aeda360da6a 100644 --- a/sdk/core/azure-core/tests/testserver_tests/test_rest_query.py +++ b/sdk/core/azure-core/tests/test_rest_query.py @@ -28,4 +28,4 @@ def test_request_url_with_params_with_none_in_list(): def test_request_url_with_params_with_none(): with pytest.raises(ValueError): - _format_query_into_url(url="a/b/c?t=y", params={"g": None}) \ No newline at end of file + _format_query_into_url(url="a/b/c?t=y", params={"g": None}) diff --git a/sdk/core/azure-core/tests/testserver_tests/test_rest_stream_responses.py b/sdk/core/azure-core/tests/test_rest_stream_responses.py similarity index 100% rename from sdk/core/azure-core/tests/testserver_tests/test_rest_stream_responses.py rename to sdk/core/azure-core/tests/test_rest_stream_responses.py diff --git a/sdk/core/azure-core/tests/test_retry_policy.py b/sdk/core/azure-core/tests/test_retry_policy.py index 9980b5367ee2..ce1a590fba26 100644 --- a/sdk/core/azure-core/tests/test_retry_policy.py +++ b/sdk/core/azure-core/tests/test_retry_policy.py @@ -65,7 +65,7 @@ def test_retry_types(): @pytest.mark.parametrize("retry_after_input", [('0'), ('800'), ('1000'), ('1200')]) def test_retry_after(retry_after_input): retry_policy = RetryPolicy() - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost") response = HttpResponse(request, None) response.headers["retry-after-ms"] = retry_after_input pipeline_response = PipelineResponse(request, response, None) @@ -83,7 +83,7 @@ def test_retry_after(retry_after_input): @pytest.mark.parametrize("retry_after_input", [('0'), ('800'), ('1000'), ('1200')]) def test_x_ms_retry_after(retry_after_input): retry_policy = RetryPolicy() - request = HttpRequest("GET", "https://bing.com") + request = HttpRequest("GET", "http://localhost") response = HttpResponse(request, None) response.headers["x-ms-retry-after-ms"] = retry_after_input pipeline_response = PipelineResponse(request, response, None) @@ -115,7 +115,7 @@ def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineRe response.status_code = 429 return response - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') http_retry = RetryPolicy(retry_total = 1) transport = MockTransport() pipeline = Pipeline(transport, [http_retry]) @@ -141,7 +141,7 @@ def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineRe response.headers = headers return response - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') http_retry = RetryPolicy(retry_total = 1) transport = MockTransport() pipeline = Pipeline(transport, [http_retry]) @@ -171,7 +171,7 @@ def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineRe return response data = BytesIO(b"Lots of dataaaa") - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') http_request.set_streamed_data_body(data) http_retry = RetryPolicy(retry_total = 1) pipeline = Pipeline(MockTransport(), [http_retry]) @@ -208,7 +208,7 @@ def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineRe file = tempfile.NamedTemporaryFile(delete=False) file.write(b'Lots of dataaaa') file.close() - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') headers = {'Content-Type': "multipart/form-data"} http_request.headers = headers with open(file.name, 'rb') as f: @@ -239,7 +239,7 @@ def send(request, **kwargs): pipeline = Pipeline(transport, [RetryPolicy(timeout=timeout)]) with pytest.raises(ServiceResponseTimeoutError): - response = pipeline.run(HttpRequest("GET", "http://127.0.0.1/")) + response = pipeline.run(HttpRequest("GET", "http://localhost/")) def test_timeout_defaults(): @@ -259,7 +259,7 @@ def send(request, **kwargs): ) pipeline = Pipeline(transport, [RetryPolicy()]) - pipeline.run(HttpRequest("GET", "http://127.0.0.1/")) + pipeline.run(HttpRequest("GET", "http://localhost/")) assert transport.send.call_count == 1, "policy should not retry: its first send succeeded" @@ -280,6 +280,6 @@ def test_does_not_sleep_after_timeout(transport_error, expected_timeout_error): pipeline = Pipeline(transport, [RetryPolicy(timeout=timeout)]) with pytest.raises(expected_timeout_error): - pipeline.run(HttpRequest("GET", "http://127.0.0.1/")) + pipeline.run(HttpRequest("GET", "http://localhost/")) assert transport.sleep.call_count == 1 diff --git a/sdk/core/azure-core/tests/test_stream_generator.py b/sdk/core/azure-core/tests/test_stream_generator.py index c43053eeab9d..1d8b3c7172c4 100644 --- a/sdk/core/azure-core/tests/test_stream_generator.py +++ b/sdk/core/azure-core/tests/test_stream_generator.py @@ -31,7 +31,7 @@ def open(self): pass def send(self, request, **kwargs): - request = HttpRequest('GET', 'http://127.0.0.1/') + request = HttpRequest('GET', 'http://localhost/') response = HttpResponse(request, None) response.status_code = 200 return response @@ -58,7 +58,7 @@ def __init__(self): def close(self): pass - http_request = HttpRequest('GET', 'http://127.0.0.1/') + http_request = HttpRequest('GET', 'http://localhost/') pipeline = Pipeline(MockTransport()) http_response = HttpResponse(http_request, None) http_response.internal_response = MockInternalResponse() diff --git a/sdk/core/azure-core/tests/test_streaming.py b/sdk/core/azure-core/tests/test_streaming.py index 26041540159d..2a5e6a4d0bb8 100644 --- a/sdk/core/azure-core/tests/test_streaming.py +++ b/sdk/core/azure-core/tests/test_streaming.py @@ -23,7 +23,6 @@ # THE SOFTWARE. # # -------------------------------------------------------------------------- -import os from azure.core import PipelineClient from azure.core.exceptions import DecodeError diff --git a/sdk/core/azure-core/tests/testserver_tests/test_testserver.py b/sdk/core/azure-core/tests/test_testserver.py similarity index 99% rename from sdk/core/azure-core/tests/testserver_tests/test_testserver.py rename to sdk/core/azure-core/tests/test_testserver.py index a31d449fbd53..0cf5e4ffc26e 100644 --- a/sdk/core/azure-core/tests/testserver_tests/test_testserver.py +++ b/sdk/core/azure-core/tests/test_testserver.py @@ -23,7 +23,6 @@ # THE SOFTWARE. # # -------------------------------------------------------------------------- -import pytest from azure.core.pipeline.transport import HttpRequest, RequestsTransport """This file does a simple call to the testserver to make sure we can use the testserver""" diff --git a/sdk/core/azure-core/tests/test_tracing_decorator.py b/sdk/core/azure-core/tests/test_tracing_decorator.py index b4a7d3918a8f..be9a820747e3 100644 --- a/sdk/core/azure-core/tests/test_tracing_decorator.py +++ b/sdk/core/azure-core/tests/test_tracing_decorator.py @@ -9,7 +9,6 @@ except ImportError: import mock -import sys import time import pytest @@ -31,7 +30,7 @@ class MockClient: @distributed_trace def __init__(self, policies=None, assert_current_span=False): time.sleep(0.001) - self.request = HttpRequest("GET", "https://bing.com") + self.request = HttpRequest("GET", "http://localhost") if policies is None: policies = [] policies.append(mock.Mock(spec=HTTPPolicy, send=self.verify_request)) diff --git a/sdk/core/azure-core/tests/test_tracing_policy.py b/sdk/core/azure-core/tests/test_tracing_policy.py index c52572d40357..2a0fc03a78e7 100644 --- a/sdk/core/azure-core/tests/test_tracing_policy.py +++ b/sdk/core/azure-core/tests/test_tracing_policy.py @@ -11,7 +11,6 @@ from azure.core.settings import settings from tracing_common import FakeSpan import time -import pytest try: from unittest import mock @@ -25,7 +24,7 @@ def test_distributed_tracing_policy_solo(): with FakeSpan(name="parent") as root_span: policy = DistributedTracingPolicy() - request = HttpRequest("GET", "http://127.0.0.1/temp?query=query") + request = HttpRequest("GET", "http://localhost/temp?query=query") request.headers["x-ms-client-request-id"] = "some client request id" pipeline_request = PipelineRequest(request, PipelineContext(None)) @@ -51,7 +50,7 @@ def test_distributed_tracing_policy_solo(): assert network_span.name == "/temp" assert network_span.attributes.get("http.method") == "GET" assert network_span.attributes.get("component") == "http" - assert network_span.attributes.get("http.url") == "http://127.0.0.1/temp?query=query" + assert network_span.attributes.get("http.url") == "http://localhost/temp?query=query" assert network_span.attributes.get("http.user_agent") is None assert network_span.attributes.get("x-ms-request-id") == "some request id" assert network_span.attributes.get("x-ms-client-request-id") == "some client request id" @@ -62,7 +61,7 @@ def test_distributed_tracing_policy_solo(): assert network_span.name == "/temp" assert network_span.attributes.get("http.method") == "GET" assert network_span.attributes.get("component") == "http" - assert network_span.attributes.get("http.url") == "http://127.0.0.1/temp?query=query" + assert network_span.attributes.get("http.url") == "http://localhost/temp?query=query" assert network_span.attributes.get("x-ms-client-request-id") == "some client request id" assert network_span.attributes.get("http.user_agent") is None assert network_span.attributes.get("x-ms-request-id") == None @@ -77,7 +76,7 @@ def test_distributed_tracing_policy_attributes(): 'myattr': 'myvalue' }) - request = HttpRequest("GET", "http://127.0.0.1/temp?query=query") + request = HttpRequest("GET", "http://localhost/temp?query=query") pipeline_request = PipelineRequest(request, PipelineContext(None)) policy.on_request(pipeline_request) @@ -133,7 +132,7 @@ def test_distributed_tracing_policy_with_user_agent(): with FakeSpan(name="parent") as root_span: policy = DistributedTracingPolicy() - request = HttpRequest("GET", "http://127.0.0.1") + request = HttpRequest("GET", "http://localhost") request.headers["x-ms-client-request-id"] = "some client request id" pipeline_request = PipelineRequest(request, PipelineContext(None)) @@ -165,7 +164,7 @@ def test_distributed_tracing_policy_with_user_agent(): assert network_span.name == "/" assert network_span.attributes.get("http.method") == "GET" assert network_span.attributes.get("component") == "http" - assert network_span.attributes.get("http.url") == "http://127.0.0.1" + assert network_span.attributes.get("http.url") == "http://localhost" assert network_span.attributes.get("http.user_agent").endswith("mytools") assert network_span.attributes.get("x-ms-request-id") == "some request id" assert network_span.attributes.get("x-ms-client-request-id") == "some client request id" @@ -175,7 +174,7 @@ def test_distributed_tracing_policy_with_user_agent(): assert network_span.name == "/" assert network_span.attributes.get("http.method") == "GET" assert network_span.attributes.get("component") == "http" - assert network_span.attributes.get("http.url") == "http://127.0.0.1" + assert network_span.attributes.get("http.url") == "http://localhost" assert network_span.attributes.get("http.user_agent").endswith("mytools") assert network_span.attributes.get("x-ms-client-request-id") == "some client request id" assert network_span.attributes.get("x-ms-request-id") is None @@ -188,7 +187,7 @@ def test_span_namer(): settings.tracing_implementation.set_value(FakeSpan) with FakeSpan(name="parent") as root_span: - request = HttpRequest("GET", "http://127.0.0.1/temp?query=query") + request = HttpRequest("GET", "http://localhost/temp?query=query") pipeline_request = PipelineRequest(request, PipelineContext(None)) def fixed_namer(http_request): diff --git a/sdk/core/azure-core/tests/test_universal_pipeline.py b/sdk/core/azure-core/tests/test_universal_pipeline.py index cb181ab5b9b1..ea5676374458 100644 --- a/sdk/core/azure-core/tests/test_universal_pipeline.py +++ b/sdk/core/azure-core/tests/test_universal_pipeline.py @@ -50,8 +50,6 @@ from azure.core.pipeline.policies import ( NetworkTraceLoggingPolicy, ContentDecodePolicy, - UserAgentPolicy, - HttpLoggingPolicy, RequestHistory, RetryPolicy, HTTPPolicy, @@ -94,7 +92,7 @@ def __deepcopy__(self, memodict={}): raise ValueError() body = Non_deep_copiable() - request = HttpRequest('GET', 'http://127.0.0.1/', {'user-agent': 'test_request_history'}) + request = HttpRequest('GET', 'http://localhost/', {'user-agent': 'test_request_history'}) request.body = body request_history = RequestHistory(request) assert request_history.http_request.headers == request.headers @@ -107,7 +105,7 @@ def __deepcopy__(self, memodict={}): raise TypeError() body = Non_deep_copiable() - request = HttpRequest('GET', 'http://127.0.0.1/', {'user-agent': 'test_request_history'}) + request = HttpRequest('GET', 'http://localhost/', {'user-agent': 'test_request_history'}) request.body = body request_history = RequestHistory(request) assert request_history.http_request.headers == request.headers @@ -116,7 +114,7 @@ def __deepcopy__(self, memodict={}): @mock.patch('azure.core.pipeline.policies._universal._LOGGER') def test_no_log(mock_http_logger): - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') request = PipelineRequest(universal_request, PipelineContext(None)) http_logger = NetworkTraceLoggingPolicy() response = PipelineResponse(request, HttpResponse(universal_request, None), request.context) @@ -193,7 +191,7 @@ def send(*args): def test_raw_deserializer(): raw_deserializer = ContentDecodePolicy() context = PipelineContext(None, stream=False) - universal_request = HttpRequest('GET', 'http://127.0.0.1/') + universal_request = HttpRequest('GET', 'http://localhost/') request = PipelineRequest(universal_request, context) def build_response(body, content_type=None): diff --git a/sdk/core/azure-core/tests/test_user_agent_policy.py b/sdk/core/azure-core/tests/test_user_agent_policy.py index 239daffbe63d..4f8b01c93b7e 100644 --- a/sdk/core/azure-core/tests/test_user_agent_policy.py +++ b/sdk/core/azure-core/tests/test_user_agent_policy.py @@ -21,7 +21,7 @@ def test_user_agent_policy(): user_agent = UserAgentPolicy(base_user_agent='foo', user_agent='bar', user_agent_use_env=False) assert user_agent._user_agent == 'bar foo' - request = HttpRequest('GET', 'http://127.0.0.1/') + request = HttpRequest('GET', 'http://localhost/') pipeline_request = PipelineRequest(request, PipelineContext(None)) pipeline_request.context.options['user_agent'] = 'xyz' @@ -35,6 +35,6 @@ def test_user_agent_environ(): policy = UserAgentPolicy(None) assert policy.user_agent.endswith("mytools") - request = HttpRequest('GET', 'http://127.0.0.1/') + request = HttpRequest('GET', 'http://localhost/') policy.on_request(PipelineRequest(request, PipelineContext(None))) assert request.headers["user-agent"].endswith("mytools") diff --git a/sdk/core/azure-core/tests/testserver_tests/conftest.py b/sdk/core/azure-core/tests/testserver_tests/conftest.py deleted file mode 100644 index 422904288fd1..000000000000 --- a/sdk/core/azure-core/tests/testserver_tests/conftest.py +++ /dev/null @@ -1,92 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- -import time -import pytest -import signal -import os -import subprocess -import random -from six.moves import urllib -from rest_client import TestRestClient -import sys - -# Ignore collection of async tests for Python 2 -collect_ignore = [] -if sys.version_info < (3, 5): - collect_ignore.append("async_tests") - -def is_port_available(port_num): - req = urllib.request.Request("http://localhost:{}/health".format(port_num)) - try: - return urllib.request.urlopen(req).code != 200 - except Exception as e: - return True - -def get_port(): - count = 3 - for _ in range(count): - port_num = random.randrange(3000, 5000) - if is_port_available(port_num): - return port_num - raise TypeError("Tried {} times, can't find an open port".format(count)) - -@pytest.fixture -def port(): - return os.environ["FLASK_PORT"] - -def start_testserver(): - port = get_port() - os.environ["FLASK_APP"] = "coretestserver" - os.environ["FLASK_PORT"] = str(port) - cmd = "flask run -p {}".format(port) - if os.name == 'nt': #On windows, subprocess creation works without being in the shell - child_process = subprocess.Popen(cmd, env=dict(os.environ)) - else: - #On linux, have to set shell=True - child_process = subprocess.Popen(cmd, shell=True, preexec_fn=os.setsid, env=dict(os.environ)) - count = 5 - for _ in range(count): - if not is_port_available(port): - return child_process - time.sleep(1) - raise ValueError("Didn't start!") - -def terminate_testserver(process): - if os.name == 'nt': - process.kill() - else: - os.killpg(os.getpgid(process.pid), signal.SIGTERM) # Send the signal to all the process groups - -@pytest.fixture(autouse=True, scope="package") -def testserver(): - """Start the Autorest testserver.""" - server = start_testserver() - yield - terminate_testserver(server) - -@pytest.fixture -def client(port): - return TestRestClient(port) diff --git a/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/basic.py b/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/basic.py index 933a53de5d14..86117c112810 100644 --- a/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/basic.py +++ b/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/basic.py @@ -8,8 +8,9 @@ from flask import ( Response, Blueprint, - request + request, ) +from .helpers import jsonify, get_dict basic_api = Blueprint('basic_api', __name__) @@ -75,3 +76,19 @@ def headers(): "CamelCase-Header": "camelCase", } ) + +@basic_api.route("/anything", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "TRACE"]) +def anything(): + return jsonify( + get_dict( + "url", + "args", + "headers", + "origin", + "method", + "form", + "data", + "files", + "json", + ) + ) diff --git a/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/helpers.py b/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/helpers.py index 46680f65d3f9..f541d4be27c1 100644 --- a/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/helpers.py +++ b/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/helpers.py @@ -3,10 +3,161 @@ # Licensed under the MIT License. See LICENSE.txt in the project root for # license information. # ------------------------------------------------------------------------- +from flask import ( + request, + jsonify as flask_jsonify, +) +from six.moves.urllib.parse import urlparse, urlunparse +from .structures import CaseInsensitiveDict +import json + +ENV_HEADERS = ( + 'X-Varnish', + 'X-Request-Start', + 'X-Heroku-Queue-Depth', + 'X-Real-Ip', + 'X-Forwarded-Proto', + 'X-Forwarded-Protocol', + 'X-Forwarded-Ssl', + 'X-Heroku-Queue-Wait-Time', + 'X-Forwarded-For', + 'X-Heroku-Dynos-In-Use', + 'X-Forwarded-Protocol', + 'X-Forwarded-Port', + 'X-Request-Id', + 'Via', + 'Total-Route-Time', + 'Connect-Time' +) def assert_with_message(param_name, expected_value, actual_value): assert expected_value == actual_value, "Expected '{}' to be '{}', got '{}'".format( param_name, expected_value, actual_value ) -__all__ = ["assert_with_message"] +def jsonify(*args, **kwargs): + response = flask_jsonify(*args, **kwargs) + if not response.data.endswith(b"\n"): + response.data += b"\n" + return response + +def get_url(request): + """ + Since we might be hosted behind a proxy, we need to check the + X-Forwarded-Proto, X-Forwarded-Protocol, or X-Forwarded-SSL headers + to find out what protocol was used to access us. + """ + protocol = request.headers.get('X-Forwarded-Proto') or request.headers.get('X-Forwarded-Protocol') + if protocol is None and request.headers.get('X-Forwarded-Ssl') == 'on': + protocol = 'https' + if protocol is None: + return request.url + url = list(urlparse(request.url)) + url[0] = protocol + return urlunparse(url) + +def get_files(): + """Returns files dict from request context.""" + + files = dict() + + for k, v in request.files.items(): + content_type = request.files[k].content_type or 'application/octet-stream' + val = json_safe(v.read(), content_type) + if files.get(k): + if not isinstance(files[k], list): + files[k] = [files[k]] + files[k].append(val) + else: + files[k] = val + + return files + +def get_headers(hide_env=True): + """Returns headers dict from request context.""" + + headers = dict(request.headers.items()) + + if hide_env and ('show_env' not in request.args): + for key in ENV_HEADERS: + try: + del headers[key] + except KeyError: + pass + + return CaseInsensitiveDict(headers.items()) + +def semiflatten(multi): + """Convert a MutiDict into a regular dict. If there are more than one value + for a key, the result will have a list of values for the key. Otherwise it + will have the plain value.""" + if multi: + result = multi.to_dict(flat=False) + for k, v in result.items(): + if len(v) == 1: + result[k] = v[0] + return result + else: + return multi + +def json_safe(string, content_type='application/octet-stream'): + """Returns JSON-safe version of `string`. + + If `string` is a Unicode string or a valid UTF-8, it is returned unmodified, + as it can safely be encoded to JSON string. + + If `string` contains raw/binary data, it is Base64-encoded, formatted and + returned according to "data" URL scheme (RFC2397). Since JSON is not + suitable for binary data, some additional encoding was necessary; "data" + URL scheme was chosen for its simplicity. + """ + try: + string = string.decode('utf-8') + json.dumps(string) + return string + except (ValueError, TypeError): + return b''.join([ + b'data:', + content_type.encode('utf-8'), + b';base64,', + base64.b64encode(string) + ]).decode('utf-8') + +def get_dict(*keys, **extras): + """Returns request dict of given keys.""" + + _keys = ('url', 'args', 'form', 'data', 'origin', 'headers', 'files', 'json', 'method') + + assert all(map(_keys.__contains__, keys)) + data = request.data + form = semiflatten(request.form) + + try: + _json = json.loads(data.decode('utf-8')) + except (ValueError, TypeError): + _json = None + + d = dict( + url=get_url(request), + args=semiflatten(request.args), + form=form, + data=json_safe(data), + origin=request.headers.get('X-Forwarded-For', request.remote_addr), + headers=get_headers(), + files=get_files(), + json=_json, + method=request.method, + ) + + out_d = dict() + + for key in keys: + out_d[key] = d.get(key) + + out_d.update(extras) + + return out_d + +__all__ = ["assert_with_message", + "get_dict", + "jsonify"] \ No newline at end of file diff --git a/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/structures.py b/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/structures.py new file mode 100644 index 000000000000..1e443986cdf2 --- /dev/null +++ b/sdk/core/azure-core/tests/testserver_tests/coretestserver/coretestserver/test_routes/structures.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +class CaseInsensitiveDict(dict): + """Case-insensitive Dictionary for headers. + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header. + """ + + def _lower_keys(self): + return [k.lower() for k in self.keys()] + + def __contains__(self, key): + return key.lower() in self._lower_keys() + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + if key in self: + return list(self.items())[self._lower_keys().index(key.lower())][1]