"""M16 bounded soak. A realistic mixed workload held for a bounded period, measuring what actually drifts: latency distribution, cold versus warm execution, memory, GPU, database growth, queue depth, leases and orphaned work. Every number reported here is measured; nothing is extrapolated from a short run. The workload deliberately mixes bursts, steady state and idle periods. A soak that only hammers never exercises the keep-warm and unload paths, and a soak that only idles never exercises admission control. Production is read, never mutated: no promotion, no alias change, no external workload is touched. The only writes are gateway requests through a disposable LAB client and the operational polls the platform already performs for itself. python scripts/m16_soak.py --minutes 45 --report soak.json """ from __future__ import annotations import argparse import json import os import random import socket import statistics import subprocess # noqa: S404 - fixed argv container inspection, never a shell import sys import threading import time import urllib.error import urllib.parse import urllib.request from collections import Counter from dataclasses import dataclass, field from datetime import UTC, datetime from pathlib import Path from typing import Any from sqlalchemy import create_engine, text from sqlalchemy.orm import Session sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "backend" / "src")) from modelforge_api.services.invariants import ( # noqa: E402 InvariantStatus, check_invariants, ) DEFAULT_BASE_URL = "http://127.0.0.1:8000" DEFAULT_DATABASE_URL = os.getenv("MODELFORGE_RUNTIME_DATABASE_URL") SENTENCES = [ "ModelForge binds applications to capabilities rather than to model paths.", "A verified backup is the only backup that counts as a recovery point.", "Stale telemetry must never be presented as present-day truth.", "Every production promotion carries evidence from local validation.", "Downloaded model repositories stay untrusted until supply-chain checks complete.", "The scheduler refuses unsafe work instead of risking an out-of-memory failure.", "Recovery reconciliation clears current truth and re-measures it.", "An embedding-space change never silently reuses incompatible vectors.", ] @dataclass class Sample: at: float kind: str ok: bool status: int latency_ms: float detail: dict[str, Any] = field(default_factory=dict) @dataclass class SoakState: samples: list[Sample] = field(default_factory=list) lock: threading.Lock = field(default_factory=threading.Lock) stop: threading.Event = field(default_factory=threading.Event) def record(self, sample: Sample) -> None: with self.lock: self.samples.append(sample) def docker(*args: str) -> str: try: completed = subprocess.run( # noqa: S603 - fixed argv, no shell ["docker", *args], # noqa: S607 capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=60, check=False, ) except (OSError, subprocess.TimeoutExpired): return "" return (completed.stdout or "").strip() def container_stats(names: list[str]) -> dict[str, dict[str, Any]]: """Point-in-time RSS and CPU per container, read from the runtime rather than guessed.""" raw = docker( "stats", "--no-stream", "--format", "{{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}\t{{.PIDs}}", *names, ) result: dict[str, dict[str, Any]] = {} for line in raw.splitlines(): parts = line.split("\t") if len(parts) != 4: continue name, memory, cpu, pids = parts used = memory.split("/")[0].strip() result[name] = {"memory": used, "cpu_percent": cpu.strip(), "pids": pids.strip()} return result def restart_counts(names: list[str]) -> dict[str, int]: counts: dict[str, int] = {} for name in names: value = docker("inspect", "--format", "{{.RestartCount}}", name) counts[name] = int(value) if value.isdigit() else -1 return counts def http( url: str, *, token: str | None = None, bearer: str | None = None, method: str = "GET", payload: dict[str, Any] | None = None, timeout: float = 180.0, ) -> tuple[bool, int, float, dict[str, Any]]: body = json.dumps(payload).encode() if payload is not None else None request = urllib.request.Request(url, data=body, method=method) # noqa: S310 - fixed scheme if token: request.add_header("X-ModelForge-Admin-Token", token) if bearer: request.add_header("Authorization", f"Bearer {bearer}") if body is not None: request.add_header("Content-Type", "application/json") started = time.perf_counter() try: with urllib.request.urlopen(request, timeout=timeout) as response: # noqa: S310 raw = response.read() elapsed = (time.perf_counter() - started) * 1000 try: decoded = json.loads(raw.decode("utf-8")) except (UnicodeDecodeError, json.JSONDecodeError): decoded = {} return True, response.status, elapsed, decoded if isinstance(decoded, dict) else {} except urllib.error.HTTPError as error: elapsed = (time.perf_counter() - started) * 1000 try: decoded = json.loads(error.read().decode("utf-8")) except Exception: # noqa: BLE001 - an unreadable error body is still an error decoded = {} return False, error.code, elapsed, decoded if isinstance(decoded, dict) else {} except (urllib.error.URLError, TimeoutError, OSError) as error: elapsed = (time.perf_counter() - started) * 1000 return False, 0, elapsed, {"transport_error": type(error).__name__} # The soak reports latency percentiles, so the client-side floor has to be negligible before any # of them mean anything. A first run measured a p50 of two seconds on every route including # /health/live; the cause was the harness resolving "localhost" to ::1 on Windows and waiting out # the connect timeout before falling back to IPv4. That inflated every percentile by a constant # ~2,045 ms of client cost and said nothing about the platform. Measure the floor and refuse rather # than publish a number that is mostly the measuring instrument. MAX_CONNECT_FLOOR_MS = 100.0 def connect_floor_ms(base_url: str, samples: int = 7) -> float: """Median TCP connect time to the target, excluding anything the platform does.""" parsed = urllib.parse.urlparse(base_url) host = parsed.hostname or "127.0.0.1" port = parsed.port or (443 if parsed.scheme == "https" else 80) timings = [] for _ in range(samples): started = time.perf_counter() try: connection = socket.create_connection((host, port), timeout=10) except OSError: return float("inf") connection.close() timings.append((time.perf_counter() - started) * 1000) return statistics.median(timings) # --------------------------------------------------------------------- workers def gateway_worker( state: SoakState, base_url: str, secret: str, rng: random.Random, worker_id: int ) -> None: """Real capability traffic with bursts, steady state and idle gaps.""" while not state.stop.is_set(): phase = rng.choices(["burst", "steady", "idle"], weights=[2, 5, 3])[0] if phase == "idle": state.stop.wait(rng.uniform(8, 25)) continue count = rng.randint(3, 6) if phase == "burst" else 1 for _ in range(count): if state.stop.is_set(): return batch = [rng.choice(SENTENCES) for _ in range(rng.randint(1, 4))] ok, status, latency, body = http( f"{base_url}/api/v1/capabilities/rag.embedding@1/invoke", bearer=secret, method="POST", payload={"input": batch}, ) execution = body.get("execution") or {} timings = execution.get("timings") or {} state.record( Sample( at=time.time(), kind="gateway.rag.embedding", ok=ok, status=status, latency_ms=latency, detail={ "cold": bool(execution.get("cold")), "residency": execution.get("residency"), "queue_ms": timings.get("queue_ms"), "inference_ms": timings.get("inference_ms"), "load_ms": timings.get("load_ms"), "worker": worker_id, "batch": len(batch), "code": (body.get("error") or {}).get("code") if not ok else None, }, ) ) if phase == "burst": state.stop.wait(rng.uniform(0.05, 0.4)) else: state.stop.wait(rng.uniform(1.5, 5.0)) READ_ROUTES = [ ("registry.models", "/api/v1/models", False), ("registry.projects", "/api/v1/projects", False), ("hardware", "/api/v1/hardware", False), ("health.ready", "/api/v1/health/ready", False), ("operations.overview", "/api/v1/admin/operations/overview", True), ("operations.alerts", "/api/v1/admin/operations/alerts?limit=50", True), ("lifecycle.operations", "/api/v1/admin/lifecycle/operations", True), ("migration.plans", "/api/v1/admin/migrations/plans", True), ("recovery.dashboard", "/api/v1/admin/recovery/dashboard", True), ("recovery.backups", "/api/v1/admin/recovery/backups?limit=20", True), ] def read_worker(state: SoakState, base_url: str, token: str, rng: random.Random) -> None: while not state.stop.is_set(): kind, path, needs_token = rng.choice(READ_ROUTES) ok, status, latency, _ = http( f"{base_url}{path}", token=token if needs_token else None, timeout=60.0 ) state.record(Sample(at=time.time(), kind=kind, ok=ok, status=status, latency_ms=latency)) state.stop.wait(rng.uniform(0.5, 3.0)) def background_worker(state: SoakState, base_url: str, token: str) -> None: """The operational work the platform performs for itself, driven at a bounded rate.""" while not state.stop.is_set(): for kind, path in ( ("ops.capacity_collect", "/api/v1/admin/operations/capacity/collect"), ("ops.slo_evaluate", "/api/v1/admin/operations/slo-evaluations/run"), ("ops.alert_evaluate", "/api/v1/admin/operations/alerts/evaluate"), ): if state.stop.is_set(): return ok, status, latency, _ = http( f"{base_url}{path}", token=token, method="POST", timeout=120.0 ) state.record( Sample(at=time.time(), kind=kind, ok=ok, status=status, latency_ms=latency) ) state.stop.wait(60) # --------------------------------------------------------------------- measurement def resource_snapshot(database_url: str, containers: list[str]) -> dict[str, Any]: engine = create_engine(database_url, pool_pre_ping=True) try: with Session(engine) as session: counts = { table: int( session.execute(text(f"select count(*) from {table}")).scalar_one() # noqa: S608 ) for table in ( "audit_events", "gateway_requests", "serving_jobs", "serving_gpu_leases", "slo_evaluations", "capacity_snapshots", "alert_history_events", "operational_alerts", "placement_plans", "hardware_inventory_runs", ) } active_leases = int( session.execute( text( "select count(*) from serving_gpu_leases " "where released_at is null and state in " "('pending','granted','active','held')" ) ).scalar_one() ) in_flight = int( session.execute( text( "select count(*) from serving_jobs " "where status in ('queued','leased','running')" ) ).scalar_one() ) residency = int( session.execute( text( "select count(*) from residency_allocations " "where state in ('loading','resident','unloading')" ) ).scalar_one() ) connections = int( session.execute( text( "select count(*) from pg_stat_activity " "where datname = current_database()" ) ).scalar_one() ) gpu = session.execute( text( "select a.name, t.used_vram_bytes, t.free_vram_bytes, " "t.gpu_utilization_percent, t.observed_at " "from accelerator_telemetry_latest t " "join accelerators a on a.id = t.accelerator_id" ) ).all() scheduler = session.execute( text( "select pressure_state, recovery_candidate, last_observed_at " "from scheduler_accelerator_states" ) ).all() capacity = session.execute( text( "select gpu_external_bytes, gpu_schedulable_bytes, gpu_managed_resident_bytes, " "pressure_state, observed_at from capacity_snapshots " "order by observed_at desc limit 1" ) ).first() finally: engine.dispose() return { "observed_at": datetime.now(UTC).isoformat(), "row_counts": counts, "active_leases": active_leases, "serving_jobs_in_flight": in_flight, "residency_allocations": residency, "database_connections": connections, "gpu": [ { "name": name, "used_vram_bytes": used, "free_vram_bytes": free, "utilisation_percent": util, "observed_at": observed.isoformat() if observed else None, } for name, used, free, util, observed in gpu ], "scheduler": [ { "pressure_state": pressure, "recovery_candidate": bool(candidate), "last_observed_at": observed.isoformat() if observed else None, } for pressure, candidate, observed in scheduler ], "latest_capacity": ( { "gpu_external_bytes": capacity[0], "gpu_schedulable_bytes": capacity[1], "gpu_managed_resident_bytes": capacity[2], "pressure_state": capacity[3], "observed_at": capacity[4].isoformat() if capacity[4] else None, } if capacity else None ), "containers": container_stats(containers), "restart_counts": restart_counts(containers), } def percentile(values: list[float], fraction: float) -> float | None: if not values: return None ordered = sorted(values) index = min(len(ordered) - 1, max(0, round(fraction * (len(ordered) - 1)))) return round(ordered[index], 3) def summarise(samples: list[Sample]) -> dict[str, Any]: by_kind: dict[str, list[Sample]] = {} for sample in samples: by_kind.setdefault(sample.kind, []).append(sample) result: dict[str, Any] = {} for kind, items in sorted(by_kind.items()): latencies = [item.latency_ms for item in items if item.ok] statuses = Counter(item.status for item in items) failures = [item for item in items if not item.ok] capacity = [ item for item in failures if item.status in (429, 503) or item.detail.get("code") in ("QUEUE_FULL", "RATE_LIMITED") ] internal = [item for item in failures if item.status >= 500 or item.status == 0] entry: dict[str, Any] = { "requests": len(items), "succeeded": len(items) - len(failures), "capacity_rejected": len(capacity), "internal_errors": len(internal), "statuses": dict(sorted(statuses.items())), "p50_ms": percentile(latencies, 0.50), "p95_ms": percentile(latencies, 0.95), "p99_ms": percentile(latencies, 0.99), "mean_ms": round(statistics.fmean(latencies), 3) if latencies else None, "max_ms": round(max(latencies), 3) if latencies else None, } if kind.startswith("gateway."): cold = [item for item in items if item.ok and item.detail.get("cold")] warm = [item for item in items if item.ok and not item.detail.get("cold")] queue = [ float(item.detail["queue_ms"]) for item in items if item.ok and item.detail.get("queue_ms") is not None ] inference = [ float(item.detail["inference_ms"]) for item in items if item.ok and item.detail.get("inference_ms") is not None ] entry["cold_starts"] = len(cold) entry["warm_invocations"] = len(warm) entry["queue_p95_ms"] = percentile(queue, 0.95) entry["inference_p50_ms"] = percentile(inference, 0.50) entry["inference_p95_ms"] = percentile(inference, 0.95) entry["failure_codes"] = dict( Counter( item.detail.get("code") for item in failures if item.detail.get("code") ) ) result[kind] = entry return result # --------------------------------------------------------------------- runner def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--base-url", default=DEFAULT_BASE_URL) parser.add_argument("--database-url", default=DEFAULT_DATABASE_URL) parser.add_argument("--token", default=None) parser.add_argument("--secret", default=None, help="gateway client secret") parser.add_argument("--minutes", type=float, default=45.0) parser.add_argument("--gateway-workers", type=int, default=3) parser.add_argument("--read-workers", type=int, default=2) parser.add_argument("--seed", type=int, default=20260827) parser.add_argument("--report", default=None) parser.add_argument("--progress-seconds", type=float, default=120.0) args = parser.parse_args(argv) if not args.database_url: parser.error( "--database-url or MODELFORGE_RUNTIME_DATABASE_URL is required " "(use the non-owner runtime role)" ) root = Path(__file__).resolve().parents[1] token = args.token if not token and (root / ".env").is_file(): for line in (root / ".env").read_text("utf-8").splitlines(): if line.startswith("MODELFORGE_OPERATOR_API_KEY="): token = line.split("=", 1)[1].strip() if not token: parser.error("an operator API key is required") if not args.secret: parser.error("a gateway client secret is required") containers = [ "modelforge-api-1", "modelforge-postgres-1", "modelforge-redis-1", "modelforge-web-1", ] floor = connect_floor_ms(args.base_url) print(f"client connect floor: {floor:.1f} ms", flush=True) if floor > MAX_CONNECT_FLOOR_MS: print( f"refusing to soak: the client connect floor is {floor:.1f} ms, above the " f"{MAX_CONNECT_FLOOR_MS:.0f} ms budget. Every latency percentile would be dominated " "by the harness rather than the platform. Use an address that resolves directly " "(127.0.0.1 rather than localhost).", flush=True, ) return 2 print(f"soak: {args.minutes:.1f} minutes, seed {args.seed}", flush=True) before = resource_snapshot(args.database_url, containers) engine = create_engine(args.database_url, pool_pre_ping=True) with Session(engine) as session: baseline = check_invariants(session) engine.dispose() if baseline.violated: print("refusing to soak: invariants are already violated", flush=True) return 2 state = SoakState() threads: list[threading.Thread] = [] for index in range(args.gateway_workers): thread = threading.Thread( target=gateway_worker, args=(state, args.base_url, args.secret, random.Random(args.seed + index), index), daemon=True, ) threads.append(thread) for index in range(args.read_workers): thread = threading.Thread( target=read_worker, args=(state, args.base_url, token, random.Random(args.seed + 100 + index)), daemon=True, ) threads.append(thread) threads.append( threading.Thread( target=background_worker, args=(state, args.base_url, token), daemon=True ) ) started = time.time() deadline = started + args.minutes * 60 for thread in threads: thread.start() invariant_checks: list[dict[str, Any]] = [] progress: list[dict[str, Any]] = [] try: next_progress = started + args.progress_seconds while time.time() < deadline: time.sleep(2) if time.time() >= next_progress: next_progress = time.time() + args.progress_seconds engine = create_engine(args.database_url, pool_pre_ping=True) with Session(engine) as session: report = check_invariants(session) engine.dispose() with state.lock: total = len(state.samples) gateway = sum( 1 for item in state.samples if item.kind.startswith("gateway.") ) failed = sum(1 for item in state.samples if not item.ok) invariant_checks.append( { "at": datetime.now(UTC).isoformat(), "violated": report.violated, "violations": [ item.key for item in report.results if item.status is InvariantStatus.VIOLATED ], } ) elapsed = (time.time() - started) / 60 entry = { "minutes": round(elapsed, 1), "requests": total, "gateway": gateway, "failed": failed, "invariants_violated": report.violated, } progress.append(entry) print(f" {json.dumps(entry)}", flush=True) if report.violated: print(" invariant violated; stopping the soak early", flush=True) break except KeyboardInterrupt: print(" interrupted; reporting partial evidence", flush=True) finally: state.stop.set() for thread in threads: thread.join(timeout=240) duration = time.time() - started after = resource_snapshot(args.database_url, containers) engine = create_engine(args.database_url, pool_pre_ping=True) with Session(engine) as session: final = check_invariants(session) engine.dispose() with state.lock: samples = list(state.samples) drift = { table: after["row_counts"][table] - before["row_counts"][table] for table in before["row_counts"] } report = { "generated_at": datetime.now(UTC).isoformat(), "seed": args.seed, "client_connect_floor_ms": round(floor, 3), "requested_minutes": args.minutes, "actual_duration_seconds": round(duration, 1), "gateway_workers": args.gateway_workers, "read_workers": args.read_workers, "total_requests": len(samples), "total_failures": sum(1 for item in samples if not item.ok), "by_kind": summarise(samples), "resources_before": before, "resources_after": after, "row_growth": drift, "invariant_checks": invariant_checks, "invariants_final": { "checked": final.checked, "violated": final.violated, "violations": [ {"key": item.key, "examples": item.violations} for item in final.results if item.status is InvariantStatus.VIOLATED ], }, "progress": progress, } print(json.dumps({key: report[key] for key in ("actual_duration_seconds", "total_requests", "total_failures")}, indent=2)) print(json.dumps(report["by_kind"], indent=2)) print("row growth:", json.dumps(drift)) print("leases after:", after["active_leases"], "| jobs in flight:", after["serving_jobs_in_flight"]) print("invariants:", final.holding, "/", final.checked, "hold") if args.report: Path(args.report).write_text(json.dumps(report, indent=2), encoding="utf-8") print(f"report written to {args.report}") return 0 if final.violated == 0 else 1 if __name__ == "__main__": raise SystemExit(main())