Repository: aio-libs/aiohttp

Issue:
Enable dns cache in Connector by default, use aiodns resolver by default if available.
Casual user doesn't tune TCPConnector usually.
Thus settings should provide the best performance by default.

Taking into account that aiodns respects `/etc/hosts` now it's safe drop-in replacement for regular threaded resolver.



Discussion:

Resolving patch:
diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py
--- a/aiohttp/__init__.py
+++ b/aiohttp/__init__.py
@@ -20,6 +20,7 @@
 from ._ws_impl import WSMsgType, WSCloseCode, WSMessage, WebSocketError  # noqa
 from .file_sender import FileSender  # noqa
 from .cookiejar import CookieJar  # noqa
+from .resolver import *  # noqa
 
 
 MsgType = WSMsgType  # backward compatibility
diff --git a/aiohttp/connector.py b/aiohttp/connector.py
--- a/aiohttp/connector.py
+++ b/aiohttp/connector.py
@@ -456,14 +456,11 @@ def __init__(self, *, verify_ssl=True, fingerprint=None,
         elif resolve is not sentinel:
             _use_dns_cache = resolve
         else:
-            _use_dns_cache = False
+            _use_dns_cache = True
 
-        self._resolver = resolver or DefaultResolver(loop=self._loop)
-
-        if _use_dns_cache or resolver:
-            self._use_resolver = True
-        else:
-            self._use_resolver = False
+        if resolver is None:
+            resolver = DefaultResolver(loop=self._loop)
+        self._resolver = resolver
 
         self._use_dns_cache = _use_dns_cache
         self._cached_hosts = {}
@@ -552,12 +549,10 @@ def clear_resolved_hosts(self, host=None, port=None):
 
     @asyncio.coroutine
     def _resolve_host(self, host, port):
-        if not self._use_resolver or is_ip_address(host):
+        if is_ip_address(host):
             return [{'hostname': host, 'host': host, 'port': port,
                      'family': self._family, 'proto': 0, 'flags': 0}]
 
-        assert self._resolver
-
         if self._use_dns_cache:
             key = (host, port)
 
diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py
--- a/aiohttp/resolver.py
+++ b/aiohttp/resolver.py
@@ -3,13 +3,17 @@
 
 from .abc import AbstractResolver
 
+__all__ = ('ThreadedResolver', 'AsyncResolver', 'DefaultResolver')
+
 try:
     import aiodns
+    aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname')
 except ImportError:  # pragma: no cover
     aiodns = None
+    aiodns_default = False
 
 
-class DefaultResolver(AbstractResolver):
+class ThreadedResolver(AbstractResolver):
     """Use Executor for synchronous getaddrinfo() calls, which defaults to
     concurrent.futures.ThreadPoolExecutor.
     """
@@ -91,3 +95,6 @@ def resolve_with_query(self, host, port=0, family=socket.AF_INET):
     @asyncio.coroutine
     def close(self):
         return self._resolver.cancel()
+
+
+DefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver


Test patch:
diff --git a/aiohttp/test_utils.py b/aiohttp/test_utils.py
--- a/aiohttp/test_utils.py
+++ b/aiohttp/test_utils.py
@@ -474,10 +474,12 @@ def make_mocked_request(method, path, headers=None, *,
     return req
 
 
-def make_mocked_coro(return_value):
+def make_mocked_coro(return_value=sentinel, raise_exception=sentinel):
     """Creates a coroutine mock."""
     @asyncio.coroutine
     def mock_coro(*args, **kwargs):
+        if raise_exception is not sentinel:
+            raise raise_exception
         return return_value
 
     return mock.Mock(wraps=mock_coro)
diff --git a/tests/test_connector.py b/tests/test_connector.py
--- a/tests/test_connector.py
+++ b/tests/test_connector.py
@@ -412,8 +412,8 @@ def test_tcp_connector_ctor(loop):
     assert conn.fingerprint is None
 
     with pytest.warns(DeprecationWarning):
-        assert not conn.resolve
-    assert not conn.use_dns_cache
+        assert conn.resolve
+    assert conn.use_dns_cache
 
     assert conn.family == 0
 
@@ -780,6 +780,11 @@ def test_both_use_dns_cache_only(loop):
         assert conn.resolve
 
 
+def test_default_use_dns_cache(loop):
+    conn = aiohttp.TCPConnector(loop=loop)
+    assert conn.use_dns_cache
+
+
 class TestHttpClientConnector(unittest.TestCase):
 
     def setUp(self):
diff --git a/tests/test_proxy.py b/tests/test_proxy.py
--- a/tests/test_proxy.py
+++ b/tests/test_proxy.py
@@ -1,20 +1,12 @@
 import asyncio
 import gc
+import socket
 import unittest
 from unittest import mock
 
 import aiohttp
 from aiohttp.client_reqrep import ClientRequest, ClientResponse
-
-
-def _create_mocked_loop():
-    """
-    Single place where to define the loop to be used as mock for the tests
-    Delete the `create_future()` from the mock, so it defaults to a new Future
-    """
-    loop_mock = unittest.mock.Mock()()
-    del loop_mock.create_future
-    return loop_mock
+from aiohttp.test_utils import make_mocked_coro
 
 
 class TestProxy(unittest.TestCase):
@@ -30,16 +22,7 @@ def tearDown(self):
         self.loop.close()
         gc.collect()
 
-    def _fake_coroutine(self, mock, return_value):
-
-        def coro(*args, **kw):
-            if isinstance(return_value, Exception):
-                raise return_value
-            return return_value
-            yield  # pragma: no cover
-        mock.side_effect = coro
-
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_connect(self, ClientRequestMock):
         req = ClientRequest(
             'GET', 'http://www.python.org',
@@ -49,15 +32,11 @@ def test_connect(self, ClientRequestMock):
         self.assertEqual(req.proxy, 'http://proxy.example.com')
 
         # mock all the things!
-        loop_mock = _create_mocked_loop()
-        connector = aiohttp.TCPConnector(loop=loop_mock)
-        self.assertIs(loop_mock, connector._loop)
-        resolve_host = unittest.mock.Mock()
-        self._fake_coroutine(resolve_host, [unittest.mock.MagicMock()])
-        connector._resolve_host = resolve_host
-
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro([mock.MagicMock()])
+
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
         conn = self.loop.run_until_complete(connector.connect(req))
         self.assertEqual(req.path, 'http://www.python.org/')
         self.assertIs(conn._transport, tr)
@@ -67,7 +46,7 @@ def test_connect(self, ClientRequestMock):
             'GET', 'http://proxy.example.com',
             auth=None,
             headers={'Host': 'www.python.org'},
-            loop=loop_mock)
+            loop=self.loop)
 
     def test_proxy_auth(self):
         with self.assertRaises(ValueError) as ctx:
@@ -75,7 +54,7 @@ def test_proxy_auth(self):
                 'GET', 'http://python.org',
                 proxy='http://proxy.example.com',
                 proxy_auth=('user', 'pass'),
-                loop=unittest.mock.Mock())
+                loop=mock.Mock())
         self.assertEqual(
             ctx.exception.args[0],
             "proxy_auth must be None or BasicAuth() tuple",
@@ -83,8 +62,8 @@ def test_proxy_auth(self):
 
     def test_proxy_connection_error(self):
         connector = aiohttp.TCPConnector(loop=self.loop)
-        connector._resolve_host = resolve_mock = unittest.mock.Mock()
-        self._fake_coroutine(resolve_mock, OSError('dont take it serious'))
+        connector._resolve_host = make_mocked_coro(
+            raise_exception=OSError('dont take it serious'))
 
         req = ClientRequest(
             'GET', 'http://www.python.org',
@@ -97,7 +76,7 @@ def test_proxy_connection_error(self):
         self.assertEqual(req.path, '/')
         self.assertEqual(dict(req.headers), expected_headers)
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_auth(self, ClientRequestMock):
         proxy_req = ClientRequest(
             'GET', 'http://proxy.example.com',
@@ -108,13 +87,11 @@ def test_auth(self, ClientRequestMock):
         self.assertIn('AUTHORIZATION', proxy_req.headers)
         self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers)
 
-        loop_mock = _create_mocked_loop()
-        connector = aiohttp.TCPConnector(loop=loop_mock)
-        connector._resolve_host = resolve_mock = unittest.mock.Mock()
-        self._fake_coroutine(resolve_mock, [unittest.mock.MagicMock()])
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro([mock.MagicMock()])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'http://www.python.org',
@@ -135,7 +112,7 @@ def test_auth(self, ClientRequestMock):
         ClientRequestMock.assert_called_with(
             'GET', 'http://proxy.example.com',
             auth=aiohttp.helpers.BasicAuth('user', 'pass'),
-            loop=unittest.mock.ANY, headers=unittest.mock.ANY)
+            loop=mock.ANY, headers=mock.ANY)
         conn.close()
 
     def test_auth_utf8(self):
@@ -145,7 +122,7 @@ def test_auth_utf8(self):
             loop=self.loop)
         self.assertIn('AUTHORIZATION', proxy_req.headers)
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_auth_from_url(self, ClientRequestMock):
         proxy_req = ClientRequest('GET', 'http://user:pass@proxy.example.com',
                                   loop=self.loop)
