Initial import with GitLab CI/CD and registry deploy flow
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import create_engine, inspect, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from scripts.event_bus_smoke import run_smoke_check
|
||||
from services.shared.db import DATABASE_URL, _normalize_database_url
|
||||
from services.shared.sql_models import EventOutboxRow
|
||||
|
||||
|
||||
def _engine_for(database_url: str | None):
|
||||
return create_engine(_normalize_database_url(database_url or DATABASE_URL), future=True)
|
||||
|
||||
|
||||
def _parse_iso(value: str | None) -> datetime | None:
|
||||
if not value:
|
||||
return None
|
||||
try:
|
||||
return datetime.fromisoformat(value.replace("Z", "+00:00"))
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def evaluate_track8(
|
||||
*,
|
||||
database_url: str | None = None,
|
||||
require_bus_enabled: bool = False,
|
||||
base_url: str | None = None,
|
||||
failed_age_seconds: int = 300,
|
||||
) -> list[str]:
|
||||
issues: list[str] = []
|
||||
engine = _engine_for(database_url)
|
||||
inspector = inspect(engine)
|
||||
tables = set(inspector.get_table_names())
|
||||
required_tables = {"event_outbox", "event_inbox", "reporting_event_log"}
|
||||
missing = sorted(required_tables - tables)
|
||||
if missing:
|
||||
issues.append(f"Missing required tables: {', '.join(missing)}")
|
||||
|
||||
if require_bus_enabled and os.getenv("EVENT_BUS_ENABLED", "0").strip() not in {"1", "true", "yes", "on"}:
|
||||
issues.append("EVENT_BUS_ENABLED is not enabled in the current environment")
|
||||
|
||||
with Session(engine) as session:
|
||||
failed_rows = session.execute(
|
||||
select(EventOutboxRow).where(EventOutboxRow.status == "failed")
|
||||
).scalars().all()
|
||||
stale_cutoff = datetime.now(timezone.utc) - timedelta(seconds=failed_age_seconds)
|
||||
stale_failed = [
|
||||
row for row in failed_rows if (_parse_iso(row.updated_at) or _parse_iso(row.created_at) or stale_cutoff) < stale_cutoff
|
||||
]
|
||||
if stale_failed:
|
||||
issues.append(f"Found {len(stale_failed)} failed outbox events older than {failed_age_seconds}s")
|
||||
|
||||
pending_rows = session.execute(
|
||||
select(EventOutboxRow).where(EventOutboxRow.status == "pending")
|
||||
).scalars().all()
|
||||
if len(pending_rows) > 500:
|
||||
issues.append(f"Outbox backlog too high: {len(pending_rows)} pending events")
|
||||
|
||||
if not (ROOT / "contracts" / "events" / "ivr.completed.json").exists():
|
||||
issues.append("Missing contracts/events/ivr.completed.json")
|
||||
|
||||
if base_url:
|
||||
smoke = run_smoke_check(base_url=base_url, database_url=database_url)
|
||||
if not smoke["passed"]:
|
||||
issues.append("Event bus smoke check failed")
|
||||
|
||||
return issues
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Validate Track 8 event-bus readiness.")
|
||||
parser.add_argument("--database-url", default=None)
|
||||
parser.add_argument("--require-bus-enabled", action="store_true")
|
||||
parser.add_argument("--base-url", default=None)
|
||||
parser.add_argument("--failed-age-seconds", type=int, default=300)
|
||||
args = parser.parse_args()
|
||||
|
||||
issues = evaluate_track8(
|
||||
database_url=args.database_url,
|
||||
require_bus_enabled=args.require_bus_enabled,
|
||||
base_url=args.base_url,
|
||||
failed_age_seconds=args.failed_age_seconds,
|
||||
)
|
||||
if issues:
|
||||
print("[FAIL] Track 8 validation failed:")
|
||||
for issue in issues:
|
||||
print(f"- {issue}")
|
||||
raise SystemExit(1)
|
||||
print("[PASS] Track 8 validation checks passed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user