summaryrefslogtreecommitdiff
path: root/maint/fuzz-it-all
blob: 8ed738a5298219fecaca493710a027af0ef082ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env bash
#
# Build every fuzzer; run them on the testing corpus, and then run them
# in a loop.

set -euo pipefail

usage() {
    echo "Usage: $0 [-d <minutes>] [-n] [-c] [-u] [-h]"
    echo "  -d <minutes>: Switch fuzzers every <minutes>."
    echo "  -h          : Display this message and exit."
    echo "  -n          : Stop after building fuzzers and testing corpus."
    echo "  -c          : Check fuzzers ('cargo fuzz check') and exit."
    echo "  -u          : Update Cargo.lock files in fuzz directories."
}

CHECK_FUZZERS=no
RUN_FUZZERS=yes
DURATION=20
UPDATE=no

while getopts "d:hncu" opt; do
    case "$opt" in
	h)
	    usage
	    exit 0
	    ;;
	n)
	    RUN_FUZZERS=no
	    ;;
	c)
	    CHECK_FUZZERS=yes
	    ;;
	d)
	    DURATION="$OPTARG"
	    ;;
	u)
	    UPDATE=yes
	    ;;
	*)
	    usage
	    exit 1;
	    ;;
    esac
done

echo "Using toolchain +${RUST_FUZZ_TOOLCHAIN:=nightly}. (Override with \$RUST_FUZZ_TOOLCHAIN)"

# Validate that "+${RUST_FUZZ_TOOLCHAIN}" is installed.  This will log a message to stderr
# if it isn't.
cargo "+${RUST_FUZZ_TOOLCHAIN}" -h >/dev/null

# Validate that "cargo fuzz" is installed.
cargo "+${RUST_FUZZ_TOOLCHAIN}" fuzz --help>/dev/null


# Chdir to the source root directory, and make sure we have the corpora checked out.
cd "$(dirname "$0")/.."

if ! test -d "./arti-corpora"; then
    echo "Did not find 'arti-corpora' directory in $(pwd). Cannot proceed." 1>&2
    exit 1
fi



# CHECK ONLY: If requested, check every fuzzer and exit.
if test "$CHECK_FUZZERS" = "yes"; then
    for d in ./crates/*/fuzz; do
	pushd "$(dirname "$d")"
	if test "$UPDATE" = yes; then
	    cargo update
	fi
	for fuzzer in $(cargo fuzz list); do
	    cargo "+${RUST_FUZZ_TOOLCHAIN}" fuzz check "$fuzzer"
	done
	popd
    done
    exit 0
fi

# STEP 1: Build every fuzzer.
for d in ./crates/*/fuzz; do
    pushd "$(dirname "$d")"
    if test "$UPDATE" = yes; then
	cargo update
    fi
    for fuzzer in $(cargo fuzz list); do

	# TODO: Should we do a cargo update? for the fuzzer's cargo.lock?
	cargo "+${RUST_FUZZ_TOOLCHAIN}" fuzz build "$fuzzer"
    done
    popd
done

# STEP 2: Run static test cases

for d in ./crates/*/fuzz; do
    pushd "$(dirname "$d")"
    for fuzzer in $(cargo fuzz list); do
	echo "Running fuzzer '$fuzzer' on static testcases"
	# "-runs=0" means that we won't actually do any additional fuzzing
	# after we load the corpus.
	cargo "+${RUST_FUZZ_TOOLCHAIN}" fuzz run "$fuzzer" -- \
	      -runs=0
    done
    popd
done

if test "$RUN_FUZZERS" = "no"; then
    exit 0
fi

# STEP 3: Run every fuzzer in a loop, for a while, then switch to the next one.

#JOBS=4
#SEED=0

while true; do
    for d in ./crates/*/fuzz; do
	pushd "$(dirname "$d")"
	for fuzzer in $(cargo fuzz list); do
	    cargo "+${RUST_FUZZ_TOOLCHAIN}" fuzz run "$fuzzer" -- \
		-jobs="${JOBS:-0}" \
		-workers="${JOBS:-0}" \
		-max_total_time=$((DURATION * 60)) \
		-seed="${SEED:-0}"
	done
	popd
    done
done