@@ -153,13 +130,11 @@ def test_auth_from_url(self, ClientRequestMock):
         self.assertIn('AUTHORIZATION', proxy_req.headers)
         self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers)
 
-        loop_mock = _create_mocked_loop()
-        connector = aiohttp.TCPConnector(loop=loop_mock)
-        connector._resolve_host = resolve_mock = unittest.mock.Mock()
-        self._fake_coroutine(resolve_mock, [unittest.mock.MagicMock()])
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro([mock.MagicMock()])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'http://www.python.org',
@@ -178,20 +153,19 @@ def test_auth_from_url(self, ClientRequestMock):
 
         ClientRequestMock.assert_called_with(
             'GET', 'http://user:pass@proxy.example.com',
-            auth=None, loop=unittest.mock.ANY, headers=unittest.mock.ANY)
+            auth=None, loop=mock.ANY, headers=mock.ANY)
         conn.close()
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_auth__not_modifying_request(self, ClientRequestMock):
         proxy_req = ClientRequest('GET', 'http://user:pass@proxy.example.com',
                                   loop=self.loop)
         ClientRequestMock.return_value = proxy_req
         proxy_req_headers = dict(proxy_req.headers)
 
-        loop_mock = _create_mocked_loop()
-        connector = aiohttp.TCPConnector(loop=loop_mock)
-        connector._resolve_host = resolve_mock = unittest.mock.Mock()
-        self._fake_coroutine(resolve_mock, OSError('nothing personal'))
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            raise_exception=OSError('nothing personal'))
 
         req = ClientRequest(
             'GET', 'http://www.python.org',
@@ -205,24 +179,25 @@ def test_auth__not_modifying_request(self, ClientRequestMock):
         self.assertEqual(req.path, '/')
         self.assertEqual(proxy_req.headers, proxy_req_headers)
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_https_connect(self, ClientRequestMock):
-        loop_mock = _create_mocked_loop()
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
-                                  loop=loop_mock)
+                                  loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
         proxy_resp = ClientResponse('get', 'http://proxy.example.com')
