from __future__ import annotations import os from unittest import TestCase from unittest.mock import patch from fastapi import APIRouter from fastapi.testclient import TestClient from sqlalchemy import text from govoplan_core.core.registry import PlatformRegistry from govoplan_core.db.query_metrics import collect_query_metrics from govoplan_core.db.session import create_database_engine from govoplan_core.server.fastapi import create_govoplan_app class QueryMetricsTests(TestCase): def test_collect_query_metrics_counts_instrumented_engine_queries(self) -> None: engine = create_database_engine("sqlite:///:memory:") try: with collect_query_metrics() as metrics: with engine.connect() as connection: self.assertEqual(1, connection.execute(text("select 1")).scalar_one()) self.assertEqual(1, metrics.query_count) self.assertGreaterEqual(metrics.total_ms, 0.0) self.assertGreaterEqual(metrics.slowest_ms, 0.0) self.assertEqual(0, metrics.error_count) finally: engine.dispose() def test_slow_request_log_includes_query_metrics(self) -> None: engine = create_database_engine("sqlite:///:memory:") router = APIRouter() @router.get("/query") def query_route() -> dict[str, bool]: with engine.connect() as connection: connection.execute(text("select 1")).scalar_one() return {"ok": True} try: with patch.dict(os.environ, {"GOVOPLAN_SLOW_REQUEST_MS": "0.001"}): app = create_govoplan_app( title="query metrics test", version="0", registry=PlatformRegistry(), api_router=router, ) with TestClient(app) as client, self.assertLogs("govoplan.request", level="WARNING") as logs: response = client.get("/query") self.assertEqual(200, response.status_code, response.text) output = "\n".join(logs.output) self.assertIn("db_query_count=1", output) self.assertIn("db_time_ms=", output) self.assertIn("db_slowest_ms=", output) self.assertIn("db_error_count=0", output) finally: engine.dispose()