a73x

d5e04be1

test: a refused birth paints [refused] and the wall stays up

a73x   2026-08-28 19:53

Commit message
test: a refused birth paints [refused] and the wall stays up

`.refused` lost its only end-to-end witness with the `mux TARGET#session`
spelling that used to drive it, and rested on a labelText unit test that
pins the string rather than a pump reaching it. A daemon holding
max_clients sessions refuses the picker's ninth attach: the bar wears the
state word, and the eight tiles already up outlive it.

test/e2e.sh
Old New
@@ -177,8 +177,8 @@ done
177 # one of those and adds a convergence point would be pinning a fact every 177 # one of those and adds a convergence point would be pinning a fact every
178 # leg above already establishes. 178 # leg above already establishes.
179 179
180 [ "$OK_COUNT" = "88" ] || { 180 [ "$OK_COUNT" = "89" ] || {
181 echo "e2e FAIL: $OK_COUNT scenario checkpoints ran, the pin says 88 —" 181 echo "e2e FAIL: $OK_COUNT scenario checkpoints ran, the pin says 89 —"
182 echo " a scenario was added (update the pin) or silently lost" 182 echo " a scenario was added (update the pin) or silently lost"
183 exit 1 183 exit 1
184 } 184 }
test/e2e_13_birth.sh
Old New
@@ -672,3 +672,94 @@ grep -q "lfd-two" "$OUT.lfdsess1" && {
672 assert_stopped "$SOCK74" "$D74PID" "lowest-free-digit" "$OUT.lfdstop" 672 assert_stopped "$SOCK74" "$D74PID" "lowest-free-digit" "$OUT.lfdstop"
673 D74PID="" 673 D74PID=""
674 ok "a new tile takes the lowest free digit, and the daemon takes the name back" 674 ok "a new tile takes the lowest free digit, and the daemon takes the name back"
675
676 # ---- a birth the DAEMON refuses narrates, and the wall stays up ---------
677 #
678 # `.refused` is a live tile state and the only one with no CLI spelling
679 # left to reach it: `mux TARGET#session` is gone, so what used to drive
680 # this leg went with it and the state word rested on a unit test of
681 # `labelText` — which pins the STRING, not that a refused pump ever
682 # reaches it.
683 #
684 # The refusal is the client TABLE, not the session table, and that is what
685 # makes this cheap: every tile is its own attach and so its own client
686 # slot, so a daemon holding eight sessions on a terminal with room for ten
687 # stripes has eight tiles and no slot left. The picker's Enter dials a
688 # ninth, the daemon refuses it before any replay frame, and the pump paints
689 # `[refused]` on that tile's bar on its way out.
690 #
691 # Two claims, and the second is the newer one: the wall STAYS. A refused
692 # picker birth used to take mux down with it (rc 1 on a terminal); a tile
693 # that keeps the wall (`Tile.keeps_wall`) leaves the eight standing, which
694 # is what the marker typed after the refusal proves — it reaches a session
695 # because there is still a wall to type into.
696 SOCK75="${TMPDIR:-/tmp}/muxd-e2e-reftile-$$.sock"
697 defer_sock "$SOCK75"
698 RTSTATE="${TMPDIR:-/tmp}/mux-e2e-reftile-state-$$"
699 defer_rm "$RTSTATE"
700 start_daemon "$SOCK75" "$OUT.rt.d" "refused-tile daemon never bound" --shell /bin/sh
701 D75PID=$DPID
702 # Seven more, so the daemon holds eight sessions with its own `0`: exactly
703 # max_clients, so the wall fills the table and the ninth attach is the one
704 # under test. The fills detach as they go and leave the slots free.
705 fill_sessions "$SOCK75" "$OUT.rtfill" f 1 7
706 wait_sessions "$SOCK75" 8 "refused-tile: the daemon should hold eight sessions"
707 mkdir -p "$RTSTATE/mux"
708 printf -- '--sock %s\n' "$SOCK75" > "$RTSTATE/mux/hosts"
709 no_saved_tree "$RTSTATE"
710 set +e
711 # Tall and not wide, the hosts group's shape and for its reason: 80 columns
712 # is under the aspect rule's `cols >= 2 * rows`, so the cut is stacked and
713 # every bar gets the full width — beside, eight stripes are nine columns
714 # each and `labelText` spends them all on the state word. Forty-four rows
715 # over eight stripes leaves room for a ninth (three rows each, two of
716 # content under a bar): the WALL is not what refuses here, and a terminal
717 # that ran out of stripes first would say `[no room on the wall for another
718 # tile]` and never dial at all.
719 XDG_STATE_HOME="$RTSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 44 \
720 --out "$OUT.rtcap" --err "$OUT.rtcap.err" -- "$MUX" > "$OUT.rtpc" 2>&1 <<'EOF'
721 expect [up] 25000
722 settle 2000 25000
723 send \x1cs
724 expect Enter/c new session 15000
725 send \r
726 expect [refused] 25000
727 settle 1500 20000
728 send printf 'rt-%s\n' alive\n
729 expect rt-alive 20000
730 settle 500 15000
731 send \x1cd
732 waitexit 15000
733 EOF
734 RC=$?
735 set -e
736 # The exit code IS the second claim: a wall that ended on the refusal would
737 # be gone before the marker, and this is where that shows.
738 [ "$RC" -eq 0 ] || {
739 echo "e2e FAIL: refused-tile: the wall exited $RC — a refused birth must"
740 echo " leave the tiles that were already up standing:"
741 cat "$OUT.rtpc"; echo "--- stderr ---"; cat "$OUT.rtcap.err"; exit 1; }
742 # The narration, off the STREAM: the refused tile vanishes on the pass
743 # after it paints, so the final grid is not where the word lives.
744 grep -qF -- "[refused]" "$OUT.rtcap" || {
745 echo "e2e FAIL: refused-tile: no tile ever wore the refused state word:"
746 grep -ao '\[[a-z ]*\]' "$OUT.rtcap" | sort -u | head; exit 1; }
747 # ...and the refusal created nothing. A daemon that refused the attach but
748 # kept the session would leave a session nobody can see — the worse of the
749 # two failures, and invisible to the screen.
750 wait_sessions "$SOCK75" 8 "refused-tile: a refused birth must leave no session behind"
751 # The marker landed in a session on the wall, asked of the DAEMON: the
752 # eight tiles outlived the ninth. Which one holds it is the focus's
753 # business — the refusal puts the focus back on the tile it was born from
754 # — so every session is asked and one hit is the claim.
755 RTWHERE=""
756 for _rt in 0 f1 f2 f3 f4 f5 f6 f7; do
757 if dump_session "$SOCK75" "$_rt" 2>/dev/null | grep -q "rt-alive"; then RTWHERE="$_rt"; fi
758 done
759 [ -n "$RTWHERE" ] || {
760 echo "e2e FAIL: refused-tile: the marker typed after the refusal reached no"
761 echo " session — the wall did not survive its own refused birth:"
762 cat "$OUT.rtpc"; exit 1; }
763 assert_stopped "$SOCK75" "$D75PID" "refused-tile" "$OUT.rtstop"
764 D75PID=""
765 ok "a birth the daemon refuses paints [refused] and leaves the wall standing"