Skip to content

Commit

Permalink
Merge pull request #4060 from open-formulieren/chore/suppress-logging…
Browse files Browse the repository at this point in the history
…-output-in-tests

Fixed log output suppression when running tests locally
  • Loading branch information
sergei-maertens authored Mar 28, 2024
2 parents db0dbd3 + 4595a48 commit c7d1d46
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 40 deletions.
15 changes: 2 additions & 13 deletions src/openforms/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,6 @@
},
"timestamped": {"format": "%(asctime)s %(levelname)s %(name)s %(message)s"},
"simple": {"format": "%(levelname)s %(message)s"},
"performance": {
"format": "%(asctime)s %(process)d | %(thread)d | %(message)s",
},
"outgoing_requests": {"()": HttpFormatter},
},
"filters": {
Expand Down Expand Up @@ -425,14 +422,6 @@
"maxBytes": 1024 * 1024 * 10, # 10 MB
"backupCount": 10,
},
"performance": {
"level": "INFO",
"class": "logging.handlers.RotatingFileHandler",
"filename": os.path.join(LOGGING_DIR, "performance.log"),
"formatter": "performance",
"maxBytes": 1024 * 1024 * 10, # 10 MB
"backupCount": 10,
},
"log_outgoing_requests": {
"level": "DEBUG",
"formatter": "outgoing_requests",
Expand All @@ -446,7 +435,7 @@
"loggers": {
"openforms": {
"handlers": ["project"] if not LOG_STDOUT else ["console"],
"level": "DEBUG",
"level": "INFO",
"propagate": True,
},
"stuf": {
Expand All @@ -466,7 +455,7 @@
},
"mozilla_django_oidc": {
"handlers": ["project"] if not LOG_STDOUT else ["console"],
"level": "DEBUG",
"level": "INFO",
},
"log_outgoing_requests": {
"handlers": (
Expand Down
22 changes: 4 additions & 18 deletions src/openforms/conf/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# otherwise the test suite is flaky due to logging config lookups to the DB in
# non-DB test cases
os.environ.setdefault("LOG_REQUESTS", "no")
os.environ.setdefault("LOG_STDOUT", "1")
os.environ.setdefault("VCR_RECORD_MODE", "once")

from .base import * # noqa isort:skip
Expand All @@ -40,30 +41,15 @@

LOGGING["loggers"].update(
{
"openforms": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": True,
},
"stuf": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": True,
},
"django": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": True,
"propagate": False,
},
"django.db.backends": {
"handlers": ["django"],
"level": "DEBUG",
"propagate": False,
},
"performance": {
"handlers": ["console"],
"level": "INFO",
"propagate": True,
"propagate": False,
},
#
# See: https://code.djangoproject.com/ticket/30554
Expand All @@ -77,7 +63,7 @@
"weasyprint": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": True,
"propagate": False,
},
}
)
Expand Down
28 changes: 19 additions & 9 deletions src/openforms/conf/local_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import os
import sys

from .dev import LOGGING as _LOGGING
from .utils import config
from .dev import LOGGING
from .utils import config, mute_logging

# Configure your database via the DB_* envvars in .env, see also dotenv.example file.

Expand All @@ -21,22 +21,32 @@

# Silence logging during testing
# if "VERBOSE" not in os.environ:
# LOGGING = None
# mute_logging(LOGGING)


if "CELERY_TASK_ALWAYS_EAGER" in os.environ:
# run celery tasks so submissions get processed in dev server
# Ceveat emptor: this breaks test isolation and breaks a few tests in the suite
if config("CELERY_TASK_ALWAYS_EAGER", default=False):
CELERY_TASK_ALWAYS_EAGER = True

#
# LOGGING
#

# Log DB queries to file and console
# LOGGING["loggers"]["django.db.backends"] = {
# "handlers": ["django", "console"],
# "level": "DEBUG",
# "propagate": False,
# }

if log_level := os.environ.get("LOG_LEVEL"):
for logger in _LOGGING["loggers"].values():
for logger in LOGGING["loggers"].values():
logger["level"] = log_level


# make the language code configurable via envvars
LANGUAGE_CODE = config("LANGUAGE_CODE", "nl")

# allow SPA dev server and API on different ports
# CORS_ALLOW_ALL_ORIGINS = True

