1#!/bin/sh
2# Soaks a dedicated machine until stopped: each round runs every seeded sweep in full with
3# a fresh seed shift, then each fuzz target for a time limit. A failing round leaves its
4# log in soak/ with the command that replays it; libFuzzer keeps crash inputs in
5# fuzz/artifacts/<target>/.
6#
7# tools/soak.sh [seconds per fuzz target, default 600]
8set -u
9cd "$(dirname "$0")/.."
10seconds=${1:-600}
11mkdir -p soak
12# Release speed with the checks debug builds make.
13sweeps="cargo test --release --no-fail-fast --config profile.release.debug-assertions=true --config profile.release.overflow-checks=true -p onestore -p notebook -p canvas"
14$sweeps --no-run || exit 1
15cargo +nightly fuzz build || exit 1
16while :; do
17 shift=$(od -An -N4 -tu4 /dev/urandom | tr -d ' ')
18 log=soak/sweep-$shift.log
19 if SNOWBOUND_SWEEP=$shift $sweeps >"$log" 2>&1; then
20 rm "$log"
21 else
22 echo "replay: SNOWBOUND_SWEEP=$shift $sweeps" | tee -a "$log"
23 sed -n 's/^---- \(.*\) stdout ----$/\1/p' "$log" | while read -r name; do
24 echo "replay: SNOWBOUND_SWEEP=$shift $sweeps -- --exact $name" | tee -a "$log"
25 done
26 fi
27 for target in $(cargo +nightly fuzz list); do
28 log=soak/fuzz-$target-$(date +%Y%m%d-%H%M%S).log
29 if cargo +nightly fuzz run "$target" -- -max_total_time="$seconds" >"$log" 2>&1; then
30 rm "$log"
31 else
32 grep 'cargo fuzz run' "$log" | sed 's/^[[:space:]]*/replay: /' | tee -a "$log"
33 fi
34 done
35done