ci/woodpecker/pr/ci Pipeline was successful
New check_structure_anchor_provisioning audit per spec 1.2a + PHASE2-MAP F7: four states — both anchors present pass (paths reported only); one missing/empty WARNs naming the var with the launchers as authoritative source; neither present emits INFORMATIONAL launcher-equivalent derivation explicitly labeled non-authoritative (never an error by design); doctor never exports, writes, or fabricates values — audit only. Severity follows the doctor's existing note/warn conventions (warn counts toward --fail-on-warn). Hermetic suite follows the test-brain-home-check extraction discipline: 7 arms covering all four states incl. genuinely-unset (env -u) and empty-string forms, plus a mutation red control proving the empty-vs-set distinction bites (-n tests replaced by -v in a mutant copy). Registered in test:framework-shell; enumeration/sanitization/tools-index green.
125 lines
5.4 KiB
Bash
Executable File
125 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Covers the structure-anchor provisioning check in `mosaic-doctor` (T51 WP0b).
|
|
#
|
|
# Same discipline as test-brain-home-check.sh: functions are extracted from the
|
|
# shipped script (exact header + closing brace), never copied — a test carrying
|
|
# its own copy of the logic keeps passing after the shipped copy changes.
|
|
#
|
|
# Four contract states (charter T51P2WP0B-20260824):
|
|
# 1. both present+nonempty -> pass ([OK]), no warns, no notes
|
|
# 2a. host missing, brain set -> warn naming MOSAIC_HOST_ROOT + launchers
|
|
# 2b. brain missing, host set -> warn naming MOSAIC_BRAIN_HOME + launchers
|
|
# 2c. present-but-EMPTY counts as missing (both empty -> state 3; one empty -> state 2)
|
|
# 3. neither present -> informational notes, NON-AUTHORITATIVE, never warn
|
|
# Arms include genuinely-UNSET (env -u) forms, not only empty strings.
|
|
# Red control: empty-vs-unset distinction removed in a mutated copy -> suite red.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR=$(cd -- "$(dirname "$0")" && pwd)
|
|
DOCTOR="$SCRIPT_DIR/mosaic-doctor"
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
[ -f "$DOCTOR" ] || fail "missing mosaic-doctor at $DOCTOR"
|
|
|
|
extract_function() {
|
|
local name="$1"
|
|
local extracted
|
|
extracted=$(sed -n "/^${name}() {/,/^}/p" "$DOCTOR")
|
|
[ -n "$extracted" ] || fail "could not extract ${name}() from mosaic-doctor — script reshaped?"
|
|
printf '%s\n' "$extracted"
|
|
}
|
|
|
|
for fn in check_structure_anchor_provisioning; do
|
|
extract_function "$fn" >/dev/null
|
|
done
|
|
|
|
# run_case LABEL EXPECT(ok|warn|note) [env assignments as args; -u VAR tokens for unset]
|
|
run_case() {
|
|
local label="$1" expect="$2"
|
|
shift 2
|
|
local envs=() unsets=()
|
|
local a
|
|
for a in "$@"; do
|
|
case "$a" in
|
|
-u:*) unsets+=("${a#-u:}") ;;
|
|
*) envs+=("$a") ;;
|
|
esac
|
|
done
|
|
local out warns notes oks
|
|
# build the env command with proper -u flags (array expansion must not
|
|
# glue '-u VAR' into one word)
|
|
local cmd=(env)
|
|
local e u
|
|
# env(1) parses options only before the first assignment — -u flags FIRST
|
|
for u in "${unsets[@]:-}"; do [ -n "$u" ] && cmd+=(-u "$u"); done
|
|
for e in "${envs[@]:-}"; do [ -n "$e" ] && cmd+=("$e"); done
|
|
cmd+=(bash -c "warn() { echo \"[WARN] \$*\"; }; note() { echo \"[NOTE] \$*\"; return 0; }; pass() { echo \"[OK] \$*\"; return 0; }; $(extract_function check_structure_anchor_provisioning); check_structure_anchor_provisioning")
|
|
out=$("${cmd[@]}" 2>&1)
|
|
warns=$(printf '%s\n' "$out" | grep -c '^\[WARN\]' || true)
|
|
notes=$(printf '%s\n' "$out" | grep -c '^\[NOTE\]' || true)
|
|
oks=$(printf '%s\n' "$out" | grep -c '^\[OK\]' || true)
|
|
if [[ "$expect" == ok && "$oks" -gt 0 && "$warns" -eq 0 && "$notes" -eq 0 ]]; then
|
|
echo "ok - $label"
|
|
elif [[ "$expect" == warn && "$warns" -eq 1 ]]; then
|
|
echo "ok - $label (warned)"
|
|
elif [[ "$expect" == note && "$notes" -gt 0 && "$warns" -eq 0 ]]; then
|
|
echo "ok - $label (noted)"
|
|
else
|
|
echo "output: $out" >&2
|
|
fail "$label: expected $expect (oks=$oks warns=$warns notes=$notes)"
|
|
fi
|
|
}
|
|
|
|
ROOT=$(mktemp -d)
|
|
trap 'rm -rf "$ROOT"' EXIT
|
|
HOST="$ROOT/host"
|
|
BRAIN="$ROOT/brain"
|
|
|
|
# ── state 1: both present + nonempty → pass ────────────────────────────────
|
|
run_case "both anchors present passes" ok \
|
|
MOSAIC_HOST_ROOT="$HOST" MOSAIC_BRAIN_HOME="$BRAIN"
|
|
|
|
# ── state 2a: host missing (unset), brain set → exactly one warn ───────────
|
|
run_case "unset host root warns" warn \
|
|
-u:MOSAIC_HOST_ROOT MOSAIC_BRAIN_HOME="$BRAIN"
|
|
|
|
# ── state 2b: brain missing (unset), host set → exactly one warn ───────────
|
|
run_case "unset brain home warns" warn \
|
|
MOSAIC_HOST_ROOT="$HOST" -u:MOSAIC_BRAIN_HOME
|
|
|
|
# ── state 2c-empty: present-but-empty counts as missing ────────────────────
|
|
run_case "empty-string host root warns (empty != set)" warn \
|
|
MOSAIC_HOST_ROOT= MOSAIC_BRAIN_HOME="$BRAIN"
|
|
run_case "empty-string brain home warns (empty != set)" warn \
|
|
MOSAIC_HOST_ROOT="$HOST" MOSAIC_BRAIN_HOME=
|
|
|
|
# ── state 3: neither present (genuinely unset) → notes, never warn ─────────
|
|
run_case "both unset yields non-authoritative notes" note \
|
|
-u:MOSAIC_HOST_ROOT -u:MOSAIC_BRAIN_HOME
|
|
run_case "both empty-string yields non-authoritative notes" note \
|
|
MOSAIC_HOST_ROOT= MOSAIC_BRAIN_HOME=
|
|
|
|
# ── red control (mutation): empty-vs-unset distinction removed → red ───────
|
|
# Mutant replaces the -n tests with plain set-tests, so an EMPTY value counts
|
|
# as present: the empty-host arm above would flip to pass and the suite reds.
|
|
MUT="$ROOT/mosaic-doctor.mutant"
|
|
sed 's/\[\[ -n "$host_root" \&\& -n "$brain_home" \]\]/[[ -v MOSAIC_HOST_ROOT \&\& -v MOSAIC_BRAIN_HOME ]]/' \
|
|
"$DOCTOR" > "$MUT"
|
|
if cmp -s "$DOCTOR" "$MUT"; then
|
|
echo "SKIP red control (mutation anchor not found — sed pattern drifted)" >&2
|
|
else
|
|
outm=$(env MOSAIC_HOST_ROOT= MOSAIC_BRAIN_HOME="$BRAIN" bash -c \
|
|
"warn() { echo \"[WARN] \$*\"; }; note() { echo \"[NOTE] \$*\"; return 0; }; pass() { echo \"[OK] \$*\"; return 0; }; $(sed -n "/^check_structure_anchor_provisioning() {/,/^}/p" "$MUT"); check_structure_anchor_provisioning" 2>&1)
|
|
if printf '%s\n' "$outm" | grep -q '^\[OK\]'; then
|
|
echo "ok - red control bites (mutant treats empty as present; shipped does not)"
|
|
else
|
|
fail "red control did not reproduce the regression shape (mutant output unexpected)"
|
|
fi
|
|
fi
|
|
|
|
echo "structure anchor doctor check: all arms passed"
|