3f277597
fix: tp1's daemon guard proves serving, not existing
a73x 2026-08-10 12:54
Commit message
test/e2e.sh
| Old | New | ||
|---|---|---|---|
| @@ -1842,7 +1842,15 @@ done | |||
| 1842 | # made=2/suppressed=1 on the next. Under load all three could coalesce, | 1842 | # made=2/suppressed=1 on the next. Under load all three could coalesce, |
| 1843 | # which would read as made=0 — the mutation's own signature. One send | 1843 | # which would read as made=0 — the mutation's own signature. One send |
| 1844 | # cannot coalesce with anything, so the counters below are exact. | 1844 | # cannot coalesce with anything, so the counters below are exact. |
| 1845 | set +e | 1845 | # |
| 1846 | # suppressed=0 therefore says more than "the keystroke predicted", and the | ||
| 1847 | # rest is worth writing down because a future edit to the input path could | ||
| 1848 | # take it away silently: Ctrl-\ is answered and returned on before | ||
| 1849 | # offerKeystroke is ever reached (client.zig:874), so the detach chord | ||
| 1850 | # cannot land in the counter; and Shift+PageUp has to arrive as ONE read, | ||
| 1851 | # because the whole-chunk mem.eql at client.zig:882 is what recognizes it — | ||
| 1852 | # split across two reads it matches nothing, falls through to the keystroke | ||
| 1853 | # path, and is both counted suppressed and forwarded to the shell as input. | ||
| 1846 | MUX_PREDICT_STATS=1 timeout 60 "$PTYCLIENT" --cols 80 --rows 24 \ | 1854 | MUX_PREDICT_STATS=1 timeout 60 "$PTYCLIENT" --cols 80 --rows 24 \ |
| 1847 | --out "$OUT.tp1" --err "$OUT.tp1.err" -- \ | 1855 | --out "$OUT.tp1" --err "$OUT.tp1.err" -- \ |
| 1848 | "$MUX" --via "$MUXD proxy --sock $SOCK13" > "$OUT.tp1.log" 2>&1 <<'EOF' & | 1856 | "$MUX" --via "$MUXD proxy --sock $SOCK13" > "$OUT.tp1.log" 2>&1 <<'EOF' & |
| @@ -1858,16 +1866,20 @@ send \x1c | |||
| 1858 | waitexit 15000 | 1866 | waitexit 15000 |
| 1859 | EOF | 1867 | EOF |
| 1860 | TP1PID=$! | 1868 | TP1PID=$! |
| 1861 | set -e | ||
| 1862 | 1869 | ||
| 1863 | # The tear goes between verb 3 (the scroll view is on screen) and verb 4; | 1870 | # The tear goes between verb 3 (the scroll view is on screen) and verb 4; |
| 1864 | # the fixture's "done 3" line is the barrier. Every needle above is unique | 1871 | # the fixture's "done 3" line is the barrier. Every needle above is unique |
| 1865 | # to its phase, which is what makes each expect sound under the no-counting | 1872 | # to its phase, which is what makes each expect sound under the no-counting |
| 1866 | # rule: | 1873 | # rule: |
| 1867 | # the first "100" is the attach snapshot's last row; | 1874 | # the first "100" is the attach snapshot's last row; |
| 1868 | # "60" is in the history page (54..77) and in NOTHING before it — the | 1875 | # "60" is in the history page (54..77) and in NOTHING before it. The |
| 1869 | # snapshot's rows are 78..100 and the client's own paints address rows | 1876 | # snapshot's rows are 78..100, and the escapes around them cannot spell |
| 1870 | # and column 1 only, so no cursor escape can spell it; | 1877 | # it either — but that is a fact about THIS session, not about the paint |
| 1878 | # code: both paint paths end with a CUP carrying the cursor's real | ||
| 1879 | # column (client.zig:968, :991), and a cursor at column 60 would put a | ||
| 1880 | # "60" in the stream. Here it cannot be: the session is cat in canonical | ||
| 1881 | # mode with one keystroke typed after the tear, so that column is 1 or 2 | ||
| 1882 | # for the whole scenario, and the row half of a CUP tops out at 24; | ||
| 1871 | # "reconnecting" is the banner, painted once, on the tear; | 1883 | # "reconnecting" is the banner, painted once, on the tear; |
| 1872 | # the SECOND "100" can only be the post-resync repaint: the scroll view | 1884 | # the SECOND "100" can only be the post-resync repaint: the scroll view |
| 1873 | # holds 54..77, and the banner carries no digits but its own position; | 1885 | # holds 54..77, and the banner carries no digits but its own position; |
| @@ -1890,7 +1902,12 @@ wait_for "$OUT.tp1.log" "done 3" 20 || { | |||
| 1890 | TP1PROXY=$(proxy_pid "$SOCK13") | 1902 | TP1PROXY=$(proxy_pid "$SOCK13") |
| 1891 | [ -n "$TP1PROXY" ] || { echo "e2e FAIL: tp1: no proxy to tear"; exit 1; } | 1903 | [ -n "$TP1PROXY" ] || { echo "e2e FAIL: tp1: no proxy to tear"; exit 1; } |
| 1892 | kill -9 "$TP1PROXY" | 1904 | kill -9 "$TP1PROXY" |
| 1893 | kill -0 "$D13PID" || { echo "e2e FAIL: tp1 tear killed the daemon, not the proxy"; exit 1; } | 1905 | # The daemon must still be SERVING, which is what `kill -0` cannot tell us: |
| 1906 | # it is our own backgrounded child, so a dead one is a zombie until the | ||
| 1907 | # shell reaps it, and signalling a zombie succeeds. A dump answers only if | ||
| 1908 | # the process is alive and its accept loop is running. | ||
| 1909 | "$MUXD" dump --sock "$SOCK13" >/dev/null 2>&1 || { | ||
| 1910 | echo "e2e FAIL: tp1 tear killed the daemon, not the proxy"; exit 1; } | ||
| 1894 | 1911 | ||
| 1895 | set +e | 1912 | set +e |
| 1896 | wait "$TP1PID" | 1913 | wait "$TP1PID" |