# run celery tasks so submissions get processed in dev server
# Ceveat emptor: this breaks test isolation and breaks a few tests in the suite
# CELERY_TASK_ALWAYS_EAGER = True
20 changes: 20 additions & 0 deletions src/openforms/conf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,23 @@ def get_sentry_integrations() -> list:
extra.append(celery.CeleryIntegration())

return [*default, *extra]


def mute_logging(config: dict) -> None: # pragma: no cover
"""
Disable (console) output from logging.
:arg config: The logging config, typically the django LOGGING setting.
"""

# set up the null handler for all loggers so that nothing gets emitted
for logger in config["loggers"].values():
logger["handlers"] = ["null"]

# some tooling logs to a logger which isn't defined, and that ends up in the root
# logger -> add one so that we can mute that output too.
config["loggers"].update(
{
"": {"handlers": ["null"], "level": "CRITICAL", "propagate": False},
}
)
2 changes: 2 additions & 0 deletions src/openforms/registrations/tests/test_pre_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from openforms.submissions.constants import PostSubmissionEvents
from openforms.submissions.tasks.registration import pre_registration
from openforms.submissions.tests.factories import SubmissionFactory
from openforms.utils.tests.logging import ensure_logger_level


class PreRegistrationTests(TestCase):
Expand Down Expand Up @@ -272,6 +273,7 @@ def test_retry_after_too_many_attempts_skips(self, m_get_solo):
patch(
"openforms.registrations.contrib.zgw_apis.plugin.ZGWRegistration.pre_register_submission"
) as mock_pre_register,
ensure_logger_level("DEBUG"),
self.assertLogs(level="DEBUG") as logs,
):
pre_registration(submission.id, PostSubmissionEvents.on_retry)
Expand Down
2 changes: 2 additions & 0 deletions src/openforms/registrations/tests/test_registration_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from openforms.logging.models import TimelineLogProxy
from openforms.submissions.constants import PostSubmissionEvents, RegistrationStatuses
from openforms.submissions.tests.factories import SubmissionFactory
from openforms.utils.tests.logging import ensure_logger_level

from ..base import BasePlugin
from ..exceptions import RegistrationFailed
Expand Down Expand Up @@ -286,6 +287,7 @@ def register_submission(self, submission, options):

with self.subTest("on retry"):
with (
ensure_logger_level("DEBUG"),
self.assertRaises(RegistrationFailed),
self.assertLogs(level="DEBUG") as logs,
):
Expand Down
2 changes: 2 additions & 0 deletions src/openforms/submissions/tests/test_post_submission_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from openforms.forms.tests.factories import FormDefinitionFactory
from openforms.payments.constants import PaymentStatus
from openforms.payments.tests.factories import SubmissionPaymentFactory
from openforms.utils.tests.logging import ensure_logger_level

from ..constants import PostSubmissionEvents
from ..models import SubmissionReport
Expand Down Expand Up @@ -1058,6 +1059,7 @@ def test_payment_required_and_not_should_wait_for_registration(self):
"openforms.registrations.tasks.GlobalConfiguration.get_solo",
return_value=GlobalConfiguration(wait_for_payment_to_register=True),
),
ensure_logger_level("DEBUG"),
LogCapture() as logs,
):
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion)
Expand Down
22 changes: 22 additions & 0 deletions src/openforms/utils/tests/logging.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
from contextlib import contextmanager
from typing import Iterator

from django.test.utils import TestContextDecorator

Expand All @@ -9,3 +11,23 @@ def enable(self):

def disable(self):
logging.disable(logging.NOTSET)


@contextmanager
def ensure_logger_level(level: str = "INFO", name="openforms") -> Iterator[None]:
"""
Set the (minimum) level for a given logger.
Base or individual settings may tweak the log level to reduce the overload for the
developer, but this affects tests that verify that log records are "written" by
application code for a certain log level.
This context manager allows you to pin the log level for a given text, irrespective
of individual preferences/developer settings.
"""
logger = logging.getLogger(name)
original_level = logger.getEffectiveLevel()

logger.setLevel(logging._nameToLevel[level])
yield
logger.setLevel(original_level)

0 comments on commit c7d1d46

Please sign in to comment.