From 8905a468148c61fb4daf693c5fe986692de15b13 Mon Sep 17 00:00:00 2001 From: Alfred Santacatalina Gea Date: Wed, 3 Mar 2021 22:08:45 +0100 Subject: [PATCH] New version compatible with Py3.9 (#19) * New version compatible with Py3.9 --- .env => .pyvenv | 0 .travis.yml | 4 +- README.rst | 8 ++ requirements-test.txt | 1 + requirements.txt | 4 +- service_client/__init__.py | 14 ++- service_client/formatters.py | 5 +- service_client/mocks.py | 36 ++++-- service_client/plugins.py | 38 +++---- service_client/spec_loaders.py | 6 +- setup.py | 2 +- tests/__init__.py | 28 ++++- tests/tests_formatters.py | 4 +- tests/tests_mocks.py | 3 +- tests/tests_plugins.py | 201 +++++++++++++++++---------------- tests/tests_service_client.py | 14 ++- 16 files changed, 219 insertions(+), 149 deletions(-) rename .env => .pyvenv (100%) diff --git a/.env b/.pyvenv similarity index 100% rename from .env rename to .pyvenv diff --git a/.travis.yml b/.travis.yml index 970aca3..75e7cdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ language: python python: - - "3.5" - "3.6" + - "3.7" + - "3.8" + - "3.9" # command to install dependencies install: - make requirements-test diff --git a/README.rst b/README.rst index 39359d5..1d75003 100644 --- a/README.rst +++ b/README.rst @@ -126,6 +126,14 @@ In order to send a payload you must use ``payload`` keyword on call: Changelog ========= + +v0.7.1 +------ + +- Python 3.9 compatible. +- Update aiohttp. + + v0.6.1 ------ diff --git a/requirements-test.txt b/requirements-test.txt index 724e156..ec4c920 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -3,3 +3,4 @@ flake8 coverage nose asynctest +autopep8 diff --git a/requirements.txt b/requirements.txt index 1f7efc2..193fa17 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ dirty-loader >= 0.2.2 -git+https://github.com/alfred82santa/configure.git -aiohttp >= 3.1.1 +configure-fork +aiohttp >= 3.7.4 diff --git a/service_client/__init__.py b/service_client/__init__.py index 5e67af0..b192636 100644 --- a/service_client/__init__.py +++ b/service_client/__init__.py @@ -1,8 +1,12 @@ import logging -from asyncio import get_event_loop, ensure_future -from asyncio.tasks import Task +from asyncio import Task, ensure_future, get_event_loop from urllib.parse import urlparse, urlunsplit +try: + current_task = Task.current_task +except AttributeError: # pragma: no cover + from asyncio import current_task + from aiohttp.client import ClientSession from aiohttp.client_reqrep import ClientResponse from aiohttp.connector import TCPConnector @@ -10,7 +14,7 @@ from .utils import ObjectWrapper -__version__ = '0.7.0' +__version__ = '0.7.1' class ServiceClient: @@ -36,7 +40,7 @@ def __init__(self, name='GenericService', spec=None, plugins=None, config=None, def create_response(self, *args, **kwargs): response = ObjectWrapper(ClientResponse(*args, **kwargs)) - task = Task.current_task(loop=self.loop) + task = current_task(loop=self.loop) self._execute_plugin_hooks_sync('prepare_response', endpoint_desc=task.endpoint_desc, session=task.session, @@ -78,7 +82,7 @@ async def call(self, endpoint, payload=None, **kwargs): request_params=request_params) await self.before_request(endpoint_desc, session, request_params) - task = Task.current_task(loop=self.loop) + task = current_task(loop=self.loop) task.session = session task.endpoint_desc = endpoint_desc task.request_params = request_params diff --git a/service_client/formatters.py b/service_client/formatters.py index 89f2a93..8481219 100644 --- a/service_client/formatters.py +++ b/service_client/formatters.py @@ -1,6 +1,6 @@ -from urllib.parse import urlencode from http.server import BaseHTTPRequestHandler from logging import Formatter, PercentStyle, StrFormatStyle, StringTemplateStyle +from urllib.parse import urlencode _STYLES = { '%': PercentStyle, @@ -70,7 +70,8 @@ def formatMessage(self, record): pass try: - record.exception_repr = repr(record.exception) + record.exception_repr = "{type}('{message}')".format(type=type(record.exception).__name__, + message=str(record.exception)) except AttributeError: pass diff --git a/service_client/mocks.py b/service_client/mocks.py index 6cb2ac9..c1f01b3 100644 --- a/service_client/mocks.py +++ b/service_client/mocks.py @@ -1,10 +1,12 @@ from asyncio import get_event_loop +from asyncio.futures import Future +from functools import wraps from aiohttp import RequestInfo from aiohttp.client_reqrep import ClientResponse +from aiohttp.helpers import TimerContext from dirty_loader import LoaderNamespaceReversedCached -from functools import wraps -from multidict import CIMultiDict +from multidict import CIMultiDict, CIMultiDictProxy from yarl import URL from .plugins import BasePlugin @@ -189,6 +191,11 @@ def __init__(self, endpoint_desc, session, request_params, self.loop = loop or get_event_loop() async def __call__(self, *args, **kwargs): + try: + from asyncio import create_task + except ImportError: # pragma: no cover + create_task = self.loop.create_task + args = list(args) try: method = kwargs['method'] @@ -204,14 +211,27 @@ async def __call__(self, *args, **kwargs): self.url = url self.args = args self.kwargs = kwargs - 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) + + async def writer(*args, **kwargs): + return None + + continue100 = Future() + continue100.set_result(False) + + self.response = ClientResponse(method, + URL(url), + writer=create_task(writer()), + continue100=continue100, + timer=TimerContext(loop=self.loop), + request_info=RequestInfo(URL(url), + method, + kwargs.get('headers', [])), + 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', {})) + self.response._headers = CIMultiDictProxy(CIMultiDict(self.mock_desc.get('headers', {}))) await self.prepare_response() diff --git a/service_client/plugins.py b/service_client/plugins.py index e3e85c9..a61b032 100644 --- a/service_client/plugins.py +++ b/service_client/plugins.py @@ -1,11 +1,11 @@ import logging -from asyncio import wait_for, TimeoutError +import weakref +from asyncio import TimeoutError, wait_for from datetime import datetime +from functools import wraps from urllib.parse import quote_plus -import weakref from async_timeout import timeout as TimeoutContext -from functools import wraps from multidict import CIMultiDict from service_client.utils import IncompleteFormatter, random_token @@ -336,16 +336,15 @@ def __init__(self, limit=1, timeout=None, hard_limit=None): self.limit = limit self._counter = 0 self._fut = None - self._pending = 0 + self._pending_futs = [] self._timeout = timeout self._hard_limit = hard_limit @property def pending(self): - return self._pending + return len(self._pending_futs) async def _acquire(self): - timeout = self._timeout while True: if self._counter < self.limit: @@ -355,26 +354,26 @@ async def _acquire(self): if self._hard_limit is not None and self._hard_limit < self.pending: raise TooManyRequestsPendingError(self.TOO_MANY_REQ_PENDING_MSG) - if self._fut is None: - self._fut = self.service_client.loop.create_future() - self._pending += 1 + fut = self.service_client.loop.create_future() + self._pending_futs.append(fut) try: now = self.service_client.loop.time() - await wait_for(self._fut, timeout=timeout, loop=self.service_client.loop) + await wait_for(fut, timeout=timeout, loop=self.service_client.loop) if timeout is not None: timeout -= self.service_client.loop.time() - now - if timeout <= 0: - raise TimeoutError() except TimeoutError: raise TooMuchTimePendingError(self.TOO_MUCH_TIME_MSG) - finally: - self._pending -= 1 def _release(self): self._counter -= 1 - if self._fut is not None: - self._fut.set_result(None) + + try: + fut = self._pending_futs.pop(0) + except IndexError: + pass + else: + fut.set_result(None) async def before_request(self, endpoint_desc, session, request_params): start = self.service_client.loop.time() @@ -386,9 +385,10 @@ async def before_request(self, endpoint_desc, session, request_params): self.service_client.loop.time() - start) def close(self): - if self._fut is not None: - from service_client import ConnectionClosedError - self._fut.set_exception(ConnectionClosedError('Connection closed')) + from service_client import ConnectionClosedError + while len(self._pending_futs): + fut = self._pending_futs.pop(0) + fut.set_exception(ConnectionClosedError('Connection closed')) class Pool(BaseLimitPlugin): diff --git a/service_client/spec_loaders.py b/service_client/spec_loaders.py index 3c70ee5..364c219 100644 --- a/service_client/spec_loaders.py +++ b/service_client/spec_loaders.py @@ -1,5 +1,3 @@ - - def json_loader(filename): from json import load with open(filename) as f: @@ -7,9 +5,9 @@ def json_loader(filename): def yaml_loader(filename): - from yaml import load + from yaml import load, FullLoader with open(filename) as f: - return load(f) + return load(f, Loader=FullLoader) def configuration_loader(filename): diff --git a/setup.py b/setup.py index b25f0bf..935d0bf 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>=3.1.1'], + install_requires=['dirty-loader>=0.2.2', 'aiohttp>=3.7.4', 'configure-fork'], 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 6947fd9..ab224de 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,13 +1,31 @@ -from asyncio import get_event_loop +from asyncio import Future, get_event_loop from aiohttp import ClientResponse, RequestInfo +from aiohttp.helpers import TimerContext from yarl import URL async def create_fake_response(method, url, *, session, headers=None, loop=None): + loop = loop or get_event_loop() + + try: + from asyncio import create_task + except ImportError: # pragma: no cover + create_task = loop.create_task + + async def writer(*args, **kwargs): + return None + + continue100 = Future() + continue100.set_result(False) + return ClientResponse(method, URL(url), - writer=None, continue100=False, timer=None, - request_info=RequestInfo(URL(url), method, + writer=create_task(writer()), + continue100=continue100, + timer=TimerContext(loop=loop), + request_info=RequestInfo(URL(url), + method, headers or []), - auto_decompress=False, - traces=[], loop=loop or get_event_loop(), session=session) + traces=[], + loop=loop, + session=session) diff --git a/tests/tests_formatters.py b/tests/tests_formatters.py index d4487bf..c5cbbfe 100644 --- a/tests/tests_formatters.py +++ b/tests/tests_formatters.py @@ -95,7 +95,7 @@ def test_on_parse_exception(self): 'status_code': 404, 'elapsed': timedelta(seconds=0.214), 'exception': AttributeError('test exception')}) - log_text = """EXCEPTION | GET http://example.com | 404 Not Found | 214 ms | AttributeError('test exception',) + log_text = """EXCEPTION | GET http://example.com | 404 Not Found | 214 ms | AttributeError('test exception') Headers: Test-Header-1: header value 1 Test-Header-2: header value 2 @@ -110,7 +110,7 @@ def test_on_exception(self): 'method': 'GET', 'url': 'http://example.com', 'exception': AttributeError('test exception')}) - log_text = "EXCEPTION | GET http://example.com | AttributeError('test exception',)" + log_text = "EXCEPTION | GET http://example.com | AttributeError('test exception')" self.assertEqual(self.formatter.formatMessage(log_entry), log_text) diff --git a/tests/tests_mocks.py b/tests/tests_mocks.py index f4b66d0..520522a 100644 --- a/tests/tests_mocks.py +++ b/tests/tests_mocks.py @@ -2,6 +2,7 @@ from aiohttp import hdrs from aiohttp.client import ClientSession from asynctest.case import TestCase +from multidict import CIMultiDict from service_client.mocks import Mock, mock_manager, RawFileMock from service_client.utils import ObjectWrapper @@ -124,7 +125,7 @@ async def test_calling_mock_same_endpoint(self): @mock_manager.patch_mock_desc(patch={'mock_type': 'default:RawFileMock', 'file': os.path.join(MOCKS_DIR, 'test_mock_text.data'), - 'headers': {hdrs.CONTENT_TYPE: "text/plain; charset=utf8"}}) + 'headers': CIMultiDict({hdrs.CONTENT_TYPE: "text/plain; charset=utf8"})}) async def test_patch_mock(self): await self.plugin.prepare_session(self.service_desc, self.session, {}) self.assertIsInstance(self.session.request, RawFileMock) diff --git a/tests/tests_plugins.py b/tests/tests_plugins.py index 56fd567..d324d12 100644 --- a/tests/tests_plugins.py +++ b/tests/tests_plugins.py @@ -3,12 +3,16 @@ @author: alfred ''' -import asyncio import logging from asyncio import TimeoutError -from asyncio.tasks import shield, sleep +from asyncio.tasks import Task, ensure_future, gather, shield, sleep, wait, wait_for from datetime import datetime, timedelta +try: + all_tasks = Task.all_tasks +except AttributeError: # pragma: no cover + from asyncio import all_tasks + from aiohttp.client import ClientSession from asynctest.case import TestCase from multidict import CIMultiDict @@ -101,6 +105,19 @@ async def test_no_param(self): self.assertDictEqual(self.request_params, {'path_param2': 'bar'}) +class ResponseMock: + + def __init__(self, spend_time): + self.spend_time = spend_time + + async def start(self, *args, **kwargs): + await sleep(self.spend_time) + + async def read(self): + await sleep(self.spend_time) + return 'data' + + class TimeoutTests(TestCase): async def setUp(self): @@ -198,46 +215,51 @@ async def setUp(self): async def test_use_default(self): await self.plugin.prepare_request_params(self.endpoint_desc, self.session, self.request_params) - self.assertDictEqual(self.request_params, {'path_param1': 'foo', - 'path_param2': 'bar', - 'headers': {'X-Foo-Bar': 'test headers'}}) + self.assertDictEqual(self.request_params, + {'path_param1': 'foo', + 'path_param2': 'bar', + 'headers': CIMultiDict({'X-Foo-Bar': 'test headers'})}) async def test_use_service(self): self.endpoint_desc['headers'] = {'x-foo-bar': 'test headers service_client'} await self.plugin.prepare_request_params(self.endpoint_desc, self.session, self.request_params) - self.assertDictEqual(self.request_params, {'path_param1': 'foo', - 'path_param2': 'bar', - 'headers': {'X-Foo-Bar': 'test headers service_client'}}) + self.assertDictEqual(self.request_params, + {'path_param1': 'foo', + 'path_param2': 'bar', + 'headers': CIMultiDict({'X-Foo-Bar': 'test headers service_client'})}) async def test_add_from_service(self): self.endpoint_desc['headers'] = {'x-foo-bar-service': 'test headers service_client'} await self.plugin.prepare_request_params(self.endpoint_desc, self.session, self.request_params) - self.assertDictEqual(self.request_params, {'path_param1': 'foo', - 'path_param2': 'bar', - 'headers': {'X-Foo-Bar': 'test headers', - 'X-Foo-Bar-Service': 'test headers service_client'}}) + self.assertDictEqual(self.request_params, + {'path_param1': 'foo', + 'path_param2': 'bar', + 'headers': CIMultiDict({'X-Foo-Bar': 'test headers', + 'X-Foo-Bar-Service': 'test headers service_client'})}) async def test_use_request(self): self.endpoint_desc['headers'] = {'x-foo-bar': 'test headers service_client'} self.request_params['headers'] = {'x-foo-bar': 'test headers request'} await self.plugin.prepare_request_params(self.endpoint_desc, self.session, self.request_params) - self.assertDictEqual(self.request_params, {'path_param1': 'foo', - 'path_param2': 'bar', - 'headers': {'X-Foo-Bar': 'test headers request'}}) + self.assertDictEqual(self.request_params, + {'path_param1': 'foo', + 'path_param2': 'bar', + 'headers': CIMultiDict({'X-Foo-Bar': 'test headers request'})}) - async def test_add_from_request(self): - self.endpoint_desc['headers'] = {'x-foo-bar-service': 'test headers service_client'} - self.request_params['headers'] = {'x-foo-bar-request': 'test headers request'} - await self.plugin.prepare_request_params(self.endpoint_desc, self.session, self.request_params) + async def test_add_from_request(self): + self.endpoint_desc['headers'] = {'x-foo-bar-service': 'test headers service_client'} + self.request_params['headers'] = {'x-foo-bar-request': 'test headers request'} + await self.plugin.prepare_request_params(self.endpoint_desc, self.session, self.request_params) - self.assertDictEqual(self.request_params, {'path_param1': 'foo', - 'path_param2': 'bar', - 'headers': {'X-Foo-Bar': 'test headers', - 'X-Foo-Bar-Service': 'test headers service_client', - 'X-Foo-Bar-Request': 'test headers request'}}) + self.assertDictEqual(self.request_params, + {'path_param1': 'foo', + 'path_param2': 'bar', + 'headers': CIMultiDict({'X-Foo-Bar': 'test headers', + 'X-Foo-Bar-Service': 'test headers service_client', + 'X-Foo-Bar-Request': 'test headers request'})}) class QueryParamsTest(TestCase): @@ -367,19 +389,6 @@ async def test_use_request_remove(self): 'default_param2': 'bar'}}) -class ResponseMock: - - def __init__(self, spend_time): - self.spend_time = spend_time - - async def start(self, *args, **kwargs): - await sleep(self.spend_time) - - async def read(self): - await sleep(self.spend_time) - return 'data' - - class ElapsedTest(TestCase): spend_time = 0.1 @@ -591,7 +600,7 @@ async def request(self, *args, **kwargs): response._body = b'ssssssss' response.status = 200 response.elapsed = timedelta(seconds=100) - response.headers = CIMultiDict({"content-type": "application/json"}) + response._headers = CIMultiDict({"content-type": "application/json"}) return response class LoggerMock: @@ -796,7 +805,7 @@ async def request(self, *args, **kwargs): response._body = b'ssssssss' response.status = 200 response.elapsed = timedelta(seconds=100) - response.headers = CIMultiDict({"content-type": "application/json"}) + response._headers = CIMultiDict({"content-type": "application/json"}) return response class LoggerMock: @@ -979,45 +988,45 @@ class ServiceMock: 'path_param2': 'bar'} def tearDown(self): - pending = [t for t in asyncio.Task.all_tasks() if not t.done()] + pending = [t for t in all_tasks(loop=self.loop) if not t.done()] while len(pending): try: - self.loop.run_until_complete(asyncio.gather(*pending, - loop=self.loop)) - except Exception: + self.loop.run_until_complete(gather(*pending, + loop=self.loop)) + except BaseException: pass finally: - pending = [t for t in asyncio.Task.all_tasks() if not t.done()] + pending = [t for t in all_tasks(loop=self.loop) if not t.done()] async def test_limit(self): await self.plugin.before_request(self.endpoint_desc, self.session, self.request_params) - fut = asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + fut = ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) with self.assertRaises(TimeoutError): - await asyncio.wait_for(shield(fut), 0.01) + await wait_for(shield(fut), 0.01) await self.plugin.on_response(self.endpoint_desc, self.session, self.request_params, None) - await asyncio.wait_for(fut, 0.1) + await wait_for(fut, 0.1) async def test_limit_using_exception(self): await self.plugin.before_request(self.endpoint_desc, self.session, self.request_params) - fut = asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + fut = ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) with self.assertRaises(TimeoutError): - await asyncio.wait_for(shield(fut), 0.01) + await wait_for(shield(fut), 0.01) await self.plugin.on_exception(self.endpoint_desc, self.session, self.request_params, Exception()) - await asyncio.wait_for(fut, 0.1) + await wait_for(fut, 0.1) async def test_timeout(self): await self.plugin.before_request(self.endpoint_desc, self.session, @@ -1031,16 +1040,16 @@ async def test_timeout(self): self.assertLessEqual(self.session.blocked_by_pool, 0.5) async def test_hard_limit(self): - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) with self.assertRaisesRegex(TooManyRequestsPendingError, "Too many requests pending on pool"): - await asyncio.wait_for(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params), timeout=1) + await wait_for(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params), timeout=1) self.assertGreaterEqual(self.session.blocked_by_pool, 0) self.assertLessEqual(self.session.blocked_by_pool, 0.1) @@ -1050,10 +1059,10 @@ async def test_close(self): self.request_params) with self.assertRaises(ConnectionClosedError): - fut = asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, - self.session, - self.request_params)) - await asyncio.sleep(0) + fut = ensure_future(self.plugin.before_request(self.endpoint_desc, + self.session, + self.request_params)) + await sleep(0) self.plugin.close() await fut @@ -1101,62 +1110,62 @@ class ServiceMock: 'path_param2': 'bar'} def tearDown(self): - pending = [t for t in asyncio.Task.all_tasks() if not t.done()] + pending = [t for t in all_tasks(loop=self.loop) if not t.done()] while len(pending): try: - self.loop.run_until_complete(asyncio.gather(*pending, - loop=self.loop)) - except Exception: + self.loop.run_until_complete(gather(*pending, + loop=self.loop)) + except BaseException: pass finally: - pending = [t for t in asyncio.Task.all_tasks() if not t.done()] + pending = [t for t in all_tasks(loop=self.loop) if not t.done()] async def test_limit(self): await self.plugin.before_request(self.endpoint_desc, self.session, self.request_params) - fut = asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + fut = ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) with self.assertRaises(TimeoutError): - await asyncio.wait_for(shield(fut), 0.1) + await wait_for(shield(fut), 0.1) await self.plugin.on_response(self.endpoint_desc, self.session, self.request_params, None) - await asyncio.sleep(0.2) + await sleep(0.2) - await asyncio.wait_for(fut, 0.5) + await wait_for(fut, 0.5) async def test_limit_using_exception(self): await self.plugin.before_request(self.endpoint_desc, self.session, self.request_params) - fut = asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + fut = ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) with self.assertRaises(TimeoutError): - await asyncio.wait_for(shield(fut), 0.1) + await wait_for(shield(fut), 0.1) await self.plugin.on_exception(self.endpoint_desc, self.session, self.request_params, Exception()) - await asyncio.sleep(0.2) + await sleep(0.2) - await asyncio.wait_for(fut, 0.1) + await wait_for(fut, 0.1) async def test_timeout(self): - asyncio.wait([ - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)), - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + await wait([ + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)), + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) ]) await self.plugin.on_exception(self.endpoint_desc, self.session, self.request_params, Exception()) - await asyncio.sleep(0.2) + await sleep(0.2) await self.plugin.before_request(self.endpoint_desc, self.session, self.request_params) @@ -1171,14 +1180,14 @@ async def test_timeout(self): async def test_hard_limit(self): await self.plugin.before_request(self.endpoint_desc, self.session, self.request_params) - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) - asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params)) + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) + ensure_future(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params)) with self.assertRaisesRegex(TooManyRequestsPendingError, "Too many requests pending by rate limit"): - await asyncio.wait_for(self.plugin.before_request(self.endpoint_desc, self.session, - self.request_params), timeout=1) + await wait_for(self.plugin.before_request(self.endpoint_desc, self.session, + self.request_params), timeout=1) self.assertGreaterEqual(self.session.blocked_by_ratelimit, 0) self.assertLessEqual(self.session.blocked_by_ratelimit, 0.5) @@ -1188,10 +1197,10 @@ async def test_close(self): self.request_params) with self.assertRaises(ConnectionClosedError): - fut = asyncio.ensure_future(self.plugin.before_request(self.endpoint_desc, - self.session, - self.request_params)) - await asyncio.sleep(0) + fut = ensure_future(self.plugin.before_request(self.endpoint_desc, + self.session, + self.request_params)) + await sleep(0) self.plugin.close() await fut @@ -1203,4 +1212,4 @@ async def test_regular_work(self): await self.plugin.on_response(self.endpoint_desc, self.session, self.request_params, None) - await asyncio.sleep(0.2) + await sleep(0.2) diff --git a/tests/tests_service_client.py b/tests/tests_service_client.py index e6cdcc5..907f5d1 100644 --- a/tests/tests_service_client.py +++ b/tests/tests_service_client.py @@ -1,5 +1,12 @@ from asyncio.tasks import Task +from multidict import CIMultiDict + +try: + current_task = Task.current_task +except AttributeError: # pragma: no cover + from asyncio import current_task + from aiohttp import RequestInfo from asynctest.case import TestCase from asynctest.mock import patch @@ -606,13 +613,14 @@ def serializer(data, *args, **kwargs): await self.service_client.call('testService5', payload='aaaa') async def test_create_response(self): - task = Task.current_task(loop=self.loop) + task = current_task(loop=self.loop) task.session = {} task.endpoint_desc = {} task.request_params = {} 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, + request_info=RequestInfo(URL("http://test.com"), + 'get', + headers=CIMultiDict()), traces=[], loop=self.loop, session=self.service_client.session) self.assertIsInstance(response, ObjectWrapper)