]> Cypherpunks repositories - gostls13.git/commitdiff
internal/fuzz: fix -fuzzminimizetime with 'x' bug
authorKatie Hockman <katie@golang.org>
Tue, 12 Oct 2021 20:45:40 +0000 (16:45 -0400)
committerKatie Hockman <katie@golang.org>
Tue, 12 Oct 2021 21:30:42 +0000 (21:30 +0000)
Fixes #48928

Change-Id: I3825ec615ab5fc19389ef4c10ad1042005a3761c
Reviewed-on: https://go-review.googlesource.com/c/go/+/355450
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/go/testdata/script/test_fuzz_fuzztime.txt
src/internal/fuzz/fuzz.go

index 7d644b4d13269c6c8f855763cd6020ac4d97677f..9c9972f9e96d3eef9f5f1aba10e93777504b2039 100644 (file)
@@ -16,13 +16,24 @@ exec ./fuzz.test$GOEXE -test.timeout=10ms -test.fuzz=FuzzFast -test.fuzztime=5s
 # Timeout should not cause inputs to be written as crashers.
 ! exists testdata/fuzz
 
+env GOCACHE=$WORK/tmp
+
 # 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.
+# 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
-env GOCACHE=$WORK/tmp
-go test -fuzz=FuzzCount -fuzztime=1000x -fuzzminimizetime=1x
-go run check_file_count.go 1000
+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
@@ -45,7 +56,7 @@ import (
        "testing"
 )
 
-func FuzzCount(f *testing.F) {
+func FuzzTestCount(f *testing.F) {
        pid := os.Getpid()
        n := 0
        f.Fuzz(func(t *testing.T, _ []byte) {
@@ -56,6 +67,36 @@ func FuzzCount(f *testing.F) {
                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
 
@@ -68,13 +109,13 @@ import (
 )
 
 func main() {
-       dir, err := os.ReadDir("count")
+       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[1])
+       want, _ := strconv.Atoi(os.Args[2])
        if got != want {
                fmt.Fprintf(os.Stderr, "got %d files; want %d\n", got, want)
                os.Exit(1)
index a8bbd60b1cc7e3ee33d1fd4317758445439b7ec4..03071d552140103602e1cb89e0d19f982218bb7a 100644 (file)
@@ -825,9 +825,11 @@ func (c *coordinator) peekMinimizeInput() (fuzzMinimizeInput, bool) {
                        }
                }
        }
-       remaining := c.opts.Limit - c.count - c.countWaiting
-       if input.limit > remaining {
-               input.limit = remaining
+       if c.opts.Limit > 0 {
+               remaining := c.opts.Limit - c.count - c.countWaiting
+               if input.limit > remaining {
+                       input.limit = remaining
+               }
        }
        return input, true
 }