Skip to content

Commit

Permalink
Revert "mockserver cleanup error reporting (#71)"
Browse files Browse the repository at this point in the history
This reverts commit 3d8fcc9.
  • Loading branch information
vitek committed Mar 1, 2024
1 parent 5b175b2 commit ae06b02
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 97 deletions.
2 changes: 1 addition & 1 deletion tests/plugins/mockserver/test_invalid_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ def _foo_handler(request):
)
assert response.status_code == 500
# pylint: disable=protected-access
error = mockserver._session._errors.pop()
error, _report_msg = mockserver._session.reporter._errors.pop()
assert isinstance(error, http.InvalidRequestError)
40 changes: 0 additions & 40 deletions tests/plugins/mockserver/test_mockserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@
import aiohttp
import pytest

from testsuite.mockserver import exceptions
from testsuite._internal import fixture_types


class UserError(Exception):
pass


class Client:
def __init__(self, *, base_url, session):
self._session = session
Expand Down Expand Up @@ -76,38 +71,3 @@ def _foo_handler(request):
data = await response.content.read()

assert data == b'hello'


async def test_user_error(
mockserver: fixture_types.MockserverFixture,
mockserver_client: Client,
):
@mockserver.json_handler('/foo')
def _foo_handler(request):
raise UserError

response = await mockserver_client.get('/foo')
assert response.status == 500

session = mockserver._session
assert len(session._errors) == 1

error = session._errors.pop()
assert isinstance(error, UserError)


async def test_nohandler(
mockserver: fixture_types.MockserverFixture,
mockserver_client: Client,
):
response = await mockserver_client.get(
'/foo123',
headers={mockserver.trace_id_header: mockserver.trace_id},
)
assert response.status == 500

session = mockserver._session
assert len(session._errors) == 1

error = session._errors.pop()
assert isinstance(error, exceptions.HandlerNotFoundError)
9 changes: 6 additions & 3 deletions tests/plugins/mockserver/test_tracing_disabled.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pytest

from testsuite.mockserver import exceptions
from testsuite.mockserver import reporter_plugin
from testsuite.mockserver import server


Expand Down Expand Up @@ -42,17 +43,19 @@ async def test_mockserver_raises_on_unhandled_request_from_other_sources(
http_headers,
mockserver_info,
):
reporter = reporter_plugin.MockserverReporterPlugin(colors_enabled=False)
mockserver = server.Server(
mockserver_info,
tracing_enabled=False,
reporter=reporter,
)
with mockserver.new_session() as session:
with mockserver.new_session():
request = aiohttp.test_utils.make_mocked_request(
'POST',
'/arbitrary/path',
headers=http_headers,
)
await mockserver._handle_request(request)
assert len(session._errors) == 1
error = session._errors.pop()
assert len(reporter._errors) == 1
error, _report_msg = reporter._errors[0]
assert isinstance(error, exceptions.HandlerNotFoundError)
4 changes: 0 additions & 4 deletions tests/plugins/mockserver/test_tracing_enabled.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import aiohttp.web
import pytest

from testsuite.mockserver import exceptions
from testsuite.mockserver import server # pylint: disable=protected-access


