diff --git a/CHANGES/2841.bugfix b/CHANGES/2841.bugfix new file mode 100644 index 00000000000..aca955ceee8 --- /dev/null +++ b/CHANGES/2841.bugfix @@ -0,0 +1 @@ +Fix firing DNS tracing events. diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 7c122fead8c..f506230ad42 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -728,12 +728,12 @@ async def _create_connection(self, req, traces=None): if req.proxy: _, proto = await self._create_proxy_connection( req, - traces=None + traces=traces ) else: _, proto = await self._create_direct_connection( req, - traces=None + traces=traces ) return proto diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py index d2d6a370f9b..4183fcdea11 100644 --- a/tests/test_web_functional.py +++ b/tests/test_web_functional.py @@ -2,6 +2,7 @@ import io import json import pathlib +import socket import zlib from unittest import mock @@ -1638,10 +1639,14 @@ async def handler(request): assert resp.status == 200 -async def test_request_tracing(aiohttp_client): +async def test_request_tracing(aiohttp_server): on_request_start = mock.Mock(side_effect=asyncio.coroutine(mock.Mock())) on_request_end = mock.Mock(side_effect=asyncio.coroutine(mock.Mock())) + on_dns_resolvehost_start = mock.Mock( + side_effect=asyncio.coroutine(mock.Mock())) + on_dns_resolvehost_end = mock.Mock( + side_effect=asyncio.coroutine(mock.Mock())) on_request_redirect = mock.Mock(side_effect=asyncio.coroutine(mock.Mock())) on_connection_create_start = mock.Mock( side_effect=asyncio.coroutine(mock.Mock())) @@ -1663,20 +1668,50 @@ async def redirected(request): on_connection_create_start) trace_config.on_connection_create_end.append( on_connection_create_end) + trace_config.on_dns_resolvehost_start.append( + on_dns_resolvehost_start) + trace_config.on_dns_resolvehost_end.append( + on_dns_resolvehost_end) app = web.Application() app.router.add_get('/redirector', redirector) app.router.add_get('/redirected', redirected) + server = await aiohttp_server(app) + + class FakeResolver: + _LOCAL_HOST = {0: '127.0.0.1', + socket.AF_INET: '127.0.0.1'} + + def __init__(self, fakes): + """fakes -- dns -> port dict""" + self._fakes = fakes + self._resolver = aiohttp.DefaultResolver() + + async def resolve(self, host, port=0, family=socket.AF_INET): + fake_port = self._fakes.get(host) + if fake_port is not None: + return [{'hostname': host, + 'host': self._LOCAL_HOST[family], 'port': fake_port, + 'family': socket.AF_INET, 'proto': 0, + 'flags': socket.AI_NUMERICHOST}] + else: + return await self._resolver.resolve(host, port, family) - client = await aiohttp_client(app, trace_configs=[trace_config]) + resolver = FakeResolver({'example.com': server.port}) + connector = aiohttp.TCPConnector(resolver=resolver) + client = aiohttp.ClientSession(connector=connector, + trace_configs=[trace_config]) - await client.get('/redirector', data="foo") + await client.get('http://example.com/redirector', data="foo") assert on_request_start.called assert on_request_end.called + assert on_dns_resolvehost_start.called + assert on_dns_resolvehost_end.called assert on_request_redirect.called assert on_connection_create_start.called assert on_connection_create_end.called + await client.close() async def test_return_http_exception_deprecated(aiohttp_client):