Skip to content

Commit

Permalink
Add tests for all modules and operating modes, bring coverage to 100%
Browse files Browse the repository at this point in the history
  • Loading branch information
sjaensch committed Jan 25, 2018
1 parent ed3c408 commit 8b1176c
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 6 deletions.
11 changes: 11 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import asyncio

import pytest


@pytest.fixture
def event_loop():
loop = asyncio.new_event_loop()
yield loop
loop.stop()
loop.close()
69 changes: 69 additions & 0 deletions tests/future_adapter_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import asyncio
import concurrent.futures

import mock
import pytest

from bravado_asyncio.definitions import AsyncioResponse
from bravado_asyncio.future_adapter import AsyncioFutureAdapter
from bravado_asyncio.future_adapter import FutureAdapter


@pytest.fixture
def mock_future():
return mock.Mock(name='future')


@pytest.fixture
def mock_response():
return mock.Mock(name='response')


@pytest.fixture
def mock_wait_for():
with mock.patch('bravado_asyncio.future_adapter.asyncio.wait_for') as _mock:
yield _mock


@pytest.fixture
def event_loop():
loop = asyncio.new_event_loop()
yield loop
loop.stop()
loop.close()


def test_future_adapter(mock_future, mock_response):
mock_future.result.return_value = mock_response

future_adapter = FutureAdapter(mock_future)
result = future_adapter.result(timeout=5)

assert isinstance(result, AsyncioResponse)
assert result.response is mock_response
assert 0 < result.remaining_timeout < 5

mock_future.result.assert_called_once_with(5)


def test_future_adapter_timeout_error_class():
"""Let's make sure refactors never break timeout errors"""
assert concurrent.futures.TimeoutError in AsyncioFutureAdapter.timeout_errors


def test_asyncio_future_adapter(mock_future, mock_wait_for, mock_response, event_loop):
mock_wait_for.return_value = asyncio.coroutine(lambda: mock_response)()

future_adapter = AsyncioFutureAdapter(mock_future)
result = event_loop.run_until_complete(future_adapter.result(timeout=5))

assert isinstance(result, AsyncioResponse)
assert result.response is mock_response
assert 0 < result.remaining_timeout < 5

mock_wait_for.assert_called_once_with(mock_future, timeout=5)


def test_asyncio_future_adapter_timeout_error_class():
"""Let's make sure refactors never break timeout errors"""
assert asyncio.TimeoutError in AsyncioFutureAdapter.timeout_errors
27 changes: 21 additions & 6 deletions tests/http_client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
from bravado_asyncio.response_adapter import AioHTTPResponseAdapter


@pytest.fixture(autouse=True)
def mock_ensure_future():
with mock.patch('asyncio.ensure_future') as mocked_ensure_future:
yield mocked_ensure_future


@pytest.fixture
def mock_client_session():
with mock.patch('aiohttp.ClientSession') as _mock:
Expand All @@ -29,6 +23,12 @@ def asyncio_client(request, mock_client_session):
return client


@pytest.fixture
def mock_log():
with mock.patch('bravado_asyncio.http_client.log') as _mock:
yield _mock


@pytest.fixture
def request_params():
return {
Expand All @@ -38,6 +38,11 @@ def request_params():
}


def test_fail_on_unknown_run_mode():
with pytest.raises(ValueError):
AsyncioClient(run_mode='unknown/invalid')


def test_request(asyncio_client, mock_client_session, request_params):
"""Make sure request calls the right functions and instantiates the HttpFuture correctly."""
asyncio_client.response_adapter = mock.Mock(name='response_adapter', spec=AioHTTPResponseAdapter)
Expand Down Expand Up @@ -151,3 +156,13 @@ class FileObj:
assert field_data[0]['name'] == 'picture'
assert field_data[0]['filename'] == 'filename'
assert field_data[2] == FileObj.read.return_value


def test_connect_timeout_logs_warning(asyncio_client, mock_client_session, request_params, mock_log):
request_params['connect_timeout'] = 0.1

asyncio_client.request(request_params)

assert mock_log.warning.call_count == 1
assert 'connect_timeout' in mock_log.warning.call_args[0][0]
assert mock_client_session.return_value.request.call_args[1]['timeout'] is None
118 changes: 118 additions & 0 deletions tests/response_adapter_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import asyncio

import aiohttp
import mock
import pytest

from bravado_asyncio.definitions import AsyncioResponse
from bravado_asyncio.response_adapter import AioHTTPResponseAdapter
from bravado_asyncio.response_adapter import AsyncioHTTPResponseAdapter


