From 51ba4e41fff86b9be7f53b34a5c547c63b70b1f8 Mon Sep 17 00:00:00 2001 From: Mateusz Konopelski Date: Thu, 30 Jul 2026 15:34:50 +0200 Subject: [PATCH] Pin the launch runtime in TUI docker-gate tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The startup gate branches on the backend runtime (docker -> StartContainersScreen, process -> StartBackendProcessScreen), but the container-path tests never pinned it, so they read the developer's own BACKEND_RUNTIME or saved choice. On a machine configured for process — possible since the sandbox-without-docker work — three of them asserted the wrong branch and failed. Adds a _docker_runtime() helper next to the existing _gate_ready(), marking the runtime explicitly configured (so the infer-from-what's-running block, which probes the real host for a backend process, is skipped) and resolving it to docker. Applied to all five container-path tests, including the two that only passed by accident. Verified green with BACKEND_RUNTIME unset, =process and =docker. --- mcp_server/tests/test_tui_app.py | 36 +++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/mcp_server/tests/test_tui_app.py b/mcp_server/tests/test_tui_app.py index 3f94156..592f8f9 100644 --- a/mcp_server/tests/test_tui_app.py +++ b/mcp_server/tests/test_tui_app.py @@ -360,6 +360,24 @@ def _gate_ready(): ) +def _docker_runtime(): + """Pin the launch runtime to docker, explicitly configured rather than inferred. + + The gate branches on the runtime (docker → StartContainersScreen, process → + StartBackendProcessScreen), so container-path tests must pin it: otherwise they read + the developer's own BACKEND_RUNTIME/saved choice and assert the wrong branch. Marking + it configured also skips the infer-from-what's-running block, which would consult the + real host for a backend process. + """ + return ( + patch("tui.app.backend_runtime_is_configured", return_value=True), + patch( + "tui.app.resolve_backend_runtime", + return_value=tui_app.local_env.BackendRuntime.DOCKER, + ), + ) + + class TestStartupGate: @pytest.mark.asyncio async def test_ready_gen_lands_on_dashboard(self): @@ -408,9 +426,11 @@ async def test_client_setup_skip_proceeds_to_sessions(self): @pytest.mark.asyncio async def test_containers_down_prompts_start(self): + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), - patch("tui.app.backend_runtime_is_configured", return_value=True), patch("tui.app.local_env.containers_running", return_value=False), ): app = tui_app.SpecFlowTUI(root=Path("/tmp/x"), generation_id=None, poll_interval=999) @@ -420,9 +440,11 @@ async def test_containers_down_prompts_start(self): @pytest.mark.asyncio async def test_start_no_quits_app(self): + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), - patch("tui.app.backend_runtime_is_configured", return_value=True), patch("tui.app.local_env.containers_running", return_value=False), ): app = tui_app.SpecFlowTUI(root=Path("/tmp/x"), generation_id=None, poll_interval=999) @@ -434,9 +456,11 @@ async def test_start_no_quits_app(self): @pytest.mark.asyncio async def test_start_yes_starts_then_proceeds(self): + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), - patch("tui.app.backend_runtime_is_configured", return_value=True), patch("tui.app.local_env.containers_running", return_value=False), patch("tui.app.local_env.start_containers", new=AsyncMock(return_value=0)), patch("tui.app.local_env.wait_backend_ready", new=AsyncMock(return_value=True)), @@ -454,7 +478,10 @@ async def test_start_yes_starts_then_proceeds(self): async def test_containers_up_but_backend_not_ready_says_unhealthy_not_down(self): # Containers running + backend not ready → the gate must not claim the # containers aren't running; it shows the "backend isn't healthy" prompt. + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), patch("tui.app.local_env.containers_running", return_value=True), patch("tui.app.local_env.backend_ready", new=AsyncMock(return_value=False)), @@ -476,7 +503,10 @@ async def test_backend_not_ready_retry_skips_compose_up(self): # In the up-but-not-ready path, retrying (y) re-polls readiness without # re-running `docker compose up` (the containers are already up). start = AsyncMock(return_value=0) + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), patch("tui.app.local_env.containers_running", return_value=True), patch("tui.app.local_env.backend_ready", new=AsyncMock(return_value=False)),