Files
erofs-freebsd-out-tree/tests/pre15/cases/B01-runner-selftest.sh
T
2026-08-18 09:20:44 +02:00

86 lines
3.4 KiB
Bash
Executable File

#!/bin/sh
set -eu
: "${PRE15_DUT:?PRE15_DUT is required}"
: "${PRE15_CASE_TMP:?PRE15_CASE_TMP is required}"
: "${PRE15_LIB_DIR:?PRE15_LIB_DIR is required}"
. "$PRE15_LIB_DIR/runner.sh"
controls=$PRE15_DUT/tests/pre15/fixtures/B01-runner-controls.json
pre15_record_fixture runner-control-contract "$controls"
pre15_record_fixture evidence-schema "$PRE15_DUT/tests/pre15/EVIDENCE-SCHEMA.json"
command -v qemu-system-x86_64 >/dev/null 2>&1 || \
pre15_infra_blocked 'qemu-system-x86_64 is required for the early-exit control'
command -v ssh >/dev/null 2>&1 || \
pre15_infra_blocked 'ssh is required for the connection-failure control'
pre15_control_run "$PRE15_CASE_TMP/known-good" 5 \
sh -c 'printf "reached\n" > "$PRE15_TARGET_MARKER_FILE"'
pre15_control_run "$PRE15_CASE_TMP/dut-mismatch" 5 \
sh -c 'printf "reached\n" > "$PRE15_TARGET_MARKER_FILE"; exit 10'
pre15_control_run "$PRE15_CASE_TMP/guest-command-failure" 5 sh -c 'exit 1'
pre15_control_run "$PRE15_CASE_TMP/ssh-failure" 5 sh -c \
'if ssh -o BatchMode=yes -o ConnectTimeout=1 -p 1 [email protected] true >/dev/null 2>&1; then exit 20; fi; exit 21'
pre15_control_run "$PRE15_CASE_TMP/qemu-early-exit" 5 sh -c \
'qemu-system-x86_64 --pre15-invalid-option >/dev/null 2>&1; qemu_rc=$?; test "$qemu_rc" -ne 0 || exit 20; exit 21'
timeout_pid_file=$PRE15_CASE_TMP/timeout.pid
export timeout_pid_file
pre15_control_run "$PRE15_CASE_TMP/timeout" 1 sh -c \
'printf "%s\n" "$$" > "$timeout_pid_file"; exec sleep 30'
timeout_pid=$(cat "$timeout_pid_file")
if kill -0 "$timeout_pid" 2>/dev/null; then
pre15_runner_fail "timeout control left PID $timeout_pid alive"
fi
pre15_control_run "$PRE15_CASE_TMP/owned-cleanup" 5 sh -c '
sleep 30 >/dev/null 2>&1 &
owned_pid=$!
printf "pid\t%s\tselftest-owned-sleep\n" "$owned_pid" >> "$PRE15_OWNERSHIP_FILE"
printf "%s\n" "$owned_pid" > "$PRE15_RUN_DIR/owned.pid"
printf "reached\n" > "$PRE15_TARGET_MARKER_FILE"
'
owned_pid=$(cat "$PRE15_CASE_TMP/owned-cleanup/owned.pid")
if kill -0 "$owned_pid" 2>/dev/null; then
pre15_runner_fail "owned cleanup left PID $owned_pid alive"
fi
outside_path=$PRE15_CASE_TMP/cleanup-must-refuse
printf 'owned by outer selftest\n' > "$outside_path"
export outside_path
pre15_control_run "$PRE15_CASE_TMP/cleanup-failure" 5 sh -c '
printf "path\t%s\toutside-control-boundary\n" "$outside_path" >> "$PRE15_OWNERSHIP_FILE"
printf "reached\n" > "$PRE15_TARGET_MARKER_FILE"
'
test -f "$outside_path" || \
pre15_runner_fail 'cleanup safety control deleted a non-owned path'
python3 - "$controls" "$PRE15_CASE_TMP" <<'PY'
import json
from pathlib import Path
import sys
contract = json.loads(Path(sys.argv[1]).read_text(encoding="ascii"))["controls"]
root = Path(sys.argv[2])
for name, expected in contract.items():
actual = (root / name / "result.tsv").read_text(encoding="ascii").rstrip("\n").split("\t")
if actual != expected:
raise SystemExit(f"{name}: {actual!r}, expected {expected!r}")
print(f"{name}: status={actual[0]} origin={actual[1]} cleanup={actual[2]} timeout={actual[3]}")
PY
mkdir -p "$PRE15_RUN_DIR/artifacts/controls"
for control in \
cleanup-failure dut-mismatch guest-command-failure known-good \
owned-cleanup qemu-early-exit ssh-failure timeout; do
mkdir "$PRE15_RUN_DIR/artifacts/controls/$control"
cp "$PRE15_CASE_TMP/$control/result.tsv" \
"$PRE15_CASE_TMP/$control/stdout.log" \
"$PRE15_CASE_TMP/$control/stderr.log" \
"$PRE15_CASE_TMP/$control/cleanup.log" \
"$PRE15_RUN_DIR/artifacts/controls/$control/"
done
pre15_target_reached