Expand Down Expand Up @@ -96,6 +95,3 @@ async def test_mockserver_responds_500_on_unhandled_request_from_other_sources(
client = create_service_client(mockserver.base_url, headers=http_headers)
response = await client.post('arbitrary/path')
assert response.status_code == 500

session = mockserver._session
assert len(session._errors) == 0
2 changes: 2 additions & 0 deletions tests/plugins/mockserver/test_unix_mockserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ def unix_mockserver(
@pytest.fixture(scope='session')
async def _unix_mockserver(
testsuite_logger,
_mockserver_reporter,
pytestconfig,
tmp_path_factory,
):
async with server.create_unix_server(
tmp_path_factory.mktemp('mockserver') / 'mockserver.socket',
loop=None,
testsuite_logger=testsuite_logger,
mockserver_reporter=_mockserver_reporter,
pytestconfig=pytestconfig,
) as result:
yield result
Expand Down
52 changes: 37 additions & 15 deletions testsuite/mockserver/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from . import classes
from . import exceptions
from . import reporter_plugin
from . import server

MOCKSERVER_DEFAULT_PORT = 9999
Expand Down Expand Up @@ -114,6 +115,15 @@ def pytest_addoption(parser):
)


def pytest_configure(config):
config.pluginmanager.register(
reporter_plugin.MockserverReporterPlugin(
colors_enabled=colors.should_enable_color(config),
),
'mockserver_reporter',
)


def pytest_register_object_hooks():
return {
'$mockserver': {'$fixture': '_mockserver_hook'},
Expand Down Expand Up @@ -205,14 +215,16 @@ async def _mockserver(
pytestconfig,
testsuite_logger,
loop,
_mockserver_reporter,
_mockserver_getport,
) -> annotations.AsyncYieldFixture[server.Server]:
if pytestconfig.option.mockserver_unix_socket:
async with server.create_unix_server(
socket_path=pytestconfig.option.mockserver_unix_socket,
loop=loop,
testsuite_logger=testsuite_logger,
pytestconfig=pytestconfig,
pytestconfig.option.mockserver_unix_socket,
loop,
testsuite_logger,
_mockserver_reporter,
pytestconfig,
) as result:
yield result
else:
Expand All @@ -221,11 +233,12 @@ async def _mockserver(
MOCKSERVER_DEFAULT_PORT,
)
async with server.create_server(
host=pytestconfig.option.mockserver_host,
port=port,
loop=loop,
testsuite_logger=testsuite_logger,
pytestconfig=pytestconfig,
pytestconfig.option.mockserver_host,
port,
loop,
testsuite_logger,
_mockserver_reporter,
pytestconfig,
ssl_info=None,
) as result:
yield result
Expand All @@ -237,6 +250,7 @@ async def _mockserver_ssl(
testsuite_logger,
loop,
mockserver_ssl_cert,
_mockserver_reporter,
_mockserver_getport,
) -> annotations.AsyncYieldFixture[typing.Optional[server.Server]]:
if mockserver_ssl_cert:
Expand All @@ -245,18 +259,26 @@ async def _mockserver_ssl(
MOCKSERVER_SSL_DEFAULT_PORT,
)
async with server.create_server(
host=pytestconfig.option.mockserver_ssl_host,
port=port,
loop=loop,
testsuite_logger=testsuite_logger,
pytestconfig=pytestconfig,
ssl_info=mockserver_ssl_cert,
pytestconfig.option.mockserver_ssl_host,
port,
loop,
testsuite_logger,
_mockserver_reporter,
pytestconfig,
mockserver_ssl_cert,
) as result:
yield result
else:
yield None


@pytest.fixture(scope='session')
def _mockserver_reporter(
pytestconfig,
) -> reporter_plugin.MockserverReporterPlugin:
return pytestconfig.pluginmanager.get_plugin('mockserver_reporter')


@pytest.fixture
def _mockserver_trace_id() -> str:
return server.generate_trace_id()
Expand Down
52 changes: 52 additions & 0 deletions testsuite/mockserver/reporter_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import io
import typing

import pytest

from testsuite.utils import colors

from . import exceptions


class MockserverReporterPlugin:
_errors: typing.List[typing.Tuple[Exception, str]]

def __init__(self, *, colors_enabled: bool):
self._colors_enabled = colors_enabled
self._errors = []

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(self, item):
self._errors = []
yield
if self._errors:
report = self._get_report()
item.add_report_section('errors', 'mockserver', report)
item.user_properties.append(('mockserver errors', report))
first_error, _message = self._errors[0]
raise exceptions.MockServerError(
'There were errors while processing mockserver requests.',
) from first_error

def report_error(
self,
error: Exception,
message: typing.Optional[str] = None,
) -> None:
if message is None:
message = str(error)
self._errors.append((error, message))

def _get_report(self) -> str:
if not self._errors:
return ''
output = io.StringIO()
if self._colors_enabled:
output.write(colors.Colors.BRIGHT_RED)
for index, (_error, message) in enumerate(self._errors):
if index > 0:
output.write('\n\n')
output.write(message)
if self._colors_enabled:
output.write(colors.Colors.DEFAULT)
return output.getvalue()
Loading

0 comments on commit ae06b02

Please sign in to comment.