From 3cea7dd6c5d5c986f5a4978bcb725578675affad Mon Sep 17 00:00:00 2001 From: archipelago Date: Sun, 28 Jun 2026 16:09:05 -0400 Subject: [PATCH] =?UTF-8?q?test(phase3):=20fix=20Phase-3=20quadlet=20gates?= =?UTF-8?q?=20=E2=80=94=20define=20fail(),=20drop=20stale=20Notify=3Dhealt?= =?UTF-8?q?hy=20assert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two Phase-3 bats suites used `fail` (a bats-assert helper) but bats-assert isn't installed on the alpha fleet (only bats-core), so every tripped assertion crashed with `fail: command not found` (status 127) instead of reporting a real pass/fail. Define the same minimal `fail() { echo ...; return 1; }` the other suites already use (see mempool.bats). Without this the gates were silently non-functional. Also rewrite the obsolete "HealthCmd= implies Notify=healthy" assertion in use-quadlet-backends-install.bats. Phase 3.4's Notify=healthy was deliberately reverted: gating `systemctl start` on health hung boot reconciliation for dependency-waiting apps (fedimint idles until Bitcoin IBD; lnd until macaroon unlock), leaving units stuck "deactivating". The renderer now emits HealthCmd= for Podman's health state but TimeoutStartSec=0 and NO Notify=healthy (quadlet.rs render() + contains_stale_health_gate()). The test now asserts the current invariant: no backend unit gates start on health. Verified on the .228 canary node (ARCHIPELAGO_USE_QUADLET_BACKENDS=1): use-quadlet-backends-install 6/6, backend-survives-archipelago-restart 3/3. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../backend-survives-archipelago-restart.bats | 5 +++++ .../bats/use-quadlet-backends-install.bats | 21 ++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) 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) }