scholarr/tests/unit/test_logging_policy.py
2026-03-01 18:14:22 +01:00

40 lines
1.2 KiB
Python

from __future__ import annotations
import ast
from pathlib import Path
RAW_LOG_METHODS = {
"debug",
"info",
"warning",
"error",
"exception",
"critical",
}
APP_DIR = Path(__file__).resolve().parents[2] / "app"
def _raw_logger_calls(path: Path) -> list[tuple[int, str]]:
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
violations: list[tuple[int, str]] = []
for node in ast.walk(tree):
if not isinstance(node, ast.Call):
continue
func = node.func
if not isinstance(func, ast.Attribute):
continue
if not isinstance(func.value, ast.Name) or func.value.id != "logger":
continue
if func.attr not in RAW_LOG_METHODS:
continue
violations.append((int(node.lineno), func.attr))
return violations
def test_app_runtime_uses_structured_log_only() -> None:
violations: list[str] = []
for path in sorted(APP_DIR.rglob("*.py")):
for line_number, method in _raw_logger_calls(path):
relative_path = path.relative_to(APP_DIR.parent)
violations.append(f"{relative_path}:{line_number} logger.{method}()")
assert not violations, "raw logger calls found:\n" + "\n".join(violations)