@pytest.fixture
def mock_loop():
return mock.Mock(name='loop')


@pytest.fixture(params=(AioHTTPResponseAdapter, AsyncioHTTPResponseAdapter))
def response_adapter(request, mock_loop):
return request.param(mock_loop)


@pytest.fixture
def mock_incoming_response():
return mock.Mock(name='incoming response', spec=aiohttp.ClientResponse)


@pytest.fixture
def asyncio_response(mock_incoming_response):
return AsyncioResponse(response=mock_incoming_response, remaining_timeout=5)


@pytest.fixture
def mock_run_coroutine_threadsafe():
with mock.patch('bravado_asyncio.response_adapter.asyncio.run_coroutine_threadsafe') as _mock:
yield _mock


@pytest.fixture
def mock_wait_for_result():
return mock.Mock(name='mock_wait_for result')


@pytest.fixture
def mock_wait_for(mock_wait_for_result):
with mock.patch('bravado_asyncio.response_adapter.asyncio.wait_for') as _mock:
_mock.return_value = asyncio.coroutine(lambda: mock_wait_for_result)()
yield _mock


def test_initialization(response_adapter, mock_loop, asyncio_response):
called_response_adapter = response_adapter(asyncio_response)

assert called_response_adapter is response_adapter
assert response_adapter._loop is mock_loop
assert response_adapter._delegate is asyncio_response.response
assert response_adapter._remaining_timeout is asyncio_response.remaining_timeout


def test_properties(response_adapter, asyncio_response, mock_incoming_response):
response_adapter(asyncio_response)
assert response_adapter.status_code is mock_incoming_response.status
assert response_adapter.reason is mock_incoming_response.reason
assert response_adapter.headers is mock_incoming_response.headers


def test_thread_methods(mock_run_coroutine_threadsafe, asyncio_response, mock_incoming_response, mock_loop):
response_adapter = AioHTTPResponseAdapter(mock_loop)(asyncio_response)

assert response_adapter.text is mock_run_coroutine_threadsafe.return_value.result.return_value
mock_run_coroutine_threadsafe.assert_called_once_with(mock_incoming_response.text.return_value, mock_loop)
mock_run_coroutine_threadsafe.return_value.result.assert_called_once_with(asyncio_response.remaining_timeout)

assert response_adapter.raw_bytes is mock_run_coroutine_threadsafe.return_value.result.return_value
mock_run_coroutine_threadsafe.assert_called_with(mock_incoming_response.read.return_value, mock_loop)
mock_run_coroutine_threadsafe.return_value.result.assert_called_with(asyncio_response.remaining_timeout)

assert response_adapter.json() is mock_run_coroutine_threadsafe.return_value.result.return_value
mock_run_coroutine_threadsafe.assert_called_with(mock_incoming_response.json.return_value, mock_loop)
mock_run_coroutine_threadsafe.return_value.result.assert_called_with(asyncio_response.remaining_timeout)

assert mock_run_coroutine_threadsafe.call_count == 3
assert mock_run_coroutine_threadsafe.return_value.result.call_count == 3


def test_asyncio_text(mock_wait_for, mock_wait_for_result, asyncio_response, mock_incoming_response, event_loop):
response_adapter = AsyncioHTTPResponseAdapter(event_loop)(asyncio_response)

result = event_loop.run_until_complete(response_adapter.text)
assert result is mock_wait_for_result
mock_wait_for.assert_called_once_with(
mock_incoming_response.text.return_value,
timeout=asyncio_response.remaining_timeout,
loop=event_loop,
)


def test_asyncio_raw_bytes(mock_wait_for, mock_wait_for_result, asyncio_response, mock_incoming_response, event_loop):
response_adapter = AsyncioHTTPResponseAdapter(event_loop)(asyncio_response)

result = event_loop.run_until_complete(response_adapter.raw_bytes)
assert result is mock_wait_for_result
mock_wait_for.assert_called_once_with(
mock_incoming_response.read.return_value,
timeout=asyncio_response.remaining_timeout,
loop=event_loop,
)


def test_asyncio_json(mock_wait_for, mock_wait_for_result, asyncio_response, mock_incoming_response, event_loop):
response_adapter = AsyncioHTTPResponseAdapter(event_loop)(asyncio_response)

result = event_loop.run_until_complete(response_adapter.json())
assert result is mock_wait_for_result
mock_wait_for.assert_called_once_with(
mock_incoming_response.json.return_value,
timeout=asyncio_response.remaining_timeout,
loop=event_loop,
)

0 comments on commit 8b1176c

Please sign in to comment.