86 lines
3.4 KiB
Bash
Executable File
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
|