#!/usr/bin/env bash # Covers the #1240 fleet-transport checks in `mosaic-doctor` and in # `tools/install.sh`. # # Both checks answer the same question — "can a seat actually launch on this # host?" — from two different places, because the installer has to be able to # answer it before the framework's own scripts are guaranteed to be on disk. # Two implementations of one rule is exactly the shape that drifts, so this # harness drives BOTH, in one file, from the same table of cases. # # The functions are extracted from the shipped scripts rather than copied here. # A test that carries its own copy of the logic is a test that keeps passing # after the shipped copy changes — the failure mode this whole change is about. # Extraction is by exact function header and a closing brace in column one; if # either script is reshaped so that stops matching, the extraction yields # nothing and this fails loudly instead of silently measuring an empty string. set -euo pipefail SCRIPT_DIR=$(cd -- "$(dirname -- "$0")" && pwd) DOCTOR="$SCRIPT_DIR/mosaic-doctor" # framework/tools/_scripts -> framework/tools -> framework -> mosaic -> packages -> repo INSTALLER=$(cd -- "$SCRIPT_DIR/../../../../.." && pwd)/tools/install.sh fail() { echo "FAIL: $*" >&2 exit 1 } [ -f "$DOCTOR" ] || fail "missing mosaic-doctor at $DOCTOR" [ -f "$INSTALLER" ] || fail "missing install.sh at $INSTALLER" ROOT=$(mktemp -d) trap 'rm -rf "$ROOT"' EXIT # The cases below run with PATH set to a directory that deliberately does not # contain a shell, and a PATH assignment on a command also governs how that # command is looked up — so bash has to be named absolutely or it becomes the # thing that is missing. BASH_BIN=$(command -v bash) || fail "host is missing 'bash'" # A PATH containing exactly the utilities these functions use and nothing else. # The absent-transport cases are only meaningful on a PATH where the transport # is genuinely unresolvable, and this host (like most) has tmux in /usr/bin — # so the system path cannot be part of the path under test. FAKE_BIN="$ROOT/bin" mkdir -p "$FAKE_BIN" for utility in sed head tr awk; do utility_path=$(command -v "$utility") || fail "host is missing '$utility'" ln -s "$utility_path" "$FAKE_BIN/$utility" done if PATH="$FAKE_BIN" command -v tmux >/dev/null 2>&1; then fail "'tmux' is resolvable on the minimal test path; absent-transport cases are not measurable" fi # Extract a function by its exact header, up to a closing brace in column one. extract_function() { local source_file="$1" local function_name="$2" local destination="$3" awk -v name="$function_name" ' $0 == name "() {" { collecting = 1 } collecting { print } collecting && $0 == "}" { exit } ' "$source_file" > "$destination" grep -qF "$function_name() {" "$destination" || fail "could not extract '$function_name' from $source_file — has it been renamed or reshaped?" # An unterminated extraction would be a syntax error the moment it is sourced, # but saying so here names the cause instead of leaving a bash parse error. bash -n "$destination" || fail "extracted '$function_name' does not parse; the closing brace was probably not found" } extract_function "$DOCTOR" fleet_declared_transport "$ROOT/doctor-declared.sh" extract_function "$DOCTOR" check_fleet_transport "$ROOT/doctor-check.sh" extract_function "$INSTALLER" check_fleet_transport "$ROOT/installer-check.sh" # Build a MOSAIC_HOME, optionally with a roster declaring a transport. make_home() { local home="$ROOT/$1" local declared="${2-}" rm -rf "$home" mkdir -p "$home" if [ -n "$declared" ]; then mkdir -p "$home/fleet" cat > "$home/fleet/roster.yaml" <&1 } run_installer_check() { local home="$1" local path="$2" MOSAIC_HOME="$home" PATH="$path" "$BASH_BIN" --noprofile --norc -c ' set -euo pipefail warn() { echo "[WARN] $*"; } C="" RESET="" MOSAIC_HOME="$1" source "$2" check_fleet_transport ' _ "$home" "$ROOT/installer-check.sh" 2>&1 } # A transport that exists. Named tmux because that is what the default roster # declares; the binary never runs, it only has to resolve. PRESENT_BIN="$ROOT/present-bin" mkdir -p "$PRESENT_BIN" printf '#!/usr/bin/env bash\nexit 0\n' > "$PRESENT_BIN/tmux" chmod +x "$PRESENT_BIN/tmux" PATH_WITH_TMUX="$PRESENT_BIN:$FAKE_BIN" # ── absent, no roster ──────────────────────────────────────────────────────── # Nothing has been configured yet, so the honest thing to point at is `init`. home=$(make_home no-roster) output=$(run_doctor_check "$home" "$FAKE_BIN") echo "$output" | grep -qF '[WARN]' || fail "doctor did not warn when tmux was absent" echo "$output" | grep -qF 'tmux' || fail "doctor warning did not name the transport" echo "$output" | grep -qF 'mosaic fleet init' || fail "doctor did not point a rosterless host at init" output=$(run_installer_check "$home" "$FAKE_BIN") echo "$output" | grep -qF '[WARN]' || fail "installer did not warn when tmux was absent" echo "$output" | grep -qF 'reports success and no seat comes up' || fail "installer warning did not say what the missing transport actually breaks" # ── absent, roster present ─────────────────────────────────────────────────── # A configured fleet that cannot launch is a stronger statement than a # hypothetical one, and the message says so. home=$(make_home with-roster tmux) output=$(run_doctor_check "$home" "$FAKE_BIN") echo "$output" | grep -qF '[WARN]' || fail "doctor did not warn with a roster present and tmux absent" echo "$output" | grep -qF 'roster' || fail "doctor did not mention the roster it found" echo "$output" | grep -qF 'mosaic fleet start' || fail "doctor did not point a configured host at start" # ── present ────────────────────────────────────────────────────────────────── # Silence from the installer, and a pass (not a warning) from the audit. for home_name in no-roster with-roster; do home="$ROOT/$home_name" output=$(run_doctor_check "$home" "$PATH_WITH_TMUX") if echo "$output" | grep -qF '[WARN]'; then fail "doctor warned about the transport while tmux was present ($home_name)" fi echo "$output" | grep -qF '[OK]' || fail "doctor did not record a pass with tmux present ($home_name)" output=$(run_installer_check "$home" "$PATH_WITH_TMUX") if [ -n "$output" ]; then fail "installer was not silent with tmux present ($home_name): $output" fi done # ── the roster declares something other than tmux ──────────────────────────── # The roster is read, not assumed. A host that declares a different transport # is told about the binary it actually needs, and never about tmux — being sent # to install the wrong package is worse than no advice at all. home=$(make_home other-transport zellij) output=$(run_doctor_check "$home" "$PATH_WITH_TMUX") echo "$output" | grep -qF 'zellij' || fail "doctor ignored the roster's declared transport" if echo "$output" | grep -qF 'tmux'; then fail "doctor named tmux for a host whose roster declares zellij" fi output=$(run_installer_check "$home" "$PATH_WITH_TMUX") echo "$output" | grep -qF 'zellij' || fail "installer ignored the roster's declared transport" if echo "$output" | grep -qF 'tmux'; then fail "installer named tmux for a host whose roster declares zellij" fi # ── a quoted or trailing-comment transport value ───────────────────────────── # YAML permits both and neither is exotic; a check that installs `tmux"` or # reads `tmux # default` as a binary name would send the operator nowhere. home=$(make_home quoted-transport '"tmux" # the only transport today') output=$(run_doctor_check "$home" "$PATH_WITH_TMUX") echo "$output" | grep -qF '[OK] Fleet transport available: tmux' || fail "doctor did not parse a quoted/commented transport value: $output" output=$(run_installer_check "$home" "$PATH_WITH_TMUX") if [ -n "$output" ]; then fail "installer did not parse a quoted/commented transport value: $output" fi echo "ok - fleet transport checks (mosaic-doctor + install.sh)"