-        proxy_resp._loop = loop_mock
-        proxy_req.send = send_mock = unittest.mock.Mock()
+        proxy_resp._loop = self.loop
+        proxy_req.send = send_mock = mock.Mock()
         send_mock.return_value = proxy_resp
-        proxy_resp.start = start_mock = unittest.mock.Mock()
-        self._fake_coroutine(start_mock, unittest.mock.Mock(status=200))
+        proxy_resp.start = make_mocked_coro(mock.Mock(status=200))
 
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'https://www.python.org',
@@ -241,25 +216,26 @@ def test_https_connect(self, ClientRequestMock):
         proxy_resp.close()
         self.loop.run_until_complete(req.close())
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_https_connect_runtime_error(self, ClientRequestMock):
-        loop_mock = _create_mocked_loop()
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
-                                  loop=loop_mock)
+                                  loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
         proxy_resp = ClientResponse('get', 'http://proxy.example.com')
-        proxy_resp._loop = loop_mock
-        proxy_req.send = send_mock = unittest.mock.Mock()
+        proxy_resp._loop = self.loop
+        proxy_req.send = send_mock = mock.Mock()
         send_mock.return_value = proxy_resp
-        proxy_resp.start = start_mock = unittest.mock.Mock()
-        self._fake_coroutine(start_mock, unittest.mock.Mock(status=200))
+        proxy_resp.start = make_mocked_coro(mock.Mock(status=200))
 
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
+        tr, proto = mock.Mock(), mock.Mock()
         tr.get_extra_info.return_value = None
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'https://www.python.org',
@@ -274,26 +250,28 @@ def test_https_connect_runtime_error(self, ClientRequestMock):
         proxy_resp.close()
         self.loop.run_until_complete(req.close())
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_https_connect_http_proxy_error(self, ClientRequestMock):
-        loop_mock = _create_mocked_loop()
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
-                                  loop=loop_mock)
+                                  loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
         proxy_resp = ClientResponse('get', 'http://proxy.example.com')
