File size: 3,239 Bytes
e36aeda | 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 | skip # a 5s timeout is never going to be reliable (go.dev/issue/72140)
[!fuzz] skip
[short] skip
env GOCACHE=$WORK/cache
# There are no seed values, so 'go test' should finish quickly.
go test
# For the fuzzing phase, we reduce GOMAXPROCS to avoid consuming too many
# resources during the test. Ideally this would just free up resources to run
# other parallel tests more quickly, but unfortunately it is actually necessary
# in some 32-bit environments to prevent the fuzzing engine from running out of
# address space (see https://go.dev/issue/65434).
env GOMAXPROCS=2
# Fuzzing should exit 0 after fuzztime, even if timeout is short.
go test -timeout=3s -fuzz=FuzzFast -fuzztime=5s
# We should see the same behavior when invoking the test binary directly.
go test -c
exec ./fuzz.test$GOEXE -test.timeout=3s -test.fuzz=FuzzFast -test.fuzztime=5s -test.parallel=1 -test.fuzzcachedir=$WORK/cache
# Timeout should not cause inputs to be written as crashers.
! exists testdata/fuzz
# When we use fuzztime with an "x" suffix, it runs a specific number of times.
# This fuzz function creates a file with a unique name ($pid.$count) on each
# run. We count the files to find the number of runs.
mkdir count
go test -fuzz=FuzzTestCount -fuzztime=1000x -fuzzminimizetime=1x
go run check_file_count.go count 1000
# When we use fuzzminimizetime with an "x" suffix, it runs a specific number of
# times while minimizing. This fuzz function creates a file with a unique name
# ($pid.$count) on each run once the first crash has been found. That means that
# there should be one file for each execution of the fuzz function during
# minimization, so we count these to determine how many times minimization was
# run.
mkdir minimizecount
! go test -fuzz=FuzzMinimizeCount -fuzzminimizetime=3x -parallel=1
go run check_file_count.go minimizecount 3
-- go.mod --
module fuzz
go 1.16
-- fuzz_fast_test.go --
package fuzz_test
import "testing"
func FuzzFast(f *testing.F) {
f.Fuzz(func (*testing.T, []byte) {})
}
-- fuzz_count_test.go --
package fuzz
import (
"fmt"
"os"
"testing"
)
func FuzzTestCount(f *testing.F) {
pid := os.Getpid()
n := 0
f.Fuzz(func(t *testing.T, _ []byte) {
name := fmt.Sprintf("count/%v.%d", pid, n)
if err := os.WriteFile(name, nil, 0666); err != nil {
t.Fatal(err)
}
n++
})
}
-- fuzz_minimize_count_test.go --
package fuzz
import (
"bytes"
"fmt"
"os"
"testing"
)
func FuzzMinimizeCount(f *testing.F) {
pid := os.Getpid()
n := 0
seed := bytes.Repeat([]byte("a"), 357)
f.Add(seed)
crashFound := false
f.Fuzz(func(t *testing.T, b []byte) {
if crashFound {
name := fmt.Sprintf("minimizecount/%v.%d", pid, n)
if err := os.WriteFile(name, nil, 0666); err != nil {
t.Fatal(err)
}
n++
}
if !bytes.Equal(b, seed) { // this should happen right away
crashFound = true
t.Error("minimize this!")
}
})
}
-- check_file_count.go --
// +build ignore
package main
import (
"fmt"
"os"
"strconv"
)
func main() {
dir, err := os.ReadDir(os.Args[1])
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
got := len(dir)
want, _ := strconv.Atoi(os.Args[2])
if got != want {
fmt.Fprintf(os.Stderr, "got %d files; want %d\n", got, want)
os.Exit(1)
}
}
|