#!/usr/bin/env bash # Case 2 end-to-end acceptance on a scratch root (C2-14, #1728, row 227). # # Her layout in a bare repo behind a fake Gitea on 127.0.0.1 (TLS, scratch CA), # a bus on a scratch data root with one creative instance, and the steps of the # C2-14 brief in order. scripts/case2/e2e.mjs runs the steps in one process, # since the remote lives only as long as that process does, and prints one line # per step. This script checks its syntax, runs it, and counts the lines. # # No live host, no real model, no network past 127.0.0.1, no real key. The # human is an in-process stand-in: human-cli.mjs refuses a caller with an agent # among its ancestors, so a seat can't drive it. The creative instance's run is # a fake harness bound by the driver, with no launcher. # # A step that waits on a row not yet on refactor prints a skip line naming the # row, and counts as neither pass nor fail. When the row lands, its step gets # written in the driver and its skip line goes. # # scripts/test-case2.sh full run # NO_COLOR=1 scripts/test-case2.sh plain output set -uo pipefail cd "$(dirname "$0")/.." SANDBOX="$(mktemp -d)" trap 'rm -rf "$SANDBOX"' EXIT PASS=0 FAIL=0 SKIP=0 if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then C_OK=$'\033[0;32m'; C_FAIL=$'\033[0;31m'; C_RESET=$'\033[0m' else C_OK=""; C_FAIL=""; C_RESET="" fi check() { if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $1"; else FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $1"; fi } DRIVER="scripts/case2/e2e.mjs" # The steps the driver must print, in order. A missing or extra line fails. STEPS="S1a S1b S2a S2b S2c S2d S3a S3b S3c S4 S5a S5b S6 S7 S8 S9 S10" echo "toolchain: node $(node --version), git $(git --version | cut -d' ' -f3), openssl $(openssl version | cut -d' ' -f2)" echo # --- syntax --- node --check "$DRIVER" >/dev/null 2>&1 check "syntax: $DRIVER" $? # --- the steps --- # The driver's own state stays in the sandbox. Git reads no global or system # config, so a caller's hooks, signing or credential helpers can't reach it. OUT="$SANDBOX/steps.txt" ERR="$SANDBOX/stderr.txt" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 \ node "$DRIVER" "$SANDBOX/root" >"$OUT" 2>"$ERR" RC=$? check "driver ran to the end (exit $RC)" "$RC" if [ "$RC" -ne 0 ]; then # The driver prints codes and first lines only; never git's stderr with a token in it. grep '^e2e: ' "$ERR" | head -5 fi seen="" while IFS= read -r line; do case "$line" in "ok "*) id="${line#ok }"; id="${id%% *}" check "${line#ok }" 0 ;; "not ok "*) id="${line#not ok }"; id="${id%% *}" check "${line#not ok }" 1 ;; "skip "*) id="${line#skip }"; id="${id%% *}" SKIP=$((SKIP+1)); echo "skip ${line#skip }" ;; *) id="" check "driver line not understood: ${line:0:200}" 1 ;; esac [ -n "$id" ] && seen="$seen $id" done <"$OUT" [ "${seen# }" = "$STEPS" ] check "the driver printed each step once, in order" $? # --- the token --- # The made-up token is in the slot and nowhere else the bus writes. The driver # checks the data root; this checks its output too. ! grep -rqF 'fixture-token-c2-14-made-up-0227' "$OUT" "$ERR" check "the fixture token is in no driver output" $? echo echo "selftest: $PASS passed, $FAIL failed, $SKIP skipped (each skip names the row it waits on)" [ "$FAIL" -eq 0 ]