-        proxy_resp._loop = loop_mock
-        proxy_req.send = send_mock = unittest.mock.Mock()
+        proxy_resp._loop = self.loop
+        proxy_req.send = send_mock = mock.Mock()
         send_mock.return_value = proxy_resp
-        proxy_resp.start = start_mock = unittest.mock.Mock()
-        self._fake_coroutine(
-            start_mock, unittest.mock.Mock(status=400, reason='bad request'))
+        proxy_resp.start = make_mocked_coro(
+            mock.Mock(status=400, reason='bad request'))
 
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
+        tr, proto = mock.Mock(), mock.Mock()
         tr.get_extra_info.return_value = None
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'https://www.python.org',
@@ -308,25 +286,27 @@ def test_https_connect_http_proxy_error(self, ClientRequestMock):
         proxy_resp.close()
         self.loop.run_until_complete(req.close())
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_https_connect_resp_start_error(self, ClientRequestMock):
-        loop_mock = _create_mocked_loop()
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
-                                  loop=loop_mock)
+                                  loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
         proxy_resp = ClientResponse('get', 'http://proxy.example.com')
-        proxy_resp._loop = loop_mock
-        proxy_req.send = send_mock = unittest.mock.Mock()
+        proxy_resp._loop = self.loop
+        proxy_req.send = send_mock = mock.Mock()
         send_mock.return_value = proxy_resp
-        proxy_resp.start = start_mock = unittest.mock.Mock()
-        self._fake_coroutine(start_mock, OSError("error message"))
+        proxy_resp.start = make_mocked_coro(
+            raise_exception=OSError("error message"))
 
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
+        tr, proto = mock.Mock(), mock.Mock()
         tr.get_extra_info.return_value = None
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'https://www.python.org',
@@ -336,18 +316,20 @@ def test_https_connect_resp_start_error(self, ClientRequestMock):
         with self.assertRaisesRegex(OSError, "error message"):
             self.loop.run_until_complete(connector._create_connection(req))
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_request_port(self, ClientRequestMock):
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
                                   loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
-        loop_mock = _create_mocked_loop()
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
+        tr, proto = mock.Mock(), mock.Mock()
         tr.get_extra_info.return_value = None
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'http://localhost:1234/path',
@@ -372,24 +354,25 @@ def test_proxy_auth_property_default(self):
             loop=self.loop)
         self.assertIsNone(req.proxy_auth)
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_https_connect_pass_ssl_context(self, ClientRequestMock):
-        loop_mock = _create_mocked_loop()
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
-                                  loop=loop_mock)
+                                  loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
         proxy_resp = ClientResponse('get', 'http://proxy.example.com')
-        proxy_resp._loop = loop_mock
-        proxy_req.send = send_mock = unittest.mock.Mock()
+        proxy_resp._loop = self.loop
+        proxy_req.send = send_mock = mock.Mock()
         send_mock.return_value = proxy_resp
