3e640f77
test: a cold --via proxy refuses and starts nothing
a73x 2026-08-28 19:53
Commit message
test/e2e_03_side.sh
| Old | New | ||
|---|---|---|---|
| @@ -4,12 +4,14 @@ | |||
| 4 | # assume and what it must register. | 4 | # assume and what it must register. |
| 5 | # tp1 runs its fixture in the BACKGROUND — the tear has to happen while the | 5 | # tp1 runs its fixture in the BACKGROUND — the tear has to happen while the |
| 6 | # script is mid-flight — so its pid is tracked and killed like a daemon's. | 6 | # script is mid-flight — so its pid is tracked and killed like a daemon's. |
| 7 | # M13 auto-start + stop. Two paths: the proxy arc's daemon is spawned BY | 7 | # M13 auto-start + stop. Two paths, and they no longer answer the same |
| 8 | # the proxy, the pty leg's by local mux under the M12 fixture. Both are | 8 | # way: the proxy arc's daemon is started BY HAND, because `muxd proxy` |
| 9 | # torn down by `muxd stop` — the verb under test is also the cleanup, and | 9 | # reads a box and may not create a session on it, while the pty leg's is |
| 10 | # the trap only backstops it. Neither daemon is a child of this shell, so | 10 | # still spawned by local mux under the M12 fixture. Both are torn down by |
| 11 | # each pid is read off the up-line its own spawner printed, which is the | 11 | # `muxd stop` — the verb under test is also the cleanup, and the trap only |
| 12 | # only handle that can never name a bystander. | 12 | # backstops it. Neither daemon is a child of this shell, so each pid is |
| 13 | # read off the up-line its own spawner printed, which is the only handle | ||
| 14 | # that can never name a bystander. | ||
| 13 | SOCK14="${TMPDIR:-/tmp}/muxd-e2e-astart-$$.sock" | 15 | SOCK14="${TMPDIR:-/tmp}/muxd-e2e-astart-$$.sock" |
| 14 | defer_sock "$SOCK14" | 16 | defer_sock "$SOCK14" |
| 15 | SOCK15="${TMPDIR:-/tmp}/muxd-e2e-aspty-$$.sock" | 17 | SOCK15="${TMPDIR:-/tmp}/muxd-e2e-aspty-$$.sock" |
| @@ -23,33 +25,63 @@ defer_sock "$SOCK15" | |||
| 23 | SOCK24="${TMPDIR:-/tmp}/muxd-e2e-bell-$$.sock" | 25 | SOCK24="${TMPDIR:-/tmp}/muxd-e2e-bell-$$.sock" |
| 24 | defer_sock "$SOCK24" | 26 | defer_sock "$SOCK24" |
| 25 | 27 | ||
| 26 | # --- M13: attach auto-start (proxy) + muxd stop ------------------------ | 28 | # --- M13: proxy reaches a daemon, `muxd start` makes one, muxd stop ---- |
| 27 | # | 29 | # |
| 28 | # Nothing is serving SOCK14: the attach itself must produce the daemon. | 30 | # Nothing is serving SOCK14, and `muxd proxy` no longer answers that by |
| 29 | # SHELL pinned because the auto-started daemon gets no --shell flag and | 31 | # starting a daemon: it is the verb a client reaches over ssh, and a wall |
| 32 | # runs its sibling `muxd endpoint` once a second per listed host — a read | ||
| 33 | # that creates a session (and a shell) is the regression this refuses. | ||
| 34 | # So the cold attach FAILS, in proxy.zig's own words, and the daemon the | ||
| 35 | # rest of this leg attaches to is one the user started by hand, which is | ||
| 36 | # what README tells them to do. | ||
| 37 | # | ||
| 38 | # SHELL pinned because the daemon gets no --shell flag of its own and | ||
| 30 | # resolves $SHELL — the suite must not inherit the developer's. | 39 | # resolves $SHELL — the suite must not inherit the developer's. |
| 40 | set +e | ||
| 41 | env SHELL=/bin/sh timeout 30 "$MUX" --via "$MUXD proxy --sock $SOCK14" \ | ||
| 42 | > "$OUT.ascold" 2>&1 < /dev/null | ||
| 43 | RC_COLD=$? | ||
| 44 | set -e | ||
| 45 | [ "$RC_COLD" -ne 0 ] || { | ||
| 46 | echo "e2e FAIL: a --via proxy against a socket nobody serves exited 0:" | ||
| 47 | cat "$OUT.ascold"; exit 1; } | ||
| 48 | grep -q "muxd proxy: cannot connect to $SOCK14" "$OUT.ascold" || { | ||
| 49 | echo "e2e FAIL: the cold --via proxy did not name the socket it could not reach:" | ||
| 50 | cat "$OUT.ascold"; exit 1; } | ||
| 51 | # Asked of the filesystem, not of the client: a refusal that had started a | ||
| 52 | # daemon anyway would have left the socket behind. | ||
| 53 | [ ! -e "$SOCK14" ] || { | ||
| 54 | echo "e2e FAIL: a refused --via proxy started a daemon on $SOCK14"; exit 1; } | ||
| 55 | |||
| 56 | # The pid is the whole point of the up-line: it is the only handle the | ||
| 57 | # suite has on a daemon that is nobody's child. Known gap, accepted: an | ||
| 58 | # assertion below exits before this capture runs, so a failure there | ||
| 59 | # leaves a daemon with no pid tracked — and hoisting the capture would not | ||
| 60 | # close it, since the window from the spawn to this sed cannot be made | ||
| 61 | # zero. Unlike the M10 start block's version of this gap (:1150) it is | ||
| 62 | # covered anyway: the trap also stops SOCK14/SOCK15 by PATH, which needs | ||
| 63 | # no pid. | ||
| 64 | "$MUXD" start --sock "$SOCK14" --shell /bin/sh 2> "$OUT.as.start" || { | ||
| 65 | echo "e2e FAIL: muxd start refused $SOCK14:"; cat "$OUT.as.start"; exit 1; } | ||
| 66 | APID=$(sed -n 's/.* pid=\([0-9]*\).*/\1/p' "$OUT.as.start" | head -1) | ||
| 67 | defer_kill "$APID" | ||
| 68 | [ -n "$APID" ] || { | ||
| 69 | echo "e2e FAIL: muxd start's up-line carries no pid"; cat "$OUT.as.start"; exit 1; } | ||
| 70 | kill -0 "$APID" || { echo "e2e FAIL: the started daemon is not alive"; exit 1; } | ||
| 71 | |||
| 31 | pipe_mux "$OUT.as" "$OUT.as.err" env SHELL=/bin/sh timeout 30 "$MUX" --via "$MUXD proxy --sock $SOCK14" | 72 | pipe_mux "$OUT.as" "$OUT.as.err" env SHELL=/bin/sh timeout 30 "$MUX" --via "$MUXD proxy --sock $SOCK14" |
| 32 | pipe_send 'printf "auto-%%s\\n" start\n' | 73 | pipe_send 'printf "auto-%%s\\n" start\n' |
| 33 | await_out "$OUT.as" "auto-start" "proxy auto-start: marker never reached the client" | 74 | await_out "$OUT.as" "auto-start" "proxy attach: marker never reached the client" |
| 34 | pipe_detach | 75 | pipe_detach |
| 35 | "$MUXD" dump --sock "$SOCK14" | grep -q "auto-start" || { | 76 | "$MUXD" dump --sock "$SOCK14" | grep -q "auto-start" || { |
| 36 | echo "e2e FAIL: proxy auto-start: attached daemon lost the marker" | 77 | echo "e2e FAIL: proxy attach: the daemon lost the marker" |
| 37 | cat "$OUT.as" "$OUT.as.err" 2>/dev/null; exit 1; } | 78 | cat "$OUT.as" "$OUT.as.err" 2>/dev/null; exit 1; } |
| 38 | grep -q '^muxd proxy: starting' "$OUT.as.err" || { | 79 | # Nothing on this path may print spawn progress any more — the daemon was |
| 39 | echo "e2e FAIL: cold attach printed no starting line"; cat "$OUT.as.err"; exit 1; } | 80 | # already up, and neither the proxy nor the client is allowed to make one. |
| 40 | # The pid is the whole point of the up-line: it is the only handle the | 81 | grep -q 'starting' "$OUT.as.err" && { |
| 41 | # suite has on a daemon that is nobody's child. Known gap, accepted: the | 82 | echo "e2e FAIL: the proxy attach printed spawn progress" |
| 42 | # two assertions above exit before this capture runs, so a failure in | 83 | cat "$OUT.as.err"; exit 1; } |
| 43 | # either leaves a daemon with no pid tracked — and hoisting the capture | 84 | assert_converged "$OUT.as" "$SOCK14" "attach over proxy" |
| 44 | # would not close it, since the window from the spawn to this sed cannot | ||
| 45 | # be made zero. Unlike the M10 start block's version of this gap (:1150) | ||
| 46 | # it is covered anyway: the trap also stops SOCK14/SOCK15 by PATH, which | ||
| 47 | # needs no pid. | ||
| 48 | APID=$(sed -n 's/.* pid=\([0-9]*\).*/\1/p' "$OUT.as.err" | head -1) | ||
| 49 | defer_kill "$APID" | ||
| 50 | [ -n "$APID" ] || { echo "e2e FAIL: proxy up-line carries no pid"; cat "$OUT.as.err"; exit 1; } | ||
| 51 | kill -0 "$APID" || { echo "e2e FAIL: auto-started daemon not alive"; exit 1; } | ||
| 52 | assert_converged "$OUT.as" "$SOCK14" "auto-start via proxy" | ||
| 53 | 85 | ||
| 54 | # Silence is the fast path: a warm attach must print NO spawn progress. | 86 | # Silence is the fast path: a warm attach must print NO spawn progress. |
| 55 | pipe_mux "$OUT.as2" "$OUT.as2.err" env SHELL=/bin/sh timeout 30 "$MUX" --via "$MUXD proxy --sock $SOCK14" | 87 | pipe_mux "$OUT.as2" "$OUT.as2.err" env SHELL=/bin/sh timeout 30 "$MUX" --via "$MUXD proxy --sock $SOCK14" |
| @@ -99,8 +131,9 @@ set -e | |||
| 99 | echo "e2e FAIL: stop-when-nothing exited $RC_STOP, want 0"; cat "$OUT.stop2"; exit 1; } | 131 | echo "e2e FAIL: stop-when-nothing exited $RC_STOP, want 0"; cat "$OUT.stop2"; exit 1; } |
| 100 | grep -q "nothing listening on $SOCK14" "$OUT.stop2" || { | 132 | grep -q "nothing listening on $SOCK14" "$OUT.stop2" || { |
| 101 | echo "e2e FAIL: stop-when-nothing said the wrong thing"; cat "$OUT.stop2"; exit 1; } | 133 | echo "e2e FAIL: stop-when-nothing said the wrong thing"; cat "$OUT.stop2"; exit 1; } |
| 102 | rm_swept "$OUT.as" "$OUT.as.err" "$OUT.as2" "$OUT.as2.err" "$OUT.stop" "$OUT.stop2" | 134 | rm_swept "$OUT.ascold" "$OUT.as.start" "$OUT.as" "$OUT.as.err" "$OUT.as2" \ |
| 103 | ok "attach auto-start via proxy; muxd stop tears it down" | 135 | "$OUT.as2.err" "$OUT.stop" "$OUT.stop2" |
| 136 | ok "a cold --via proxy refuses and starts nothing; muxd start makes the daemon and muxd stop tears it down" | ||
| 104 | 137 | ||
| 105 | # --- M13: local mux auto-start, under the pty fixture ------------------ | 138 | # --- M13: local mux auto-start, under the pty fixture ------------------ |
| 106 | # | 139 | # |