Remove the R1 slot-controller ties from the C2-14 fixture: the ROW227_CONTROL_ROOT check, the native permit wait in bindLaunch, the fixture-cleanup.json write, the priority.mjs preload and the owned-bwrap.sh override. The launcher uses its own bwrap. The shell runs the driver from an explicit env -i environment (PATH, LANG, a sandbox HOME, XDG dirs and TMPDIR, MOSAIC_CONFIG, no global git config) as its own process group. On a signal the driver gets 3 s by the clock, then its group and any process whose cwd is in the sandbox get SIGKILL, inside the landing gate's 5 s grace. The fixture credentials are defined only in scripts/case2/fixture-credentials.mjs. The new scripts/case2/leak-check.mjs reads them from there and never prints them.
98 lines
4.3 KiB
Bash
Executable File
98 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# C2-14 (#1728, row 227): one acceptance run on a scratch root, no skipped steps.
|
|
# Entry point for the real launcher/runner, C2-06 scripted adapter, fake TLS Gitea and Console DOM.
|
|
# Stands alone: the landing gate runs it as `bash scripts/test-case2.sh` with nothing else set up.
|
|
# The only human stand-in is bindHuman in-process; a development agent cannot prove human CLI ancestry.
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
SANDBOX="$(mktemp -d)"
|
|
DRIVER_PID=''
|
|
CASE2_HOME="$SANDBOX/home"
|
|
CASE2_TMP="$SANDBOX/t"
|
|
CASE2_CONFIG="$SANDBOX/root/config/config.json"
|
|
mkdir -p "$CASE2_HOME" "$CASE2_TMP"
|
|
# The driver runs from an explicit environment: PATH and LANG, a sandbox HOME, XDG dirs and TMPDIR,
|
|
# and the variables it needs. Nothing else from the caller, a credential variable included, reaches
|
|
# the driver or the launcher it starts. TMPDIR in the sandbox takes the Chromium profile and the
|
|
# plug-in tree with it when the sandbox goes.
|
|
CLEAN_ENV=(env -i PATH="$PATH" LANG=C.UTF-8 HOME="$CASE2_HOME"
|
|
XDG_CONFIG_HOME="$CASE2_HOME/.config" XDG_CACHE_HOME="$CASE2_HOME/.cache"
|
|
XDG_DATA_HOME="$CASE2_HOME/.local/share" XDG_STATE_HOME="$CASE2_HOME/.local/state"
|
|
TMPDIR="$CASE2_TMP" MOSAIC_CONFIG="$CASE2_CONFIG" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1)
|
|
alive() {
|
|
local stat
|
|
read -r stat 2>/dev/null <"/proc/$1/stat" || return 1
|
|
stat="${stat##*) }"
|
|
[ "${stat%% *}" != Z ]
|
|
}
|
|
# The driver leads its own process group (setsid below). On a signal it gets SIGTERM and 3 s by the
|
|
# clock to close, inside the landing gate's 5 s grace, then its group gets SIGKILL. The launcher
|
|
# starts each bwrap session in a group of its own, with its working directory in the sandbox; any
|
|
# such process still alive then gets SIGKILL too, before the sandbox goes. One find reads every
|
|
# cwd link, so the sweep stays in milliseconds however many processes the host runs.
|
|
now_us() { echo "${EPOCHREALTIME/[.,]/}"; }
|
|
stop_driver() {
|
|
local deadline p left=0
|
|
if [ -n "$DRIVER_PID" ]; then
|
|
kill -TERM "$DRIVER_PID" 2>/dev/null
|
|
deadline=$(( $(now_us) + 3000000 ))
|
|
while alive "$DRIVER_PID" && [ "$(now_us)" -lt "$deadline" ]; do sleep 0.1; done
|
|
kill -KILL -- "-$DRIVER_PID" 2>/dev/null
|
|
wait "$DRIVER_PID" 2>/dev/null
|
|
DRIVER_PID=''
|
|
fi
|
|
for p in $(find /proc/[0-9]*/cwd -maxdepth 0 \( -lname "$SANDBOX" -o -lname "$SANDBOX/*" \) 2>/dev/null); do
|
|
p="${p#/proc/}"
|
|
kill -KILL "${p%/cwd}" 2>/dev/null && left=$((left+1))
|
|
done
|
|
if [ "$left" -gt 0 ]; then echo "note: $left process(es) under the sandbox outlived the driver; sent SIGKILL"; fi
|
|
}
|
|
cleanup() {
|
|
local result=$?
|
|
trap - EXIT INT TERM
|
|
stop_driver
|
|
rm -rf "$SANDBOX"
|
|
exit "$result"
|
|
}
|
|
trap cleanup EXIT
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
PASS=0 FAIL=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
|
|
STEPS='S1a S1b S2a S2b S2c S2d S3a S3b S3c S4 S5a S5b S6 S7 S8 S9 S10'
|
|
"${CLEAN_ENV[@]}" node --check "$DRIVER" >/dev/null 2>&1
|
|
check "syntax: $DRIVER" "$?"
|
|
OUT="$SANDBOX/steps.txt" ERR="$SANDBOX/stderr.txt"
|
|
"${CLEAN_ENV[@]}" setsid node "$DRIVER" "$SANDBOX/root" >"$OUT" 2>"$ERR" &
|
|
DRIVER_PID=$!
|
|
wait "$DRIVER_PID"
|
|
RC=$?
|
|
DRIVER_PID=''
|
|
check "driver ran to the end (exit $RC)" "$RC"
|
|
if [ "$RC" -ne 0 ]; then 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 ;;
|
|
*) id=''; check 'driver line not understood (a skip cannot pass acceptance)' 1 ;;
|
|
esac
|
|
[ -n "$id" ] && seen="$seen $id"
|
|
done <"$OUT"
|
|
[ "${seen# }" = "$STEPS" ]
|
|
check 'every acceptance step ran once, in order, with nothing skipped' "$?"
|
|
# The values come from scripts/case2/fixture-credentials.mjs and are never printed.
|
|
"${CLEAN_ENV[@]}" node scripts/case2/leak-check.mjs "$OUT" "$ERR"
|
|
check 'fixture credentials are in no driver output' "$?"
|
|
printf '\nselftest: %s passed, %s failed, 0 skipped\n' "$PASS" "$FAIL"
|
|
[ "$FAIL" -eq 0 ]
|