Granian serves the compiled SPA assets directly in Rust: hashed js/wasm/css under /static (the release build uses --public-url /static/) and the card images under /assets, configured with the GRANIAN_STATIC_PATH_ROUTE/MOUNT/ DIR_TO_FILE env vars in the Dockerfile. The Python catch-all now only serves the SPA shell (index.html) at / and for client-side routes. Every module logs through getLogger(__name__): lifecycle and business events at INFO, per-move and store detail at DEBUG. The built-in default writes DEBUG to the console; LOGGING_CONFIG points at a YAML file in the logging.config.dictConfig schema to take over the configuration. PyYAML becomes a direct dependency.
67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
"""Tests for the logging configuration entry point."""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from tavolo.logging_config import configure_logging
|
|
|
|
|
|
class LoggingConfigTest(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
# configure_logging mutates the global logging state; snapshot and
|
|
# restore it so the rest of the suite is unaffected.
|
|
root = logging.getLogger()
|
|
self._root_handlers = root.handlers[:]
|
|
self._root_level = root.level
|
|
tavolo = logging.getLogger("tavolo")
|
|
self._tavolo_level = tavolo.level
|
|
|
|
def tearDown(self) -> None:
|
|
root = logging.getLogger()
|
|
root.handlers = self._root_handlers
|
|
root.level = self._root_level
|
|
logging.getLogger("tavolo").level = self._tavolo_level
|
|
|
|
def test_default_config_when_unset(self) -> None:
|
|
configure_logging(None)
|
|
root = logging.getLogger()
|
|
self.assertEqual(logging.DEBUG, root.level)
|
|
self.assertTrue(
|
|
any(isinstance(h, logging.StreamHandler) for h in root.handlers),
|
|
"default config installs a console stream handler",
|
|
)
|
|
|
|
def test_yaml_config_is_applied(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
config = Path(tmp) / "logging.yaml"
|
|
config.write_text(
|
|
"version: 1\n"
|
|
"disable_existing_loggers: false\n"
|
|
"root:\n"
|
|
" level: WARNING\n"
|
|
"loggers:\n"
|
|
" tavolo:\n"
|
|
" level: DEBUG\n"
|
|
)
|
|
configure_logging(str(config))
|
|
self.assertEqual(logging.DEBUG, logging.getLogger("tavolo").getEffectiveLevel())
|
|
self.assertEqual(logging.WARNING, logging.getLogger().getEffectiveLevel())
|
|
|
|
def test_missing_file_raises(self) -> None:
|
|
with self.assertRaises(RuntimeError):
|
|
configure_logging("/nonexistent/logging.yaml")
|
|
|
|
def test_non_mapping_yaml_raises(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
config = Path(tmp) / "logging.yaml"
|
|
config.write_text("- just\n- a\n- list\n")
|
|
with self.assertRaises(RuntimeError):
|
|
configure_logging(str(config))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|