Repository: aio-libs/aiohttp

Issue:
Client DNS start/end events not fired
## Long story short

Unable to track dns timing via TraceConfig using client with TcpConnector, since `None` intead of `traces` arg passed to direct and proxy connections methods

```
    async def _create_connection(self, req, traces=None):
        """Create connection.

        Has same keyword arguments as BaseEventLoop.create_connection.
        """
        if req.proxy:
            _, proto = await self._create_proxy_connection(
                req,
                traces=None
            )
        else:
            _, proto = await self._create_direct_connection(
                req,
                traces=None
            )

        return proto
```
## Expected behaviour

working DNS tracing with TCP

## Actual behaviour

dns events missed

## Your environment
aiohttp: 3.0.9
OS X




Discussion:
That's sad but the fix looks easy.
Would you provide a patch?
yes
shame of me, the integration test that wires all of the tracing does not cover this signal [1] ... if its not a big deal would be nice if we can add these signals to that test. That would help in the future to avoid the same mistake.

[1] https://github.com/aio-libs/aiohttp/blob/master/tests/test_web_functional.py#L1641
Thanks for pointing the test. I actually wrote a different one and seems like in a wrong place. Will do there.
Well this just checks the happy path an upper level, if you have others at function level please commit them as well!

Resolving patch:
diff --git a/aiohttp/connector.py b/aiohttp/connector.py
--- 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


Test patch:
diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py
--- 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):