Files

81 lines
2.9 KiB
Python

import io
import logging
import os
import sys
import unittest
from unittest.mock import patch
import app_logging
def _reset_root_logger() -> None:
root = logging.getLogger()
for handler in list(root.handlers):
root.removeHandler(handler)
handler.close()
root.setLevel(logging.WARNING)
class ConfigureLoggingTests(unittest.TestCase):
def setUp(self) -> None:
_reset_root_logger()
self.addCleanup(_reset_root_logger)
def test_default_level_is_info(self):
with patch.dict(os.environ, {}, clear=False):
os.environ.pop("LOG_LEVEL", None)
app_logging.configure_logging()
self.assertEqual(logging.getLogger().level, logging.INFO)
def test_log_level_env_is_honored(self):
with patch.dict(os.environ, {"LOG_LEVEL": "DEBUG"}, clear=False):
app_logging.configure_logging()
self.assertEqual(logging.getLogger().level, logging.DEBUG)
def test_invalid_log_level_falls_back_to_info(self):
with patch.dict(os.environ, {"LOG_LEVEL": "TOTALLY_BOGUS"}, clear=False):
app_logging.configure_logging()
self.assertEqual(logging.getLogger().level, logging.INFO)
def test_handler_writes_to_stdout_with_expected_format(self):
# basicConfig is a no-op if root already has handlers — start clean.
with patch.dict(os.environ, {"LOG_LEVEL": "INFO"}, clear=False):
app_logging.configure_logging()
# First handler is the one we installed (basicConfig adds at most one).
handlers = logging.getLogger().handlers
self.assertTrue(handlers, "configure_logging() must install a handler")
handler = handlers[0]
self.assertIs(handler.stream, sys.stdout)
# Confirm the format string structure by emitting a record into a buffer.
formatter = handler.formatter
record = logging.LogRecord(
name="test",
level=logging.INFO,
pathname=__file__,
lineno=1,
msg="hello",
args=(),
exc_info=None,
)
rendered = formatter.format(record) if formatter else ""
# Format is "%(asctime)s - %(name)s - %(levelname)s - %(message)s".
self.assertIn(" - test - INFO - hello", rendered)
def test_configure_logging_does_not_swallow_subsequent_logs(self):
buffer = io.StringIO()
# Reset state, then replace stdout briefly so we can capture handler output.
with patch.dict(os.environ, {"LOG_LEVEL": "INFO"}, clear=False):
with patch.object(sys, "stdout", buffer):
app_logging.configure_logging()
logging.getLogger("test.module").info("payload-marker")
for handler in logging.getLogger().handlers:
handler.flush()
self.assertIn("payload-marker", buffer.getvalue())
self.assertIn("INFO", buffer.getvalue())
if __name__ == "__main__": # pragma: no cover
unittest.main()