"""Integration: retention windows read from Settings reach the pruning (#5155).""" from __future__ import annotations import asyncio import os import uuid from datetime import datetime, timedelta, timezone import pytest pytestmark = pytest.mark.integration @pytest.fixture def app(): if not os.environ.get("STEWARD_DATABASE_URL"): pytest.skip("needs Postgres") from steward.app import create_app return create_app(testing=False) def test_the_audit_window_comes_from_settings(app): from sqlalchemy import text from steward.core.cleanup import run_cleanup from steward.core.settings import get_setting, set_setting from steward.models.audit import AuditEvent now = datetime.now(timezone.utc) tag = f"test.cleanup.{uuid.uuid4().hex[:8]}" async def _go(): async with app.db_sessionmaker() as s: async with s.begin(): await set_setting(s, "audit.retention_days", 30) s.add(AuditEvent(action=tag, entity_id="old", timestamp=now - timedelta(days=40))) s.add(AuditEvent(action=tag, entity_id="new", timestamp=now - timedelta(days=20))) try: done = await run_cleanup(app) finally: async with app.db_sessionmaker() as s: async with s.begin(): await set_setting(s, "audit.retention_days", 365) async with app.db_sessionmaker() as s: kept = [r[0] for r in (await s.execute(text( "SELECT entity_id FROM audit_events WHERE action = :a"), {"a": tag})).all()] return kept, done, await get_setting(s, "cleanup.last_run") kept, done, stored = asyncio.run(_go()) assert kept == ["new"] # What it did is kept for Settings → System (#5469), each pass by name. counts = dict(done["removed"]) assert counts["audit_events: older than 30 days"] >= 1 assert "plugin_metrics: raw samples rolled into hourly" in counts and done["secs"] >= 0 assert stored == done def test_the_chart_seam_follows_the_raw_metrics_setting(app): # With raw_days 1, a range two days back reads the hourly rollup there and # not the raw sample beside it; at the default 7 it would read the raw one. from steward.core import metric_series from steward.core.settings import set_setting from steward.models.metrics import PluginMetric, PluginMetricHourly now = datetime.now(timezone.utc) two_days = (now - timedelta(days=2)).replace(minute=0, second=0, microsecond=0) res = f"seam-{uuid.uuid4().hex[:8]}" async def _go(): async with app.db_sessionmaker() as s: async with s.begin(): await set_setting(s, "metrics.retention.raw_days", 1) s.add(PluginMetricHourly(source_module="test", resource_name=res, metric_name="cpu_pct", bucket=two_days, value_avg=10.0, value_max=10.0, sample_count=1)) s.add(PluginMetric(source_module="test", resource_name=res, metric_name="cpu_pct", value=99.0, recorded_at=two_days)) try: async with app.db_sessionmaker() as s: return await metric_series.points(s, "test", res, "cpu_pct", now - timedelta(days=3)) finally: async with app.db_sessionmaker() as s: async with s.begin(): await set_setting(s, "metrics.retention.raw_days", 7) assert [v for _, v in asyncio.run(_go())] == [10.0] def test_table_sizes_come_from_the_catalog_largest_first(app): """Settings → System's storage figures (#5469), read against real Postgres.""" from steward.core.health import TABLES_SHOWN, table_sizes async def _go(): async with app.db_sessionmaker() as s: return await table_sizes(s) got = asyncio.run(_go()) sizes = [t["bytes"] for t in got["tables"]] assert sizes == sorted(sizes, reverse=True) and len(sizes) <= TABLES_SHOWN names = {t["name"] for t in got["tables"]} assert got["rest"]["count"] or "audit_events" in names # the schema's own tables assert got["total"] >= sum(sizes) + got["rest"]["bytes"] > 0