mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
144 lines
5.9 KiB
Bash
Executable File
144 lines
5.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# Pressure profiles for the mesh-lab. Sourced by run-loop.sh.
|
|
#
|
|
# Each profile is a function `pressure_start_<name>` that spawns
|
|
# stress-ng (or whatever) in the background and writes its PID to the
|
|
# variable PRESSURE_PIDS (a bash array). The harness uses
|
|
# `pressure_stop` (defined at the bottom) to kill everything cleanly.
|
|
#
|
|
# Profiles are intentionally simple stubs until calibrated against
|
|
# actual reproduction of a known flake class.
|
|
|
|
set -u
|
|
|
|
PRESSURE_PIDS=()
|
|
|
|
# Track which profile is active for the summary.json.
|
|
PRESSURE_PROFILE_ACTIVE="idle"
|
|
|
|
# ── idle ─────────────────────────────────────────────────────────────
|
|
# No pressure. Baseline. A healthy mesh should run all reps green on
|
|
# this profile; failures here are a different bug class than what the
|
|
# lab is built to chase.
|
|
|
|
pressure_start_idle() {
|
|
PRESSURE_PROFILE_ACTIVE="idle"
|
|
# nothing to do
|
|
}
|
|
|
|
# ── light ────────────────────────────────────────────────────────────
|
|
# Single stress-ng cpu worker at ~50% load. Placeholder; calibration
|
|
# will determine the right intensity for surfacing tail behavior
|
|
# without saturating the host.
|
|
|
|
pressure_start_light() {
|
|
PRESSURE_PROFILE_ACTIVE="light"
|
|
require_stress_ng || return 1
|
|
stress-ng --cpu 1 --cpu-load 50 --quiet &
|
|
PRESSURE_PIDS+=("$!")
|
|
}
|
|
|
|
# ── github-runner-equivalent ────────────────────────────────────────
|
|
# Calibrated to approximate the headroom a 2-core GitHub Actions
|
|
# ubuntu-latest runner has when also juggling four concurrent package-
|
|
# build workflows. Target effective per-host load: ~75% of cores
|
|
# consumed, ~30% of RAM allocated, so the test+daemon containers
|
|
# compete for ~2 effective cores and ~7-8 GiB headroom — close to a
|
|
# runner under quad-package-build contention.
|
|
#
|
|
# Calibration target: ≥20% mechanism-match rate over 5-rep pilots on
|
|
# the `rekey` suite. Calibration history (host = 8c/62GiB):
|
|
#
|
|
# 2026-05-16 first cut --cpu 1 --vm 1 --vm-bytes 512m
|
|
# 25 reps, 1 mechanism-match (4%)
|
|
# (stochastic pilot fire; not contention-driven)
|
|
# 2026-05-16 second cut --cpu 6 --vm 2 --vm-bytes 10g
|
|
# 5 reps, 0 mechanism-match
|
|
# (host load=8.25/8 cores, 20GiB resident; the
|
|
# mechanism did not surface even at saturation)
|
|
#
|
|
# Layered with the mesh-lab/compose-resource-limits.yml override
|
|
# (per-daemon cpus=0.3 + mem_limit=1g) and in-container tc qdisc netem
|
|
# (10ms ± 5ms delay + 1% loss), the rekey Phase 5 mechanism still did
|
|
# not reproduce above the stub's stochastic baseline on this host —
|
|
# implying the GHA fires are more likely code-side (tokio task stall,
|
|
# channel backpressure, mutex contention) than environment-side.
|
|
|
|
pressure_start_github_runner_equivalent() {
|
|
PRESSURE_PROFILE_ACTIVE="github-runner-equivalent"
|
|
require_stress_ng || return 1
|
|
# CPU pressure: six full-load cpu workers (75% of an 8-core host).
|
|
# On smaller hosts the per-worker share rises; on larger hosts the
|
|
# absolute headroom rises proportionally — the profile is anchored
|
|
# to "what's left after the pressure," not to a target host size.
|
|
stress-ng --cpu 6 --quiet &
|
|
PRESSURE_PIDS+=("$!")
|
|
# Memory pressure: two vm workers, 20 GiB total resident. Sized to
|
|
# eat ~30% of a 62 GiB host. --vm-keep holds pages resident rather
|
|
# than churning the allocator, which mirrors a peer workflow that
|
|
# has allocated and is using its working set, not one trashing it.
|
|
stress-ng --vm 2 --vm-bytes 10g --vm-keep --quiet &
|
|
PRESSURE_PIDS+=("$!")
|
|
}
|
|
|
|
# ── heavy ────────────────────────────────────────────────────────────
|
|
# Two cpu workers + memory pressure. Worst-case profile for stall-
|
|
# finding work once the milder profiles are characterized.
|
|
|
|
pressure_start_heavy() {
|
|
PRESSURE_PROFILE_ACTIVE="heavy"
|
|
require_stress_ng || return 1
|
|
stress-ng --cpu 2 --quiet &
|
|
PRESSURE_PIDS+=("$!")
|
|
stress-ng --vm 1 --vm-bytes 1g --vm-keep --quiet &
|
|
PRESSURE_PIDS+=("$!")
|
|
}
|
|
|
|
# ── helpers ──────────────────────────────────────────────────────────
|
|
|
|
require_stress_ng() {
|
|
if ! command -v stress-ng >/dev/null 2>&1; then
|
|
echo " ERROR: stress-ng not installed; cannot run pressure profile '$PRESSURE_PROFILE_ACTIVE'" >&2
|
|
echo " install on Debian/Ubuntu: sudo apt-get install stress-ng" >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
pressure_start() {
|
|
local profile="$1"
|
|
PRESSURE_PIDS=()
|
|
case "$profile" in
|
|
idle)
|
|
pressure_start_idle ;;
|
|
light)
|
|
pressure_start_light ;;
|
|
github-runner-equivalent | github | gha)
|
|
pressure_start_github_runner_equivalent ;;
|
|
heavy)
|
|
pressure_start_heavy ;;
|
|
*)
|
|
echo " ERROR: unknown pressure profile '$profile'" >&2
|
|
echo " available: idle, light, github-runner-equivalent, heavy" >&2
|
|
return 1 ;;
|
|
esac
|
|
}
|
|
|
|
pressure_stop() {
|
|
if [ "${#PRESSURE_PIDS[@]}" -eq 0 ]; then
|
|
return 0
|
|
fi
|
|
for pid in "${PRESSURE_PIDS[@]}"; do
|
|
# kill the process group; stress-ng spawns children
|
|
kill -TERM "-$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
|
|
done
|
|
# Brief grace, then SIGKILL stragglers
|
|
sleep 1
|
|
for pid in "${PRESSURE_PIDS[@]}"; do
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill -KILL "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
PRESSURE_PIDS=()
|
|
}
|