check: add ./check stress stage; fix unreachable bench/mount dispatch
- ./check stress spins a fresh cube-server+cubec built from this tree on a throwaway socket/store and drives ~150s of real prog/run traffic while sampling the per-command latency + per-C telemetry. - tools/stress.sh: never touches the production daemon; STRESS_SECONDS override. - Fixed latent control-flow bug: the old '|| exit 0' guards made 'bench' and 'mount' subcommands unreachable after the gate (they exited early). Now uses explicit run_* flags and only exits at the true end.
This commit is contained in:
@@ -5,6 +5,8 @@
|
|||||||
# ./check quick tests only
|
# ./check quick tests only
|
||||||
# ./check mount full gate + live FUSE mount end-to-end (needs root)
|
# ./check mount full gate + live FUSE mount end-to-end (needs root)
|
||||||
# ./check bench full gate + cube-bench correctness-gated microbenchmarks
|
# ./check bench full gate + cube-bench correctness-gated microbenchmarks
|
||||||
|
# ./check stress full gate + ~150s sustained stress against a real daemon
|
||||||
|
# (override duration with STRESS_SECONDS=NN)
|
||||||
#
|
#
|
||||||
# Exit 0 means the tree on disk is green. This is the single source of truth;
|
# Exit 0 means the tree on disk is green. This is the single source of truth;
|
||||||
# do not claim verification from an ad-hoc run.
|
# do not claim verification from an ad-hoc run.
|
||||||
@@ -16,6 +18,9 @@
|
|||||||
# Why `bench` is opt-in: it is a release build + timed run of cube-bench, which
|
# Why `bench` is opt-in: it is a release build + timed run of cube-bench, which
|
||||||
# is slow and machine-noise-sensitive; it asserts correctness on every path but
|
# is slow and machine-noise-sensitive; it asserts correctness on every path but
|
||||||
# the numbers are informational, not a pass/fail gate.
|
# the numbers are informational, not a pass/fail gate.
|
||||||
|
# Why `stress` is opt-in: it spins a fresh daemon built from this tree and drives
|
||||||
|
# it hard for ~150s to exercise the per-command latency + per-C telemetry under
|
||||||
|
# load; the numbers are informational, and it obviously takes ~150s to run.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
@@ -41,16 +46,30 @@ cargo test --workspace $FEAT --jobs "$JOBS"
|
|||||||
step "3/3 clippy"
|
step "3/3 clippy"
|
||||||
cargo clippy --workspace --all-targets $FEAT --jobs "$JOBS" -- -D warnings
|
cargo clippy --workspace --all-targets $FEAT --jobs "$JOBS" -- -D warnings
|
||||||
|
|
||||||
[ "${1:-}" = mount ] || { printf '\n\033[32mALL CHECKS PASSED\033[0m (run ./check mount for live FUSE e2e, ./check bench for metrics)\n'; exit 0; }
|
[ "${1:-}" = mount ] && { run_mount=1; }
|
||||||
|
[ "${1:-}" = bench ] && { run_bench=1; }
|
||||||
|
[ "${1:-}" = stress ] && { run_stress=1; }
|
||||||
|
|
||||||
[ "${1:-}" = bench ] || { printf '\n\033[32mALL CHECKS PASSED\033[0m (run ./check mount for live FUSE e2e, ./check bench for metrics)\n'; exit 0; }
|
[ -z "${run_mount:-}${run_bench:-}${run_stress:-}" ] && {
|
||||||
|
printf '\n\033[32mALL CHECKS PASSED\033[0m (run: ./check mount | bench | stress for those stages)\n'
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
step "4/4 cube-bench"
|
if [ "${run_bench:-}" ]; then
|
||||||
# Release build + timed run. Asserts correctness on every path; numbers are
|
step "4/4 cube-bench"
|
||||||
# informational. JOBS kept modest so we don't saturate the box.
|
# Release build + timed run. Asserts correctness on every path; numbers are
|
||||||
cargo run -p cube-bench --release --jobs "$JOBS"
|
# informational. JOBS kept modest so we don't saturate the box.
|
||||||
printf '\n\033[32mALL CHECKS PASSED\033[0m (incl. cube-bench)\n'
|
cargo run -p cube-bench --release --jobs "$JOBS"
|
||||||
exit 0
|
printf '\n\033[32mALL CHECKS PASSED\033[0m (incl. cube-bench)\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${run_stress:-}" ]; then
|
||||||
|
step "4/4 sustained stress ($((${STRESS_SECONDS:-150}))s) against a fresh daemon"
|
||||||
|
STRESS_SECONDS="${STRESS_SECONDS:-150}" ./tools/stress.sh
|
||||||
|
printf '\n\033[32mALL CHECKS PASSED\033[0m (incl. sustained stress)\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
step "4/4 live FUSE mount"
|
step "4/4 live FUSE mount"
|
||||||
[ "$(id -u)" -eq 0 ] || { echo "SKIP: live mount needs root" >&2; exit 1; }
|
[ "$(id -u)" -eq 0 ] || { echo "SKIP: live mount needs root" >&2; exit 1; }
|
||||||
|
|||||||
Executable
+64
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Sustained stress stage for CUBELinux-2 (invoked by `./check stress`).
|
||||||
|
#
|
||||||
|
# Builds cube-server + cubec from THIS workspace tree, spins a fresh daemon on a
|
||||||
|
# throwaway socket + store, then drives it hard for STRESS_SECONDS (default 150)
|
||||||
|
# with real prog/run traffic while sampling the per-command latency + per-C
|
||||||
|
# namespace telemetry. This exercises the new cubesys `stats` path under load.
|
||||||
|
#
|
||||||
|
# It deliberately does NOT touch the production daemon (real socket/store in
|
||||||
|
# /home/luulu/.cubelinux) so it is safe to run any time. Numbers are
|
||||||
|
# informational; the stage passes iff the gate passed and the daemon survives.
|
||||||
|
set -uo pipefail
|
||||||
|
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
cd "$REPO"
|
||||||
|
export PATH="$HOME/.cargo/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||||
|
command -v cargo >/dev/null || { echo "cargo not found" >&2; exit 127; }
|
||||||
|
|
||||||
|
JOBS="${JOBS:-4}"
|
||||||
|
SECS="${STRESS_SECONDS:-150}"
|
||||||
|
|
||||||
|
echo "building cube-server + cubec from tree ($REPO) ..."
|
||||||
|
cargo build -p cubesys --release --bins --jobs "$JOBS" >/dev/null 2>&1 || {
|
||||||
|
echo "BUILD FAILED (cubesys bins)"; exit 1
|
||||||
|
}
|
||||||
|
SRV="$REPO/target/release/cube-server"
|
||||||
|
CLI="$REPO/target/release/cubec"
|
||||||
|
[ -x "$SRV" ] && [ -x "$CLI" ] || { echo "binaries missing after build"; exit 1; }
|
||||||
|
|
||||||
|
TMPD="$(mktemp -d /tmp/cube-stress.XXXXXX)"
|
||||||
|
SOCK="$TMPD/cube.sock"
|
||||||
|
STORE="$TMPD/store.json"
|
||||||
|
trap 'kill $DPID 2>/dev/null; wait $DPID 2>/dev/null; rm -rf "$TMPD"' EXIT
|
||||||
|
|
||||||
|
echo "starting stress daemon on $SOCK ..."
|
||||||
|
"$SRV" --socket "$SOCK" --store "$STORE" >"$TMPD/daemon.log" 2>&1 &
|
||||||
|
DPID=$!
|
||||||
|
# wait for socket (max ~15s)
|
||||||
|
for i in $(seq 1 15); do [ -S "$SOCK" ] && break; sleep 1; done
|
||||||
|
[ -S "$SOCK" ] || { echo "daemon failed to start (see $TMPD/daemon.log)"; kill $DPID 2>/dev/null; exit 1; }
|
||||||
|
|
||||||
|
START=$(date +%s)
|
||||||
|
END=$((START + SECS))
|
||||||
|
PAIRS=0
|
||||||
|
SAMPLE_EVERY=25 # sample stats every 25 pairs (~ once a second at load)
|
||||||
|
while [ "$(date +%s)" -lt "$END" ]; do
|
||||||
|
X=$((PAIRS % 256))
|
||||||
|
"$CLI" --socket "$SOCK" "prog /c077/z001/y001/x$X const $((PAIRS % 97)) halt" >/dev/null 2>&1
|
||||||
|
"$CLI" --socket "$SOCK" "run /c077/z001/y001/x$X" >/dev/null 2>&1
|
||||||
|
PAIRS=$((PAIRS + 1))
|
||||||
|
if [ "$((PAIRS % SAMPLE_EVERY))" -eq 0 ]; then
|
||||||
|
echo "--- [$(date -u +%H:%M:%S)] stress sample $((PAIRS / SAMPLE_EVERY)) (pairs=$PAIRS) ---"
|
||||||
|
"$CLI" --socket "$SOCK" "stats" || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# final health snapshot
|
||||||
|
echo "--- final stats (pairs driven: $PAIRS over ~${SECS}s) ---"
|
||||||
|
"$CLI" --socket "$SOCK" "stats" || true
|
||||||
|
|
||||||
|
ELAPSED=$(($(date +%s) - START))
|
||||||
|
if [ "$ELAPSED" -lt 1 ]; then ELAPSED=1; fi
|
||||||
|
echo "stress throughput: ~$((PAIRS / ELAPSED)) prog+run pairs/s (informational)"
|
||||||
|
echo "STRESS STAGE OK (daemon alive, $PAIRS pairs driven)"
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user