From 6dbd3d691c86e5e62d6b278a8a9e1e327346061a Mon Sep 17 00:00:00 2001 From: Jarvis Date: Sun, 21 Jun 2026 15:58:35 -0500 Subject: [PATCH] =?UTF-8?q?test(fleet):=20hermetic=20heartbeat=20tests=20?= =?UTF-8?q?=E2=80=94=20temp=20run-dir=20+=20no=20leaked=20sidecars?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests 3, 4, 5 previously returned synthetic pane PIDs (99999/99998/99997) from their fake list-panes shims but did not set MOSAIC_HEARTBEAT_RUN_DIR, causing the launcher to fall back to the real ~/.config/mosaic/fleet/run and potentially spawn a background sidecar against an arbitrary host PID. Fix: - list-panes in tests 3/4/5 now returns empty string → PANE_PID stays unset → no sidecar is spawned for tests where heartbeat is not under test. - MOSAIC_HEARTBEAT_RUN_DIR is exported to a per-test mktemp dir in each fake-tmux test (3, 4, 5) as defence-in-depth so even if the sidecar code path changes, it can never write to the real fleet run dir. - New temp dirs are registered in CLEANUP_DIRS so they are removed by the existing EXIT trap. - Tests 6 and 7 (the dedicated heartbeat tests) are unchanged: test 6 uses a real tmux pane PID + its own HB_RUN_DIR, test 7 intercepts via a fake setsid shim that captures args and exits immediately. - All 7 tests pass; verify-sanitized.sh passes; no stray sidecar processes or unexpected .hb files are written to ~/.config/mosaic/fleet/run. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01RMoEx7hfdFGjUiCHuN1RRi --- .../tools/fleet/test-start-agent-session.sh | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/mosaic/framework/tools/fleet/test-start-agent-session.sh b/packages/mosaic/framework/tools/fleet/test-start-agent-session.sh index df73747..11a4c3f 100755 --- a/packages/mosaic/framework/tools/fleet/test-start-agent-session.sh +++ b/packages/mosaic/framework/tools/fleet/test-start-agent-session.sh @@ -50,8 +50,10 @@ grep -qF 'already running' /tmp/mosaic-start-agent-idempotent.out || fail "dupli # - Intercepts 'new-session' calls and records its arguments to a file. # - For 'has-session' calls, exits 1 (session does not exist) so the script # proceeds to launch instead of printing "already running". -# - For 'list-panes' calls, returns a synthetic PID so the heartbeat sidecar -# path is exercised without needing a real tmux session. +# - For 'list-panes' calls, returns empty so PANE_PID stays unset and the +# heartbeat sidecar is NOT spawned (heartbeat is not the focus of this test; +# test 6 and 7 cover that path). This prevents any real-filesystem side +# effects or leaked background processes. # - For all other subcommands, exits 0. # # Assertions: @@ -62,7 +64,8 @@ grep -qF 'already running' /tmp/mosaic-start-agent-idempotent.out || fail "dupli FAKE_BIN=$(mktemp -d) FAKE_RUNTIME_BIN=$(mktemp -d) TMUX_ARGS_FILE=$(mktemp) -CLEANUP_DIRS+=("$FAKE_BIN" "$FAKE_RUNTIME_BIN") +HB_RUN_DIR3=$(mktemp -d) +CLEANUP_DIRS+=("$FAKE_BIN" "$FAKE_RUNTIME_BIN" "$HB_RUN_DIR3") # Write the fake tmux shim (uses only positional args, no sourced vars). cat > "$FAKE_BIN/tmux" </dev/null || true) @@ -118,7 +123,8 @@ echo "$all_args" | grep -qF "mosaic yolo pi --model openai-codex/gpt-5.5:high" | # ── Test 4: when no extra runtime-bin dirs exist, exec still appears ─────────── TMUX_ARGS_FILE2=$(mktemp) FAKE_BIN2=$(mktemp -d) -CLEANUP_DIRS+=("$FAKE_BIN2") +HB_RUN_DIR4=$(mktemp -d) +CLEANUP_DIRS+=("$FAKE_BIN2" "$HB_RUN_DIR4") cat > "$FAKE_BIN2/tmux" </dev/null || true) @@ -171,7 +179,8 @@ echo "$all_args4" | grep -qF "mosaic yolo pi" || fail "pane command does not inc TMUX_ARGS_FILE5=$(mktemp) FAKE_BIN5=$(mktemp -d) FAKE_RUNTIME_BIN5=$(mktemp -d) # this dir IS on the launcher's PATH below -CLEANUP_DIRS+=("$FAKE_BIN5" "$FAKE_RUNTIME_BIN5") +HB_RUN_DIR5=$(mktemp -d) +CLEANUP_DIRS+=("$FAKE_BIN5" "$FAKE_RUNTIME_BIN5" "$HB_RUN_DIR5") cat > "$FAKE_BIN5/tmux" </dev/null || true)