-        proxy_resp.start = start_mock = unittest.mock.Mock()
-        self._fake_coroutine(start_mock, unittest.mock.Mock(status=200))
+        proxy_resp.start = make_mocked_coro(mock.Mock(status=200))
 
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         req = ClientRequest(
             'GET', 'https://www.python.org',
@@ -398,7 +381,7 @@ def test_https_connect_pass_ssl_context(self, ClientRequestMock):
         )
         self.loop.run_until_complete(connector._create_connection(req))
 
-        loop_mock.create_connection.assert_called_with(
+        self.loop.create_connection.assert_called_with(
             mock.ANY,
             ssl=connector.ssl_context,
             sock=mock.ANY,
@@ -414,26 +397,27 @@ def test_https_connect_pass_ssl_context(self, ClientRequestMock):
         proxy_resp.close()
         self.loop.run_until_complete(req.close())
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_https_auth(self, ClientRequestMock):
-        loop_mock = _create_mocked_loop()
         proxy_req = ClientRequest('GET', 'http://proxy.example.com',
                                   auth=aiohttp.helpers.BasicAuth('user',
                                                                  'pass'),
-                                  loop=loop_mock)
+                                  loop=self.loop)
         ClientRequestMock.return_value = proxy_req
 
         proxy_resp = ClientResponse('get', 'http://proxy.example.com')
-        proxy_resp._loop = loop_mock
-        proxy_req.send = send_mock = unittest.mock.Mock()
+        proxy_resp._loop = self.loop
+        proxy_req.send = send_mock = mock.Mock()
         send_mock.return_value = proxy_resp
-        proxy_resp.start = start_mock = unittest.mock.Mock()
-        self._fake_coroutine(start_mock, unittest.mock.Mock(status=200))
+        proxy_resp.start = make_mocked_coro(mock.Mock(status=200))
 
-        connector = aiohttp.TCPConnector(loop=loop_mock)
+        connector = aiohttp.TCPConnector(loop=self.loop)
+        connector._resolve_host = make_mocked_coro(
+            [{'hostname': 'hostname', 'host': '127.0.0.1', 'port': 80,
+              'family': socket.AF_INET, 'proto': 0, 'flags': 0}])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
 
         self.assertIn('AUTHORIZATION', proxy_req.headers)
         self.assertNotIn('PROXY-AUTHORIZATION', proxy_req.headers)
@@ -453,6 +437,8 @@ def test_https_auth(self, ClientRequestMock):
         self.assertNotIn('AUTHORIZATION', proxy_req.headers)
         self.assertIn('PROXY-AUTHORIZATION', proxy_req.headers)
 
+        connector._resolve_host.assert_called_with('proxy.example.com', 80)
+
         self.loop.run_until_complete(proxy_req.close())
         proxy_resp.close()
         self.loop.run_until_complete(req.close())
@@ -475,15 +461,6 @@ def tearDown(self):
         self.loop.close()
         gc.collect()
 
-    def _fake_coroutine(self, mock, return_value):
-
-        def coro(*args, **kw):
-            if isinstance(return_value, Exception):
-                raise return_value
-            return return_value
-            yield  # pragma: no cover
-        mock.side_effect = coro
-
     def test_ctor(self):
         connector = aiohttp.ProxyConnector(
             'http://localhost:8118',
@@ -498,22 +475,19 @@ def test_ctor(self):
         )
         self.assertTrue(connector.force_close)
 
-    @unittest.mock.patch('aiohttp.connector.ClientRequest')
+    @mock.patch('aiohttp.connector.ClientRequest')
     def test_connect(self, ClientRequestMock):
         req = ClientRequest('GET', 'http://www.python.org', loop=self.loop)
         self.assertEqual(req.path, '/')
 
-        loop_mock = _create_mocked_loop()
         connector = aiohttp.ProxyConnector('http://proxy.example.com',
-                                           loop=loop_mock)
-        self.assertIs(loop_mock, connector._loop)
+                                           loop=self.loop)
+        self.assertIs(self.loop, connector._loop)
 
