From a2ecb2a7b45061ed224f05d868b0cffc3c36dee3 Mon Sep 17 00:00:00 2001 From: alfred82santa Date: Tue, 3 Apr 2018 17:11:42 +0200 Subject: [PATCH] Upgrade to aihttp 3.1.1 --- requirements.txt | 2 +- service_client/__init__.py | 8 +++-- service_client/mocks.py | 11 ++++-- service_client/plugins.py | 2 +- setup.py | 2 +- tests/__init__.py | 13 ++++++++ tests/tests_mocks.py | 2 +- tests/tests_plugins.py | 63 ++++++++++++++++++----------------- tests/tests_service_client.py | 24 ++++++++----- 9 files changed, 78 insertions(+), 49 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2f630ed..1f7efc2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ dirty-loader >= 0.2.2 git+https://github.com/alfred82santa/configure.git -aiohttp >= 2.0.0 \ No newline at end of file +aiohttp >= 3.1.1 diff --git a/service_client/__init__.py b/service_client/__init__.py index db7083f..5e67af0 100644 --- a/service_client/__init__.py +++ b/service_client/__init__.py @@ -1,5 +1,5 @@ import logging -from asyncio import get_event_loop +from asyncio import get_event_loop, ensure_future from asyncio.tasks import Task from urllib.parse import urlparse, urlunsplit @@ -10,7 +10,7 @@ from .utils import ObjectWrapper -__version__ = '0.6.1' +__version__ = '0.7.0' class ServiceClient: @@ -224,7 +224,9 @@ def close(self): Close service client and its plugins. """ self._execute_plugin_hooks_sync(hook='close') - self.session.close() + + if not self.session.closed: + ensure_future(self.session.close(), loop=self.loop) def __del__(self): # pragma: no cover self.close() diff --git a/service_client/mocks.py b/service_client/mocks.py index 416ea4c..6cb2ac9 100644 --- a/service_client/mocks.py +++ b/service_client/mocks.py @@ -1,5 +1,6 @@ from asyncio import get_event_loop +from aiohttp import RequestInfo from aiohttp.client_reqrep import ClientResponse from dirty_loader import LoaderNamespaceReversedCached from functools import wraps @@ -203,8 +204,12 @@ async def __call__(self, *args, **kwargs): self.url = url self.args = args self.kwargs = kwargs - self.response = ClientResponse(method, URL(url)) - self.response._post_init(self.loop) + self.response = ClientResponse(method, URL(url), + writer=None, continue100=False, timer=None, + request_info=RequestInfo(URL(url), method, kwargs.get('headers', [])), + auto_decompress=False, + traces=[], loop=self.loop, session=self.session) + self.response.status = self.mock_desc.get('status', 200) self.response.headers = CIMultiDict(self.mock_desc.get('headers', {})) @@ -216,7 +221,7 @@ async def __call__(self, *args, **kwargs): class BaseFileMock(BaseMock): async def prepare_response(self): filename = self.mock_desc['file'] - self.response._content = self.load_file(filename) + self.response._body = self.load_file(filename) class RawFileMock(BaseFileMock): diff --git a/service_client/plugins.py b/service_client/plugins.py index 99d95ba..e3e85c9 100644 --- a/service_client/plugins.py +++ b/service_client/plugins.py @@ -4,7 +4,7 @@ from urllib.parse import quote_plus import weakref -from aiohttp.helpers import Timeout as TimeoutContext +from async_timeout import timeout as TimeoutContext from functools import wraps from multidict import CIMultiDict diff --git a/setup.py b/setup.py index 6602416..b25f0bf 100644 --- a/setup.py +++ b/setup.py @@ -46,7 +46,7 @@ 'Development Status :: 4 - Beta'], packages=['service_client'], include_package_data=False, - install_requires=['dirty-loader>=0.2.2', 'aiohttp>=2.0.0'], + install_requires=['dirty-loader>=0.2.2', 'aiohttp>=3.1.1'], description="Service Client Framework powered by Python asyncio.", long_description=open(os.path.join(os.path.dirname(__file__), 'README.rst')).read(), test_suite="nose.collector", diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..6947fd9 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,13 @@ +from asyncio import get_event_loop + +from aiohttp import ClientResponse, RequestInfo +from yarl import URL + + +async def create_fake_response(method, url, *, session, headers=None, loop=None): + return ClientResponse(method, URL(url), + writer=None, continue100=False, timer=None, + request_info=RequestInfo(URL(url), method, + headers or []), + auto_decompress=False, + traces=[], loop=loop or get_event_loop(), session=session) diff --git a/tests/tests_mocks.py b/tests/tests_mocks.py index cffa26c..f4b66d0 100644 --- a/tests/tests_mocks.py +++ b/tests/tests_mocks.py @@ -23,7 +23,7 @@ async def __call__(self, *args, **kwargs): class TestMocker(TestCase): - def setUp(self): + async def setUp(self): self.plugin = Mock(namespaces={'mocks': 'tests.mocks'}) self.session = ObjectWrapper(ClientSession()) self.service_desc = {'mock': {'mock_type': 'mocks:FakeMock', diff --git a/tests/tests_plugins.py b/tests/tests_plugins.py index 90168b2..56fd567 100644 --- a/tests/tests_plugins.py +++ b/tests/tests_plugins.py @@ -6,24 +6,24 @@ import asyncio import logging from asyncio import TimeoutError -from asyncio.tasks import sleep, shield +from asyncio.tasks import shield, sleep from datetime import datetime, timedelta from aiohttp.client import ClientSession -from aiohttp.client_reqrep import ClientResponse from asynctest.case import TestCase from multidict import CIMultiDict from yarl import URL from service_client import ConnectionClosedError -from service_client.plugins import PathTokens, Timeout, Headers, QueryParams, Elapsed, InnerLogger, OuterLogger, \ - TrackingToken, Pool, RateLimit, TooMuchTimePendingError, TooManyRequestsPendingError +from service_client.plugins import Elapsed, Headers, InnerLogger, OuterLogger, PathTokens, Pool, \ + QueryParams, RateLimit, Timeout, TooManyRequestsPendingError, TooMuchTimePendingError, TrackingToken from service_client.utils import ObjectWrapper +from tests import create_fake_response class PathTests(TestCase): - def setUp(self): + async def setUp(self): self.plugin = PathTokens() self.session = ClientSession() self.endpoint_desc = {'path': '/test1/path/noway', @@ -103,7 +103,7 @@ async def test_no_param(self): class TimeoutTests(TestCase): - def setUp(self): + async def setUp(self): class SessionMock: async def request(self, *args, **kwargs): await sleep(0.5) @@ -159,7 +159,7 @@ async def test_no_timeout(self): class TimeoutWithResponseTests(TestCase): - def setUp(self): + async def setUp(self): class SessionMock: async def request(self, *args, **kwargs): await sleep(0.5) @@ -184,7 +184,7 @@ async def test_no_timeout(self): class HeadersTests(TestCase): - def setUp(self): + async def setUp(self): self.plugin = Headers(default_headers={'x-foo-bar': 'test headers'}) self.session = ClientSession() self.endpoint_desc = {'path': '/test1/path/noway', @@ -242,7 +242,7 @@ async def test_add_from_request(self): class QueryParamsTest(TestCase): - def setUp(self): + async def setUp(self): self.plugin = QueryParams() self.session = ClientSession() self.endpoint_desc = {'path': '/test1/path/noway', @@ -275,7 +275,7 @@ async def test_use_request(self): class QueryParamsDefaultTest(TestCase): - def setUp(self): + async def setUp(self): self.plugin = QueryParams(default_query_params={'default_param1': 'value1', 'default_param2': 'value2'}) self.session = ClientSession() @@ -383,7 +383,7 @@ async def read(self): class ElapsedTest(TestCase): spend_time = 0.1 - def setUp(self): + async def setUp(self): this = self class SessionMock: @@ -531,14 +531,13 @@ async def test_no_parse_elapsed_request_params(self): class TrackingTokenTest(TestCase): - def setUp(self): + async def setUp(self): this = self class SessionMock: async def request(self, *args, **kwargs): - response = ObjectWrapper(ClientResponse('get', URL('http://test.test'))) - response._post_init(this.loop) - return response + return ObjectWrapper(await create_fake_response('get', URL('http://test.test'), + session=self, loop=this.loop)) self.plugin = TrackingToken(prefix='test-') self.session = ObjectWrapper(SessionMock()) @@ -581,14 +580,15 @@ async def test_set_tracking_on_response(self): class InnerLogTest(TestCase): - def setUp(self): + async def setUp(self): this = self class SessionMock: async def request(self, *args, **kwargs): - response = ObjectWrapper(ClientResponse('get', URL('http://test.test'))) - response._post_init(this.loop) - response._content = b'ssssssss' + response = ObjectWrapper(await create_fake_response('get', URL('http://test.test'), + session=self, loop=this.loop)) + + response._body = b'ssssssss' response.status = 200 response.elapsed = timedelta(seconds=100) response.headers = CIMultiDict({"content-type": "application/json"}) @@ -785,14 +785,15 @@ async def test_on_parse_exception(self): class OuterLogTest(TestCase): - def setUp(self): + async def setUp(self): this = self class SessionMock: async def request(self, *args, **kwargs): - response = ObjectWrapper(ClientResponse('get', URL('http://test.test'))) - response._post_init(this.loop) - response._content = b'ssssssss' + response = ObjectWrapper(await create_fake_response('get', URL('http://test.test'), + session=self, loop=this.loop)) + + response._body = b'ssssssss' response.status = 200 response.elapsed = timedelta(seconds=100) response.headers = CIMultiDict({"content-type": "application/json"}) @@ -945,14 +946,14 @@ async def test_on_parse_exception(self): class PoolTest(TestCase): - def setUp(self): + async def setUp(self): this = self class SessionMock: async def request(self, *args, **kwargs): - response = ObjectWrapper(ClientResponse('get', URL('http://test.test'))) - response._post_init(this.loop) - response._content = b'ssssssss' + response = ObjectWrapper(await create_fake_response('get', URL('http://test.test'), + session=self, loop=this.loop)) + response._body = b'ssssssss' response.status = 200 response.elapsed = timedelta(seconds=100) response.headers = CIMultiDict({"content-type": "application/json"}) @@ -1067,14 +1068,14 @@ async def test_regular_work(self): class RateLimitTest(TestCase): - def setUp(self): + async def setUp(self): this = self class SessionMock: async def request(self, *args, **kwargs): - response = ObjectWrapper(ClientResponse('get', URL('http://test.test'))) - response._post_init(this.loop) - response._content = b'ssssssss' + response = ObjectWrapper(await create_fake_response('get', URL('http://test.test'), + session=self, loop=this.loop)) + response._body = b'ssssssss' response.status = 200 response.elapsed = timedelta(seconds=100) response.headers = CIMultiDict({"content-type": "application/json"}) diff --git a/tests/tests_service_client.py b/tests/tests_service_client.py index 7c62cfb..e6cdcc5 100644 --- a/tests/tests_service_client.py +++ b/tests/tests_service_client.py @@ -1,12 +1,13 @@ from asyncio.tasks import Task -from aiohttp.client_reqrep import ClientResponse +from aiohttp import RequestInfo from asynctest.case import TestCase from asynctest.mock import patch from yarl import URL from service_client import ServiceClient from service_client.utils import ObjectWrapper +from tests import create_fake_response class FakePlugin: @@ -94,19 +95,23 @@ def setUp(self, mock_session): plugins=[self.plugin], config=self.config, base_path='http://foo.com/sdsd') - def tearDown(self): - pass + async def tearDown(self): + self.service_client.close() def _mock_session(self): async def request(*args, **kwargs): self.request = {'args': args, 'kwargs': kwargs} - self.response = ClientResponse('get', URL('http://test.test')) - self.response._post_init(self.loop) - self.response._content = b'bbbb' + self.response = await create_fake_response('get', 'http://test.test', session=self.mock_session) + self.response._body = b'bbbb' return self.response + async def close(): + pass + self.mock_session.request.side_effect = request + self.mock_session.close.side_effect = close self.mock_session.return_value = self.mock_session + self.mock_session.closed = True async def test_workflow_get(self): response = await self.service_client.call('testService1') @@ -605,6 +610,9 @@ async def test_create_response(self): task.session = {} task.endpoint_desc = {} task.request_params = {} - response = self.service_client.create_response(method='get', url=URL("http://test.com")) - response._post_init(self.loop) + response = self.service_client.create_response(method='get', url=URL("http://test.com"), + writer=None, continue100=False, timer=None, + request_info=RequestInfo(URL("http://test.com"), 'get', []), + auto_decompress=False, + traces=[], loop=self.loop, session=self.service_client.session) self.assertIsInstance(response, ObjectWrapper)