운영 지표와 지원 요청 저장소 추가

This commit is contained in:
Yun Chan 2026-06-28 20:13:06 +09:00
parent 50fa4ad432
commit e7ebb38177
20 changed files with 3038 additions and 39 deletions

View file

@ -0,0 +1,111 @@
"""Admin health sample retention/rollup tests."""
from __future__ import annotations
import unittest
import unittest.mock
from .services import admin_health_maintenance as maintenance
class _Acquire:
def __init__(self, conn):
self.conn = conn
async def __aenter__(self):
return self.conn
async def __aexit__(self, exc_type, exc, tb):
return None
class AdminHealthMaintenanceTest(unittest.IsolatedAsyncioTestCase):
async def test_dry_run_counts_rollup_and_prunable_events_without_mutation(self) -> None:
class Conn:
def __init__(self):
self.fetch_calls = []
async def fetchrow(self, query, *args, **kwargs):
self.fetch_calls.append((query, args))
if len(self.fetch_calls) == 1:
return {"event_count": 12, "bucket_count": 3}
return {"event_count": 4}
async def fetch(self, *args, **kwargs):
raise AssertionError("dry-run must not upsert rollups")
async def execute(self, *args, **kwargs):
raise AssertionError("dry-run must not delete raw events")
conn = Conn()
with unittest.mock.patch.object(maintenance, "acquire", return_value=_Acquire(conn)):
result = await maintenance.maintain_admin_health_events(
rollup_days=2,
retention_days=30,
apply=False,
)
self.assertFalse(result.applied)
self.assertEqual(result.rollup_event_count, 12)
self.assertEqual(result.rollup_bucket_count, 3)
self.assertEqual(result.prunable_event_count, 4)
self.assertEqual(result.upserted_rollups, 0)
self.assertEqual(result.deleted_events, 0)
self.assertEqual(conn.fetch_calls[0][1], (2,))
self.assertEqual(conn.fetch_calls[1][1], (30,))
self.assertIn("observed_at::date < current_date - $1::int", conn.fetch_calls[0][0])
async def test_apply_upserts_rollups_before_pruning_raw_events(self) -> None:
calls = []
class Conn:
async def fetchrow(self, query, *args, **kwargs):
calls.append(("fetchrow", query, args))
if len([call for call in calls if call[0] == "fetchrow"]) == 1:
return {"event_count": 7, "bucket_count": 2}
return {"event_count": 5}
async def fetch(self, query, *args, **kwargs):
calls.append(("fetch", query, args))
return [1, 1]
async def execute(self, query, *args, **kwargs):
calls.append(("execute", query, args))
return "DELETE 5"
with unittest.mock.patch.object(maintenance, "acquire", return_value=_Acquire(Conn())):
result = await maintenance.maintain_admin_health_events(
rollup_days=3,
retention_days=30,
apply=True,
)
self.assertTrue(result.applied)
self.assertEqual(result.upserted_rollups, 2)
self.assertEqual(result.deleted_events, 5)
self.assertEqual([call[0] for call in calls], ["fetchrow", "fetchrow", "fetch", "execute"])
self.assertIn("INSERT INTO app.admin_health_daily_rollup", calls[2][1])
self.assertIn("last_down_at", calls[2][1])
self.assertIn("DELETE FROM app.admin_health_event", calls[3][1])
def test_invalid_windows_are_rejected(self) -> None:
with self.assertRaises(ValueError):
maintenance._validate_windows(rollup_days=0, retention_days=30)
with self.assertRaises(ValueError):
maintenance._validate_windows(rollup_days=7, retention_days=2)
def test_schema_defines_rollup_table_and_rls(self) -> None:
from pathlib import Path
root = Path(__file__).resolve().parents[3]
schema = (root / "infra" / "db" / "init" / "05_runtime_auth.sql").read_text(
encoding="utf-8"
)
self.assertIn("CREATE TABLE IF NOT EXISTS app.admin_health_daily_rollup", schema)
self.assertIn("PRIMARY KEY (rollup_date, environment, engine_mode, service_key)", schema)
self.assertIn("last_down_at TIMESTAMPTZ", schema)
self.assertIn("CREATE POLICY p_admin_health_daily_rollup_select", schema)
self.assertIn("CREATE POLICY p_admin_health_daily_rollup_update", schema)
self.assertIn("CREATE POLICY p_admin_health_event_delete", schema)
self.assertNotIn("CREATE POLICY p_admin_health_daily_rollup_delete", schema)