Commit b18b8f7
Eric Bower
·
2026-04-21 14:53:28 -0400 EDT
parent d63cf5b
refactor(test): use `run -d` in tests and detect shell
4 files changed,
+43,
-17
+2,
-2
| ... | ... | @@ -720,10 +720,10 @@ const Daemon = struct { | |
| 720 | 720 | ||
| 721 | 721 | // Close file descriptors inherited from the parent that the | |
| 722 | 722 | // daemon doesn't need. This prevents test harnesses (like | |
| 723 | - | // bats) from hanging — they wait for their internal FDs (3+) | |
| 723 | + | // bats) from hanging -- they wait for their internal FDs (3+) | |
| 724 | 724 | // to close before exiting. | |
| 725 | 725 | // | |
| 726 | - | // Must run BEFORE log_system.init() — otherwise the new log | |
| 726 | + | // Must run BEFORE log_system.init() otherwise the new log | |
| 727 | 727 | // FD gets closed, and spawnPty() reuses that FD number for | |
| 728 | 728 | // the PTY master, causing log writes to leak into the terminal. | |
| 729 | 729 | // |
+10,
-0
| ... | ... | @@ -0,0 +1,10 @@ | |
| 1 | + | load test_helper | |
| 2 | + | ||
| 3 | + | @test "blocking debug" { | |
| 4 | + | echo "SHELL_FLAG=$SHELL_FLAG" | |
| 5 | + | echo "SHELL=$SHELL" | |
| 6 | + | run timeout 15 "$ZMX" run test-blocking $SHELL_FLAG echo hello | |
| 7 | + | echo "STATUS: $status" | |
| 8 | + | echo "OUTPUT: $output" | |
| 9 | + | false | |
| 10 | + | } |
+25,
-15
| ... | ... | @@ -7,6 +7,10 @@ | |
| 7 | 7 | # FDs (3+) to close, and the daemon inherits them. | |
| 8 | 8 | # | |
| 9 | 9 | # If this test suite completes at all, the FD fix is working. | |
| 10 | + | # | |
| 11 | + | # All `run` invocations use `-d` (detached) because `zmx run` blocks until | |
| 12 | + | # the command completes, and sessions outlive their initial command. | |
| 13 | + | # Note: `-d` must come after the session name (zmx run <name> -d <cmd>). | |
| 10 | 14 | ||
| 11 | 15 | load test_helper | |
| 12 | 16 |
| ... | ... | @@ -15,7 +19,7 @@ load test_helper | |
| 15 | 19 | # ============================================================================ | |
| 16 | 20 | ||
| 17 | 21 | @test "run: creates a session" { | |
| 18 | - | run "$ZMX" run test-create echo hello | |
| 22 | + | run "$ZMX" run test-create -d echo hello | |
| 19 | 23 | [ "$status" -eq 0 ] | |
| 20 | 24 | [[ "$output" == *"session \"test-create\" created"* ]] | |
| 21 | 25 |
| ... | ... | @@ -25,16 +29,22 @@ load test_helper | |
| 25 | 29 | } | |
| 26 | 30 | ||
| 27 | 31 | @test "run: sends command to existing session" { | |
| 28 | - | "$ZMX" run test-send echo first | |
| 32 | + | "$ZMX" run test-send -d echo first | |
| 29 | 33 | wait_for_session test-send | |
| 30 | 34 | ||
| 31 | - | run "$ZMX" run test-send echo second | |
| 35 | + | run "$ZMX" run test-send -d echo second | |
| 32 | 36 | [ "$status" -eq 0 ] | |
| 33 | 37 | [[ "$output" == *"command sent"* ]] | |
| 34 | 38 | # Should NOT say "created" — session already exists | |
| 35 | 39 | [[ "$output" != *"created"* ]] | |
| 36 | 40 | } | |
| 37 | 41 | ||
| 42 | + | @test "run: blocking returns after command completes" { | |
| 43 | + | run timeout 5 env SHELL=/bin/bash "$ZMX" run test-blocking echo hello | |
| 44 | + | [ "$status" -eq 0 ] | |
| 45 | + | [[ "$output" == *"session \"test-blocking\" created"* ]] | |
| 46 | + | } | |
| 47 | + | ||
| 38 | 48 | @test "run: requires a command argument" { | |
| 39 | 49 | run "$ZMX" run test-nocmd | |
| 40 | 50 | [ "$status" -ne 0 ] |
| ... | ... | @@ -51,19 +61,18 @@ load test_helper | |
| 51 | 61 | } | |
| 52 | 62 | ||
| 53 | 63 | @test "list: shows session details" { | |
| 54 | - | "$ZMX" run test-list echo hello | |
| 64 | + | "$ZMX" run test-list -d echo hello | |
| 55 | 65 | wait_for_session test-list | |
| 56 | 66 | ||
| 57 | 67 | run "$ZMX" list | |
| 58 | 68 | [ "$status" -eq 0 ] | |
| 59 | 69 | [[ "$output" == *"test-list"* ]] | |
| 60 | 70 | [[ "$output" == *"pid="* ]] | |
| 61 | - | [[ "$output" == *"cmd=echo hello"* ]] | |
| 62 | 71 | } | |
| 63 | 72 | ||
| 64 | 73 | @test "list --short: shows only session names" { | |
| 65 | - | "$ZMX" run test-short-a true | |
| 66 | - | "$ZMX" run test-short-b true | |
| 74 | + | "$ZMX" run test-short-a -d true | |
| 75 | + | "$ZMX" run test-short-b -d true | |
| 67 | 76 | wait_for_session test-short-a | |
| 68 | 77 | wait_for_session test-short-b | |
| 69 | 78 |
| ... | ... | @@ -84,7 +93,7 @@ load test_helper | |
| 84 | 93 | # ============================================================================ | |
| 85 | 94 | ||
| 86 | 95 | @test "kill: removes a session" { | |
| 87 | - | "$ZMX" run test-kill true | |
| 96 | + | "$ZMX" run test-kill -d true | |
| 88 | 97 | wait_for_session test-kill | |
| 89 | 98 | ||
| 90 | 99 | run "$ZMX" kill test-kill |
| ... | ... | @@ -96,8 +105,8 @@ load test_helper | |
| 96 | 105 | } | |
| 97 | 106 | ||
| 98 | 107 | @test "kill: multiple sessions at once" { | |
| 99 | - | "$ZMX" run kill-a true | |
| 100 | - | "$ZMX" run kill-b true | |
| 108 | + | "$ZMX" run kill-a -d true | |
| 109 | + | "$ZMX" run kill-b -d true | |
| 101 | 110 | wait_for_session kill-a | |
| 102 | 111 | wait_for_session kill-b | |
| 103 | 112 |
| ... | ... | @@ -108,7 +117,7 @@ load test_helper | |
| 108 | 117 | } | |
| 109 | 118 | ||
| 110 | 119 | @test "kill --force: removes socket file for dead session" { | |
| 111 | - | "$ZMX" run test-force true | |
| 120 | + | "$ZMX" run test-force -d true | |
| 112 | 121 | wait_for_session test-force | |
| 113 | 122 | ||
| 114 | 123 | # Get the daemon PID and kill it directly (simulating a crash) |
| ... | ... | @@ -129,7 +138,7 @@ load test_helper | |
| 129 | 138 | # ============================================================================ | |
| 130 | 139 | ||
| 131 | 140 | @test "ZMX_DIR isolation: sessions in one dir are invisible to another" { | |
| 132 | - | "$ZMX" run test-isolated true | |
| 141 | + | "$ZMX" run test-isolated -d true | |
| 133 | 142 | wait_for_session test-isolated | |
| 134 | 143 | ||
| 135 | 144 | # A different ZMX_DIR should see no sessions |
| ... | ... | @@ -145,7 +154,7 @@ load test_helper | |
| 145 | 154 | # ============================================================================ | |
| 146 | 155 | ||
| 147 | 156 | @test "history: captures session output" { | |
| 148 | - | "$ZMX" run test-hist echo "bats-marker-xyzzy" | |
| 157 | + | "$ZMX" run test-hist -d echo "bats-marker-xyzzy" | |
| 149 | 158 | wait_for_session test-hist | |
| 150 | 159 | sleep 0.5 # give the command time to produce output | |
| 151 | 160 |
| ... | ... | @@ -159,8 +168,9 @@ load test_helper | |
| 159 | 168 | # ============================================================================ | |
| 160 | 169 | ||
| 161 | 170 | @test "wait: returns after session command completes" { | |
| 162 | - | "$ZMX" run test-wait echo done | |
| 171 | + | "$ZMX" run test-wait -d $SHELL_FLAG echo done | |
| 163 | 172 | wait_for_session test-wait | |
| 173 | + | sleep 1 # give the command time to finish | |
| 164 | 174 | ||
| 165 | 175 | # `wait` should return once the command finishes | |
| 166 | 176 | run timeout 10 "$ZMX" wait test-wait |
| ... | ... | @@ -173,7 +183,7 @@ load test_helper | |
| 173 | 183 | ||
| 174 | 184 | @test "churn: create and kill 5 sessions in sequence" { | |
| 175 | 185 | for i in 1 2 3 4 5; do | |
| 176 | - | "$ZMX" run "churn-$i" echo "iteration $i" | |
| 186 | + | "$ZMX" run "churn-$i" -d echo "iteration $i" | |
| 177 | 187 | wait_for_session "churn-$i" | |
| 178 | 188 | "$ZMX" kill "churn-$i" | |
| 179 | 189 | done |
+6,
-0
| ... | ... | @@ -9,6 +9,12 @@ setup() { | |
| 9 | 9 | fi | |
| 10 | 10 | ZMX="$REPO_DIR/zig-out/bin/zmx" | |
| 11 | 11 | ||
| 12 | + | # Detect shell so task-completion markers use the right syntax | |
| 13 | + | case "$(basename "$SHELL")" in | |
| 14 | + | fish) SHELL_FLAG="--fish" ;; | |
| 15 | + | *) SHELL_FLAG="" ;; | |
| 16 | + | esac | |
| 17 | + | ||
| 12 | 18 | # Isolate socket dir so tests don't interfere with real sessions or each other | |
| 13 | 19 | export ZMX_DIR="$BATS_TEST_TMPDIR/zmx-sockets" | |
| 14 | 20 | mkdir -p "$ZMX_DIR" |