Skip to content

Commit

Permalink
Fix problems with json_logging making loggers fail between tests.
Browse files Browse the repository at this point in the history
Related #33
  • Loading branch information
aholmes committed Jan 11, 2024
1 parent 98fa502 commit 471ef31
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
3 changes: 0 additions & 3 deletions src/web/BL_Python/web/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,9 @@ def configure_blueprint_routes(

enable_json_logging = config.logging.format == "JSON"
if enable_json_logging:
# json_logging.init_flask(enable_json=enable_json_logging)
# json_logging.ENABLE_JSON_LOGGING = True
json_logging.init_flask( # pyright: ignore[reportUnknownMemberType]
enable_json=enable_json_logging
)
# json_logging.__init(framework_name="flask")
json_logging.init_request_instrument( # pyright: ignore[reportUnknownMemberType]
app
)
Expand Down
51 changes: 41 additions & 10 deletions src/web/test/unit/create_app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import importlib
import logging
from collections import defaultdict
from contextlib import _GeneratorContextManager # pyright: ignore[reportPrivateUsage]
from contextlib import ExitStack
from typing import Any, Generator, Protocol, cast
Expand All @@ -17,6 +20,7 @@
from flask.ctx import RequestContext
from flask.sessions import SecureCookieSession
from flask.testing import FlaskClient
from mock import MagicMock
from pytest_mock import MockerFixture


Expand All @@ -38,6 +42,8 @@ def __call__(


class CreateApp:
_automatic_mocks: dict[str, MagicMock] = defaultdict()

def _basic_config(self) -> Config:
return Config(
flask=FlaskConfig(
Expand Down Expand Up @@ -148,14 +154,39 @@ def _flask_request_getter(
# then tells pytest to use it for every test in the class
@pytest.fixture(autouse=True)
def setup_method_fixture(self, mocker: MockerFixture):
_ = mocker.patch("io.open")
_ = mocker.patch("toml.decoder.loads", return_value={})
_ = mocker.patch(
"BL_Python.web.application._import_blueprint_modules", return_value=[]
)
# pre-test execution

# the pytest log formatters need to be restored
# in the event json_logging changes them, otherwise
# some tests may fail
log_formatters = [handler.formatter for handler in logging.getLogger().handlers]

self._automatic_mocks = {}

mock_targets: list[tuple[str] | tuple[str, Any]] = [
("io.open",),
("toml.decoder.loads", {}),
("BL_Python.web.application._import_blueprint_modules", []),
]

for mock_target in mock_targets:
if len(mock_target) == 1:
(target_name,) = mock_target
mock = mocker.patch(target_name)
else:
(target_name, return_value) = mock_target
mock = mocker.patch(target_name)
mock.return_value = return_value

self._automatic_mocks[target_name] = mock

# post-test execution
yield

for i, handler in enumerate(logging.getLogger().handlers):
# this assumes handlers are in the same order
# so is prone to breakage
handler.formatter = log_formatters[i]

# json_logging relies on global, so they must be reset between each test
json_logging._current_framework = None # pyright: ignore[reportPrivateUsage]
json_logging._request_util = None # pyright: ignore[reportPrivateUsage]
json_logging._default_formatter = None # pyright: ignore[reportPrivateUsage]
json_logging.ENABLE_JSON_LOGGING = False
json_logging.ENABLE_JSON_LOGGING_DEBUG = False
_ = importlib.reload(json_logging)

0 comments on commit 471ef31

Please sign in to comment.