diff --git a/tests/lifecycle/bats/backend-survives-archipelago-restart.bats b/tests/lifecycle/bats/backend-survives-archipelago-restart.bats index bb962eaa..4a1c82f8 100644 --- a/tests/lifecycle/bats/backend-survives-archipelago-restart.bats +++ b/tests/lifecycle/bats/backend-survives-archipelago-restart.bats @@ -19,6 +19,11 @@ # # Gated by ARCHY_ALLOW_DESTRUCTIVE=1 because it bounces archipelago. +# bats-core ships no `fail`; bats-assert isn't installed on the alpha fleet. +# Define the same minimal helper the other suites use (see mempool.bats) so a +# tripped assertion reports as a real test failure, not a status-127 crash. +fail() { echo "$@" >&2; return 1; } + backend_units=( "bitcoin-knots" "bitcoin-core" diff --git a/tests/lifecycle/bats/use-quadlet-backends-install.bats b/tests/lifecycle/bats/use-quadlet-backends-install.bats index 02b3abab..cbb23298 100644 --- a/tests/lifecycle/bats/use-quadlet-backends-install.bats +++ b/tests/lifecycle/bats/use-quadlet-backends-install.bats @@ -23,6 +23,11 @@ # box). No env vars required for the read-only checks. The cleanup # section at the bottom is gated by ARCHY_ALLOW_DESTRUCTIVE=1. +# bats-core ships no `fail`; bats-assert isn't installed on the alpha fleet. +# Define the same minimal helper the other suites use (see mempool.bats) so a +# tripped assertion reports as a real test failure, not a status-127 crash. +fail() { echo "$@" >&2; return 1; } + quadlet_dir() { echo "${XDG_CONFIG_HOME:-$HOME/.config}/containers/systemd" } @@ -97,18 +102,24 @@ require_quadlet_backends() { done < <(backend_quadlet_units) } -@test "Phase 3.4: any unit emitting HealthCmd= also emits Notify=healthy" { +@test "health is app-level state, NOT a systemd start gate (no Notify=healthy)" { require_quadlet_backends + # Phase 3.4 originally emitted Notify=healthy so `systemctl start` blocked + # until the healthcheck passed. That was deliberately reverted: gating start + # on health hung boot reconciliation for dependency-waiting apps (fedimint + # idles its entrypoint until Bitcoin IBD finishes; lnd until the macaroon + # unlocks), leaving units stuck in "deactivating". The renderer now emits + # HealthCmd= for Podman's health state but TimeoutStartSec=0 and NO + # Notify=healthy (see quadlet.rs render() + contains_stale_health_gate()). + # This asserts the current invariant: no backend unit gates start on health. local d d="$(quadlet_dir)" while read -r name; do [[ -z "$name" ]] && continue local body body="$(<"$d/$name.container")" - if [[ "$body" == *"HealthCmd="* ]]; then - [[ "$body" == *"Notify=healthy"* ]] \ - || fail "$name: HealthCmd= present but Notify=healthy missing — systemctl start won't gate on health" - fi + [[ "$body" != *"Notify=healthy"* ]] \ + || fail "$name: emits Notify=healthy — stale health gate; start would block on health and can hang boot reconcile" done < <(backend_quadlet_units) }