-        resolve_host = unittest.mock.Mock()
-        self._fake_coroutine(resolve_host, [unittest.mock.MagicMock()])
-        connector._resolve_host = resolve_host
+        connector._resolve_host = make_mocked_coro([mock.MagicMock()])
 
-        tr, proto = unittest.mock.Mock(), unittest.mock.Mock()
-        self._fake_coroutine(loop_mock.create_connection, (tr, proto))
+        tr, proto = mock.Mock(), mock.Mock()
+        self.loop.create_connection = make_mocked_coro((tr, proto))
         conn = self.loop.run_until_complete(connector.connect(req))
         self.assertEqual(req.path, 'http://www.python.org/')
         self.assertIs(conn._transport, tr)
@@ -526,5 +500,5 @@ def test_connect(self, ClientRequestMock):
             'GET', 'http://proxy.example.com',
             auth=None,
             headers={'Host': 'www.python.org'},
-            loop=loop_mock)
+            loop=self.loop)
         conn.close()
diff --git a/tests/test_resolver.py b/tests/test_resolver.py
--- a/tests/test_resolver.py
+++ b/tests/test_resolver.py
@@ -5,7 +5,7 @@
 
 import pytest
 
-from aiohttp.resolver import AsyncResolver, DefaultResolver
+from aiohttp.resolver import AsyncResolver, DefaultResolver, ThreadedResolver
 
 try:
     import aiodns
@@ -118,35 +118,35 @@ def test_async_resolver_query_negative_lookup(loop):
 
 
 @asyncio.coroutine
-def test_default_resolver_positive_lookup(loop):
+def test_threaded_resolver_positive_lookup(loop):
     loop.getaddrinfo = fake_addrinfo(["127.0.0.1"])
-    resolver = DefaultResolver(loop=loop)
+    resolver = ThreadedResolver(loop=loop)
     real = yield from resolver.resolve('www.python.org')
     ipaddress.ip_address(real[0]['host'])
 
 
 @asyncio.coroutine
-def test_default_resolver_multiple_replies(loop):
+def test_threaded_resolver_multiple_replies(loop):
     ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4']
     loop.getaddrinfo = fake_addrinfo(ips)
-    resolver = DefaultResolver(loop=loop)
+    resolver = ThreadedResolver(loop=loop)
     real = yield from resolver.resolve('www.google.com')
     ips = [ipaddress.ip_address(x['host']) for x in real]
     assert len(ips) > 3, "Expecting multiple addresses"
 
 
 @asyncio.coroutine
-def test_default_negative_lookup(loop):
+def test_threaded_negative_lookup(loop):
     ips = []
     loop.getaddrinfo = fake_addrinfo(ips)
-    resolver = DefaultResolver(loop=loop)
+    resolver = ThreadedResolver(loop=loop)
     with pytest.raises(socket.gaierror):
         yield from resolver.resolve('doesnotexist.bla')
 
 
 @asyncio.coroutine
-def test_close_for_default_resolver(loop):
-    resolver = DefaultResolver(loop=loop)
+def test_close_for_threaded_resolver(loop):
+    resolver = ThreadedResolver(loop=loop)
     yield from resolver.close()
 
 
@@ -157,9 +157,9 @@ def test_close_for_async_resolver(loop):
     yield from resolver.close()
 
 
-def test_default_loop_for_default_resolver(loop):
+def test_default_loop_for_threaded_resolver(loop):
     asyncio.set_event_loop(loop)
-    resolver = DefaultResolver()
+    resolver = ThreadedResolver()
     assert resolver._loop is loop
 
 
@@ -200,3 +200,10 @@ def test_async_resolver_aiodns_not_present(loop, monkeypatch):
     monkeypatch.setattr("aiohttp.resolver.aiodns", None)
     with pytest.raises(RuntimeError):
         AsyncResolver(loop=loop)
+
+
+def test_default_resolver():
+    if gethostbyname:
+        assert DefaultResolver is AsyncResolver
+    else:
+        assert DefaultResolver is ThreadedResolver