R12: Fix readiness — stale/failed community_scheduler blocks ready

- Add 'ready = ready and healthy' for community_scheduler check
- Add 'ready = False' for community_scheduler exception path
- Add 3 unit tests: success=ready, stale=not_ready, failed=not_ready
- Monitoring now correctly reports community import health
This commit is contained in:
ik
2026-09-10 05:46:49 +07:00
parent 39f66481be
commit cc3b42eaf6
2 changed files with 68 additions and 1 deletions
+2
View File
@@ -78,7 +78,9 @@ def readiness_report(
"status": "ready" if healthy else ("stale" if stale else latest_community.status), "status": "ready" if healthy else ("stale" if stale else latest_community.status),
"last_started_at": started.isoformat(), "last_started_at": started.isoformat(),
} }
ready = ready and healthy
except Exception: except Exception:
components["community_scheduler"] = {"status": "unknown"} components["community_scheduler"] = {"status": "unknown"}
ready = False
return ready, components return ready, components
+66 -1
View File
@@ -6,7 +6,7 @@ from sqlalchemy import create_engine
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.database import Base from app.database import Base
from app.models import ImportStatus, OfficialRecordImport from app.models import ImportStatus, CommunityImportRun, OfficialRecordImport
from app.readiness import readiness_report from app.readiness import readiness_report
@@ -72,3 +72,68 @@ def test_unavailable_storage_and_stale_import_fail_readiness() -> None:
assert ready is False assert ready is False
assert components["minio"]["status"] == "unavailable" assert components["minio"]["status"] == "unavailable"
assert components["official_import"]["status"] == "stale" assert components["official_import"]["status"] == "stale"
def test_community_scheduler_success_does_not_block_readiness() -> None:
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
now = datetime.now(timezone.utc)
with Session(engine) as session:
session.add(CommunityImportRun(
source_system="rf4db",
started_at=now - timedelta(minutes=30),
status="success",
source_url="fixture://rf4db",
rows_seen=5, rows_created=5, rows_updated=0, error_summary=None,
))
session.commit()
ready, components = readiness_report(
session, AvailableStorage(), import_required=False,
import_interval_seconds=3600, community_import_interval_seconds=1800, now=now,
)
assert ready is True
assert components["community_scheduler"]["status"] == "ready"
def test_community_scheduler_stale_or_failed_blocks_readiness() -> None:
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
now = datetime.now(timezone.utc)
with Session(engine) as session:
# Stale run
session.add(CommunityImportRun(
source_system="rf4db",
started_at=now - timedelta(hours=2),
status="success",
source_url="fixture://rf4db",
rows_seen=5, rows_created=5, rows_updated=0, error_summary=None,
))
session.commit()
ready, components = readiness_report(
session, AvailableStorage(), import_required=False,
import_interval_seconds=3600, community_import_interval_seconds=1800, now=now,
)
assert ready is False
assert components["community_scheduler"]["status"] == "stale"
def test_community_scheduler_failed_status_blocks_readiness() -> None:
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
now = datetime.now(timezone.utc)
with Session(engine) as session:
session.add(CommunityImportRun(
source_system="rf4db",
started_at=now - timedelta(minutes=30),
status="failed",
source_url="fixture://rf4db",
rows_seen=0, rows_created=0, rows_updated=0,
error_summary="ConnectionError",
))
session.commit()
ready, components = readiness_report(
session, AvailableStorage(), import_required=False,
import_interval_seconds=3600, community_import_interval_seconds=1800, now=now,
)
assert ready is False
assert components["community_scheduler"]["status"] == "failed"