"""Test-owned launcher: real backend + real runtime image with a stalling model. Used by the backend-crash / restart-reconciliation check. Confluence is the scripted transport; the model stalls so a container stays alive while the backend process is killed. """ from __future__ import annotations import asyncio import os from pathlib import Path import uvicorn from backend.app import create_app from backend.artifacts import ArtifactStore from backend.model import FakeModelAdapter from backend.settings import Settings from tests.integration.conftest import APPROVED_ORIGIN, RUNTIME_IMAGE, make_confluence_factory class StallingModel(FakeModelAdapter): async def complete(self, messages, tools, system_instruction, provider_state_meta=None): await asyncio.sleep(600) raise AssertionError("unreachable") def main() -> None: settings = Settings( runtime_image=RUNTIME_IMAGE, approved_confluence_origins=[APPROVED_ORIGIN], container_label_value=os.environ["CW_LABEL_VALUE"], artifact_storage_dir=Path(os.environ["CW_ARTIFACT_DIR"]), query_timeout_seconds=170.0, ) app = create_app( settings=settings, artifact_store=ArtifactStore(settings.artifact_storage_dir), model_adapter=StallingModel(), confluence_client_factory=make_confluence_factory(), ) uvicorn.run(app, host="127.0.0.1", port=int(os.environ["CW_DEV_PORT"]), workers=1, log_level="warning") if __name__ == "__main__": main()