a73x

c6a5061f

test: e2e — hosts rm asks the OS, and two settles become conditions

a73x   2026-08-28 19:53

Commit message
test: e2e — hosts rm asks the OS, and two settles become conditions

I4. The spec's Testing says `mux hosts rm` of a host with a running
session "leaves the session running (`ps`)", and scenario 5 asked the
daemon: `wait_sessions` and a grid dump, both of them the daemon's own
account of itself. Session b's setup now prints its shell's `$$`, the leg
keeps that pid, and after the `rm` it asks the OS — `kill -0`, plus a
`ps` state check so a zombie cannot answer for a live process.

Graded by killing the shell myself between the `rm` and the check: the
leg fails by name ("session b's shell (pid N) died when its daemon was
taken off the wall — forgetting is not ending"), so the witness is live
rather than vacuous.

M4. Two timed settles standing where a condition exists:

  * after `Ctrl-\ n`, the `>` landing on the second tile's bar. Both bars
    are redrawn on a focus move and the unfocused marker is the same
    width, so `2> ` appears exactly when the focus has.
  * after the daemon is restarted, its own tile. The heredoc is unquoted
    so the needle can name the socket; a duration there was a guess at
    how long a poll takes on a loaded machine.

07's `settle 1500` after the refused chord stays: no condition exists
there — the refusal paints nothing (see that leg's comment).

test/e2e_09_hosts.sh
Old New
@@ -149,10 +149,17 @@ env XDG_STATE_HOME="$HSTATE" timeout 40 "$MUX" hosts add "--sock $SOCKH2" > "$OU
149 echo "e2e FAIL: hosts: 'hosts add' refused the second daemon:" 149 echo "e2e FAIL: hosts: 'hosts add' refused the second daemon:"
150 cat "$OUT.hadd"; exit 1; } 150 cat "$OUT.hadd"; exit 1; }
151 pipe_mux "$OUT.hb" "$OUT.hb.err" env XDG_STATE_HOME="$HSTATE" timeout 40 "$MUX" --sock "$SOCKH1" --session b 151 pipe_mux "$OUT.hb" "$OUT.hb.err" env XDG_STATE_HOME="$HSTATE" timeout 40 "$MUX" --sock "$SOCKH1" --session b
152 pipe_send 'printf "hb-%%s\\n" pin\n' 152 pipe_send 'printf "hb-%%s\\n" pin; echo bshell=$$\n'
153 await_out "$OUT.hb" "hb-pin" "hb-pin never reached the client" 153 await_out "$OUT.hb" "hb-pin" "hb-pin never reached the client"
154 pipe_detach "hosts session b" 154 pipe_detach "hosts session b"
155 wait_grid "$SOCKH1" "hb-pin" "hosts: session b's marker" b 155 wait_grid "$SOCKH1" "hb-pin" "hosts: session b's marker" b
156 # The pid the shell printed of ITSELF, kept for scenario 5: what "hosts rm
157 # ends nothing" claims is about a PROCESS, and only the OS can answer that.
158 wait_grid "$SOCKH1" "bshell=" "hosts: session b's shell pid" b
159 BSHELL=$(dump_session "$SOCKH1" b | sed -n 's/.*bshell=\([0-9]*\).*/\1/p' | tail -1)
160 [ -n "$BSHELL" ] || { echo "e2e FAIL: hosts: session b printed no shell pid"; exit 1; }
161 kill -0 "$BSHELL" 2>/dev/null || {
162 echo "e2e FAIL: hosts: session b's shell pid $BSHELL is not a live process"; exit 1; }
156 pipe_mux "$OUT.hc" "$OUT.hc.err" env XDG_STATE_HOME="$HSTATE" timeout 40 "$MUX" --sock "$SOCKH2" --session c 163 pipe_mux "$OUT.hc" "$OUT.hc.err" env XDG_STATE_HOME="$HSTATE" timeout 40 "$MUX" --sock "$SOCKH2" --session c
157 pipe_send 'printf "hc-%%s\\n" pin\n' 164 pipe_send 'printf "hc-%%s\\n" pin\n'
158 await_out "$OUT.hc" "hc-pin" "hc-pin never reached the client" 165 await_out "$OUT.hc" "hc-pin" "hc-pin never reached the client"
@@ -180,7 +187,10 @@ send printf 'walk-%s\\n' one\n
180 expect walk-one 20000 187 expect walk-one 20000
181 settle 800 20000 188 settle 800 20000
182 send \x1cn 189 send \x1cn
183 settle 800 20000 190 # The `>` landing on the second tile's bar, not a guess at how long that
191 # takes: `paintLabel` redraws both bars on a focus move, and the unfocused
192 # marker is the same width, so `2> ` appears exactly when the focus has.
193 expect 2> --sock 20000
184 send printf 'walk-%s\\n' two\n 194 send printf 'walk-%s\\n' two\n
185 expect walk-two 20000 195 expect walk-two 20000
186 settle 800 20000 196 settle 800 20000
@@ -375,10 +385,13 @@ fi
375 start_daemon "$SOCKH2" "$OUT.h2b.d" "hosts daemon 2 never came back" --shell /bin/sh 385 start_daemon "$SOCKH2" "$OUT.h2b.d" "hosts daemon 2 never came back" --shell /bin/sh
376 DH2PID=$DPID 386 DH2PID=$DPID
377 set +e 387 set +e
388 # Unquoted heredoc: the needle names the REBORN daemon's own tile, which is
389 # what the wall is being waited on for. A duration here would be a guess at
390 # how long a poll takes on a loaded machine.
378 XDG_STATE_HOME="$HSTATE" timeout 60 "$PTYCLIENT" --cols 80 --rows 44 \ 391 XDG_STATE_HOME="$HSTATE" timeout 60 "$PTYCLIENT" --cols 80 --rows 44 \
379 --out "$OUT.hrcap" --err "$OUT.hrcap.err" -- "$MUX" > "$OUT.hrpc" 2>&1 <<'EOF' 392 --out "$OUT.hrcap" --err "$OUT.hrcap.err" -- "$MUX" > "$OUT.hrpc" 2>&1 <<EOF
380 expect [up] 25000 393 expect --sock $SOCKH2#0 [up] 25000
381 settle 2500 25000 394 settle 800 25000
382 send \x1cd 395 send \x1cd
383 waitexit 15000 396 waitexit 15000
384 EOF 397 EOF
@@ -436,6 +449,17 @@ if grep -qF -- "$SOCKH1" "$HSTATE/mux/hosts"; then
436 echo "e2e FAIL: hosts rm: the line is still on the wall:" 449 echo "e2e FAIL: hosts rm: the line is still on the wall:"
437 cat "$HSTATE/mux/hosts"; exit 1 450 cat "$HSTATE/mux/hosts"; exit 1
438 fi 451 fi
452 # The OS first, and it is the assertion the spec names: `hosts rm` is a
453 # line leaving a file, never an instruction to a daemon, so the SHELL that
454 # was running before it is the same process afterwards. A daemon reporting
455 # its own session count cannot catch itself being wrong about that.
456 kill -0 "$BSHELL" 2>/dev/null || {
457 echo "e2e FAIL: hosts rm: session b's shell (pid $BSHELL) died when its daemon"
458 echo " was taken off the wall — forgetting is not ending"
459 ps -o pid,ppid,stat,args -p "$BSHELL" 2>&1; exit 1; }
460 [ "$(ps -o stat= -p "$BSHELL" 2>/dev/null | cut -c1)" != "Z" ] || {
461 echo "e2e FAIL: hosts rm: session b's shell is a zombie, so kill -0 proved nothing"
462 ps -o pid,ppid,stat,args -p "$BSHELL" 2>&1; exit 1; }
439 wait_sessions "$SOCKH1" 2 "hosts rm: daemon 1's sessions must survive being forgotten" 463 wait_sessions "$SOCKH1" 2 "hosts rm: daemon 1's sessions must survive being forgotten"
440 wait_grid "$SOCKH1" "hb-pin" "hosts rm: session b's grid outlived the wall line" b 464 wait_grid "$SOCKH1" "hb-pin" "hosts rm: session b's grid outlived the wall line" b
441 465