-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added first test need to clean it up tho
- Loading branch information
1 parent
74ede1a
commit deb6f1e
Showing
8 changed files
with
406 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
[mypy] | ||
|
||
[mypy-aiohttp.*,nox.*,bs4.*] | ||
[mypy-aiohttp.*,nox.*,bs4.*,pytest.*] | ||
ignore_missing_imports = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import aiohttp | ||
import aiohttp.test_utils | ||
import aiohttp.web | ||
import asyncio | ||
import collections | ||
import pytest | ||
import socket | ||
|
||
# ---------------------------------------------------------------------------- | ||
|
||
_RedirectContext = collections.namedtuple("RedirectContext", "add_server session") | ||
|
||
|
||
@pytest.fixture | ||
async def http_redirect(ssl_certificate): | ||
""" An HTTP ClientSession fixture that redirects requests to local test servers """ | ||
resolver = FakeResolver() | ||
connector = aiohttp.TCPConnector( | ||
resolver=resolver, | ||
ssl=ssl_certificate.client_context(), | ||
use_dns_cache=False, | ||
) | ||
async with aiohttp.ClientSession(connector=connector) as session: | ||
yield _RedirectContext(add_server=resolver.add, session=session) | ||
|
||
|
||
class FakeResolver: | ||
"""aiohttp resolver that hijacks a set of uris | ||
:param servers: a mapping of remote host:port to redirect to local servers. | ||
:type servers: dict(tuple(str, int), int) | ||
""" | ||
|
||
__slots__ = ("_servers",) | ||
|
||
def __init__(self, servers=None): | ||
self._servers = servers or {} | ||
|
||
def add(self, host, port, target): | ||
""" Add an entry to the resolver """ | ||
self._servers[host, port] = target | ||
|
||
async def resolve(self, host, port=0, family=socket.AF_INET): | ||
""" Resolve a host:port pair into a connectable address """ | ||
try: | ||
fake_port = self._servers[host, port] | ||
except KeyError: | ||
raise OSError("Fake DNS lookup failed: no fake server known for %s" % host) | ||
return [ | ||
{ | ||
"hostname": host, | ||
"host": "127.0.0.1", | ||
"port": fake_port, | ||
"family": socket.AF_INET, | ||
"proto": 0, | ||
"flags": socket.AI_NUMERICHOST, | ||
} | ||
] | ||
|
||
|
||
# ---------------------------------------------------------------------------- | ||
|
||
|
||
class CaseControlledTestServer(aiohttp.test_utils.RawTestServer): | ||
""" Test server that relies on test case to supply responses and control timing """ | ||
|
||
def __init__(self, *, ssl=None, **kwargs): | ||
super().__init__(self._handle_request, **kwargs) | ||
self._ssl = ssl | ||
self._requests = asyncio.Queue() | ||
self._responses = {} | ||
|
||
async def start_server(self, **kwargs): | ||
kwargs.setdefault("ssl", self._ssl) | ||
await super().start_server(**kwargs) | ||
|
||
async def close(self): | ||
for future in self._responses.values(): | ||
future.cancel() | ||
await super().close() | ||
|
||
async def _handle_request(self, request): | ||
self._responses[id(request)] = response = asyncio.Future() | ||
self._requests.put_nowait(request) | ||
try: | ||
return await response | ||
finally: | ||
del self._responses[id(request)] | ||
|
||
@property | ||
def awaiting_request_count(self): | ||
return self._requests.qsize() | ||
|
||
async def receive_request(self, *, timeout=None): | ||
"""Wait until the test server receives a request | ||
:param float timeout: Bail out after that many seconds. | ||
:return: received request, not yet serviced. | ||
:rtype: aiohttp.web.BaseRequest | ||
:see: :meth:`send_response` | ||
""" | ||
return await asyncio.wait_for(self._requests.get(), timeout=timeout) | ||
|
||
def send_response(self, request, *args, **kwargs): | ||
"""Reply to a received request. | ||
:param request: the request to respond to. | ||
:param args: forwarded to :class:`aiohttp.web.Response`. | ||
:param kwargs: forwarded to :class:`aiohttp.web.Response`. | ||
""" | ||
self._responses[id(request)].set_result(aiohttp.web.Response(*args, **kwargs)) |
Oops, something went wrong.