mirror of
https://github.com/lgcosta/pf-linux-port.git
synced 2026-11-13 07:48:03 -03:00
Gate 16 asserts invariants under load: states tracked under concurrent connections and drained again, 200 ruleset reloads without failure, 2000 table entries flushed back to zero, 2 MB intact through NAT under a concurrent stream, no kernel faults. Throughput is measured and reported rather than gated, and the traffic phases run at a bounded rate because the PF workqueue backlog exhausts a 1 GB guest above ~1 Gbit/s. The runner writes out/stress/<timestamp>/report.md and captures the guest serial console so a panic stays diagnosable.
119 lines
4.3 KiB
Bash
Executable File
119 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# run-stress.sh — drive the PF stress test (tests/vm/16-stress.sh) against the
|
|
# libvirt lab and turn the metrics into a report.
|
|
#
|
|
# ./scripts/stress/run-stress.sh # default profile
|
|
# ./scripts/stress/run-stress.sh --quick # smaller profile (smoke)
|
|
# ./scripts/stress/run-stress.sh --seconds 30 --connections 1000
|
|
#
|
|
# Output: out/stress/<timestamp>/report.md (+ the raw gate log).
|
|
# Exit status: 0 when every stress phase passed, 1 otherwise.
|
|
set -uo pipefail
|
|
REPO="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
DEB="${DEB:-root@192.168.1.242}"
|
|
PF0_IP=192.168.122.8
|
|
TS="$(date +%Y%m%d-%H%M%S)"
|
|
OUTD="$REPO/out/stress/$TS"
|
|
mkdir -p "$OUTD"
|
|
|
|
SECS=10
|
|
PAR=4
|
|
RATE=100M
|
|
CONNS=300
|
|
RELOADS=200
|
|
RULES=200
|
|
TENTRIES=2000
|
|
MAXOH=30
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--quick) SECS=5; CONNS=100; RELOADS=50; RULES=50; TENTRIES=500; shift ;;
|
|
--seconds) SECS=$2; shift 2 ;;
|
|
--parallel) PAR=$2; shift 2 ;;
|
|
--rate) RATE=$2; shift 2 ;;
|
|
--connections) CONNS=$2; shift 2 ;;
|
|
--reloads) RELOADS=$2; shift 2 ;;
|
|
--rules) RULES=$2; shift 2 ;;
|
|
--table-entries) TENTRIES=$2; shift 2 ;;
|
|
--max-overhead) MAXOH=$2; shift 2 ;;
|
|
-h|--help) sed -n '2,12p' "$0"; exit 0 ;;
|
|
*) echo "unknown option: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
SSH="ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=8 -i /root/.ssh/pflab_ed root@$PF0_IP"
|
|
|
|
echo "pflab stress: profile seconds=$SECS parallel=$PAR rate/stream=$RATE connections=$CONNS reloads=$RELOADS rules=$RULES table_entries=$TENTRIES max_overhead=$MAXOH%"
|
|
|
|
echo "pflab stress: resetting pftest-pf0"
|
|
ssh "$DEB" "virsh destroy pftest-pf0 >/dev/null 2>&1; virsh start pftest-pf0 >/dev/null" || {
|
|
echo "pflab stress FAIL: cannot restart pftest-pf0" >&2; exit 1; }
|
|
up=0
|
|
for i in $(seq 1 20); do
|
|
sleep 6
|
|
if ssh "$DEB" "$SSH true" 2>/dev/null; then up=1; break; fi
|
|
done
|
|
[ "$up" = 1 ] || { echo "pflab stress FAIL: pf0 never came back" >&2; exit 1; }
|
|
|
|
echo "pflab stress: deploying pf.ko + pfctl to pf0:/opt/pf"
|
|
for i in 1 2 3; do
|
|
if scp -q -o ProxyJump=root@192.168.1.242 -o StrictHostKeyChecking=accept-new \
|
|
-i "$HOME/.ssh/pflab_ed" "$REPO/module/pf.ko" "$REPO/tools/out/pfctl" \
|
|
"$REPO/tools/out/pdivert" "$REPO/tools/out/pflogd" pf0:/tmp/ 2>/dev/null; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
ssh "$DEB" "$SSH 'mkdir -p /opt/pf; mv /tmp/pf.ko /tmp/pfctl /tmp/pdivert /tmp/pflogd /opt/pf/ 2>/dev/null; chmod +x /opt/pf/pfctl 2>/dev/null; true'" >/dev/null
|
|
ssh "$DEB" "$SSH 'test -s /opt/pf/pf.ko && test -x /opt/pf/pfctl'" >/dev/null 2>&1 || {
|
|
echo "pflab stress FAIL: pf.ko/pfctl missing on pf0" >&2; exit 1; }
|
|
|
|
echo "pflab stress: running the stress gate"
|
|
# The guest's serial console is a pty: a panic or a hang is lost when the VM
|
|
# reboots. Capture it on the hypervisor (the redirect happens *there*) and
|
|
# copy it back when the run ends.
|
|
REMOTE_CONSOLE="/tmp/pf0-console-$TS.log"
|
|
ssh "$DEB" "PTY=\$(virsh ttyconsole pftest-pf0); setsid nohup timeout 1800 cat \$PTY >$REMOTE_CONSOLE 2>&1 </dev/null &" >/dev/null 2>&1
|
|
sleep 2
|
|
export STRESS_SECS="$SECS" STRESS_PARALLEL="$PAR" STRESS_RATE="$RATE" STRESS_CONNS="$CONNS" \
|
|
STRESS_RELOADS="$RELOADS" STRESS_RULES="$RULES" \
|
|
STRESS_TABLE_ENTRIES="$TENTRIES" STRESS_MAX_OVERHEAD_PCT="$MAXOH"
|
|
bash "$REPO/tests/vm/16-stress.sh" >"$OUTD/16-stress.sh.log" 2>&1
|
|
RC=$?
|
|
|
|
# --- report ----------------------------------------------------------------
|
|
scp -q -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$DEB:$REMOTE_CONSOLE" \
|
|
"$OUTD/pf0-console.log" 2>/dev/null || true
|
|
{
|
|
echo "# PF-on-Linux — stress report"
|
|
echo
|
|
echo "- date: $(date -Is)"
|
|
echo "- profile: seconds=$SECS parallel=$PAR rate/stream=$RATE connections=$CONNS reloads=$RELOADS rules=$RULES table_entries=$TENTRIES max_overhead=${MAXOH}%"
|
|
echo "- exit status: $RC"
|
|
echo "- guest serial console: \`pf0-console.log\` (kernel messages during the run)"
|
|
echo
|
|
echo "## Phases"
|
|
echo
|
|
echo '```'
|
|
grep '^STRESS ' "$OUTD/16-stress.sh.log" || echo "(no metrics captured)"
|
|
echo '```'
|
|
echo
|
|
echo "## Assertions"
|
|
echo
|
|
echo '```'
|
|
grep -E '^(OK|NOT OK)' "$OUTD/16-stress.sh.log" || echo "(no assertions)"
|
|
echo '```'
|
|
} >"$OUTD/report.md"
|
|
|
|
echo
|
|
echo "pflab stress: report -> out/stress/$TS/report.md"
|
|
grep '^STRESS ' "$OUTD/16-stress.sh.log" || true
|
|
echo
|
|
if [ $RC -eq 0 ]; then
|
|
echo "STRESS RESULT: PASS"
|
|
else
|
|
echo "STRESS RESULT: FAIL (rc=$RC)"
|
|
sed -n '/^NOT OK/p' "$OUTD/16-stress.sh.log" | sed 's/^/ /'
|
|
fi
|
|
exit $RC
|