diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-22 20:12:14 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-22 20:12:14 -0500 |
| commit | 0f8bbc7c1e2c2f6fec0b17753ac0d9c4a3ad4317 (patch) | |
| tree | 3a2015786254ac90610e221f26517aaf58e7ff26 /scripts | |
| parent | 0a57d75d3947fddd6c6ab62924c52a456f4776b0 (diff) | |
| download | archangel-0f8bbc7c1e2c2f6fec0b17753ac0d9c4a3ad4317.tar.gz archangel-0f8bbc7c1e2c2f6fec0b17753ac0d9c4a3ad4317.zip | |
fix(test): fail clearly when the VM forward port is taken
A test run launched qemu without first checking the SSH forward port, so a collision with another VM already holding it surfaced only as an opaque "Failed to start VM," with qemu unable to bind and no hint why. I added a port_in_use check in run_test before the launch: it errors with the port number and the SSH_PORT override to set, records the failure, and moves on.
The check lives in run_test, not start_vm, because start_vm runs in a command substitution (vm_pid=$(start_vm ...)) where this harness's non-exiting error() would be captured as the PID instead of failing the run. The pure half, port_listening_in, takes an `ss -tln` snapshot as a string so it's unit-testable.
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/test-install.sh | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/scripts/test-install.sh b/scripts/test-install.sh index 8cfe2ec..4220d20 100755 --- a/scripts/test-install.sh +++ b/scripts/test-install.sh @@ -142,6 +142,20 @@ cleanup_disks() { rm -f "$VM_DIR"/test-"${test_name}"-disk*.qcow2 } +# Pure predicate: does this `ss -tln` snapshot show <port> already +# listening? Kept separate from the live ss query (port_in_use) so it's +# unit-testable with fixture output. The ":<port> " match anchors on the +# colon and trailing space so 2222 doesn't match 12222 or 22222. +port_listening_in() { + local port="$1" ss_output="$2" + grep -q ":${port} " <<<"$ss_output" +} + +# Live check: is <port> currently bound by a listening socket? +port_in_use() { + port_listening_in "$1" "$(ss -tln 2>/dev/null)" +} + # Start VM and return PID start_vm() { local test_name="$1" @@ -863,6 +877,19 @@ run_test() { step "Creating VM disks..." create_disks "$disk_count" "$config_name" + # Fail clearly if the forward port is taken (another VM?) before launching, + # rather than letting qemu fail to bind and report an opaque "Failed to + # start VM". Runs here, not inside start_vm — start_vm is command- + # substituted (vm_pid=$(...)), where error()'s output would be captured as + # the PID instead of failing the run. + if port_in_use "$SSH_PORT"; then + error "Port $SSH_PORT already in use (another VM?). Set SSH_PORT=<free port> and retry." + cleanup_disks "$config_name" + TESTS_FAILED=$((TESTS_FAILED + 1)) + FAILED_TESTS+=("$config_name") + return 1 + fi + step "Starting VM..." local vm_pid vm_pid=$(start_vm "$config_name" "$disk_count") |
