From aecf831f43d751811dbc6579962d4203bb48fc33 Mon Sep 17 00:00:00 2001 From: Nora Date: Tue, 23 Jun 2026 17:55:41 -0600 Subject: [PATCH] test(sp23): live bring-up test uses override + skips on port conflict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two test-only fixes after running test_compose_up_brings_up_healthy_stack on a non-CI host for the first time: 1. The test only used -f docker-compose.yml, but the production compose points secrets at /etc/cyclone/secrets/{db.key,admin_username, admin_pw} — which requires sudo to create. The test then failed with 'bind source path does not exist: /etc/cyclone/secrets/db.key' even though the stack itself was correctly configured. Fix: if docker-compose.override.yml exists at the repo root, the test uses `-f compose.yml -f override.yml` so secrets come from /tmp/cyclone-test-secrets/. Production CI skips the override. 2. The stack publishes host port 8080. If another local service (e.g. nocodb on a dev workstation) is bound to 8080, the test fails with 'Bind for 0.0.0.0:8080 failed: port is already allocated' — which is a confusing failure mode for what's actually a host-state issue, not a Cyclone bug. Fix: probe 127.0.0.1:8080 before bringing up; if it's already bound by something else, skip the test with a clear 'rerun on a fresh host' message. CI workers don't have this conflict. Verified end-to-end: - With port 8080 free: full stack comes up (healthy), pytest passes. - With port 8080 bound: pytest skips cleanly with the message above. --- backend/tests/test_docker.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/backend/tests/test_docker.py b/backend/tests/test_docker.py index 8d8f16e..48b040b 100644 --- a/backend/tests/test_docker.py +++ b/backend/tests/test_docker.py @@ -192,9 +192,25 @@ def test_frontend_dockerfile_parses(): def test_compose_up_brings_up_healthy_stack(): """Gated live test — only runs when DOCKER_TESTS=1 and docker compose is available. Builds + brings up the full stack and waits up to 120s - for the backend healthcheck to come up healthy.""" + for the backend healthcheck to come up healthy. Uses the override + file (docker-compose.override.yml) when present so the test doesn't + require sudo to create /etc/cyclone/secrets/.""" + # The stack publishes host port 8080. If something else on this host + # is already using it (e.g. nocodb on a dev box) the test can't run + # here but will run cleanly on a fresh CI worker. Skip with a clear + # message rather than failing with a confusing port-bind error. + import socket + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + if s.connect_ex(("127.0.0.1", 8080)) == 0: + pytest.skip("host port 8080 already bound — rerun on a fresh host") + + override = REPO_ROOT / "docker-compose.override.yml" + cmd_base = ["docker", "compose", "-f", str(COMPOSE_FILE)] + if override.exists(): + cmd_base.extend(["-f", str(override)]) subprocess.run( - ["docker", "compose", "-f", str(COMPOSE_FILE), "up", "-d", "--build"], + cmd_base + ["up", "-d", "--build"], check=True, cwd=REPO_ROOT, ) @@ -203,15 +219,7 @@ def test_compose_up_brings_up_healthy_stack(): for _ in range(60): ps = subprocess.run( - [ - "docker", - "compose", - "-f", - str(COMPOSE_FILE), - "ps", - "--format", - "json", - ], + cmd_base + ["ps", "--format", "json"], capture_output=True, text=True, cwd=REPO_ROOT, @@ -222,7 +230,7 @@ def test_compose_up_brings_up_healthy_stack(): pytest.fail("compose stack did not become healthy within 120s") finally: subprocess.run( - ["docker", "compose", "-f", str(COMPOSE_FILE), "down", "-v"], + cmd_base + ["down", "-v"], check=False, cwd=REPO_ROOT, )