From 542e8c74e7051690539889a1dd0197517603e473 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Thu, 3 Jun 2021 18:04:53 -0700 Subject: [PATCH] [dev.fuzz] internal/fuzz: stablize mutator benchmark and add additional benchmarks Adds a few new benchmarks, and attempts to reduce the variability of the existing BenchmarkMutatorBytes benchmark. These should help provide some insight when we're working on performance issues. Change-Id: I45b68ae36da99ec2eb4a610b7a3fc6fbf3d9494a Reviewed-on: https://go-review.googlesource.com/c/go/+/324969 Trust: Roland Shoemaker Trust: Katie Hockman Run-TryBot: Roland Shoemaker Reviewed-by: Katie Hockman TryBot-Result: Go Bot --- src/internal/fuzz/mutator_test.go | 76 +++++++++++++++++++++++++++++-- src/internal/fuzz/worker_test.go | 42 +++++++++++++++++ 2 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/internal/fuzz/worker_test.go diff --git a/src/internal/fuzz/mutator_test.go b/src/internal/fuzz/mutator_test.go index b1b5311639..5fcfb27c16 100644 --- a/src/internal/fuzz/mutator_test.go +++ b/src/internal/fuzz/mutator_test.go @@ -5,11 +5,17 @@ package fuzz import ( + "fmt" + "os" "strconv" "testing" ) func BenchmarkMutatorBytes(b *testing.B) { + origEnv := os.Getenv("GODEBUG") + defer func() { os.Setenv("GODEBUG", origEnv) }() + os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv)) + for _, size := range []int{ 1, 10, @@ -20,10 +26,74 @@ func BenchmarkMutatorBytes(b *testing.B) { } { size := size b.Run(strconv.Itoa(size), func(b *testing.B) { - vals := []interface{}{make([]byte, size)} - m := newMutator() + buf := make([]byte, size) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + // resize buffer to the correct shape and reset the PCG + buf = buf[0:size] + m := newMutator() + m.mutate([]interface{}{buf}, workerSharedMemSize) + } + }) + } +} + +func BenchmarkMutatorString(b *testing.B) { + origEnv := os.Getenv("GODEBUG") + defer func() { os.Setenv("GODEBUG", origEnv) }() + os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv)) + + for _, size := range []int{ + 1, + 10, + 100, + 1000, + 10000, + 100000, + } { + size := size + b.Run(strconv.Itoa(size), func(b *testing.B) { + buf := make([]byte, size) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + // resize buffer to the correct shape and reset the PCG + buf = buf[0:size] + m := newMutator() + m.mutate([]interface{}{string(buf)}, workerSharedMemSize) + } + }) + } +} + +func BenchmarkMutatorAllBasicTypes(b *testing.B) { + origEnv := os.Getenv("GODEBUG") + defer func() { os.Setenv("GODEBUG", origEnv) }() + os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv)) + + types := []interface{}{ + []byte(""), + string(""), + false, + float32(0), + float64(0), + int(0), + int8(0), + int16(0), + int32(0), + int64(0), + uint8(0), + uint16(0), + uint32(0), + uint64(0), + } + + for _, t := range types { + b.Run(fmt.Sprintf("%T", t), func(b *testing.B) { for i := 0; i < b.N; i++ { - m.mutate(vals, workerSharedMemSize) + m := newMutator() + m.mutate([]interface{}{t}, workerSharedMemSize) } }) } diff --git a/src/internal/fuzz/worker_test.go b/src/internal/fuzz/worker_test.go new file mode 100644 index 0000000000..10d61b19db --- /dev/null +++ b/src/internal/fuzz/worker_test.go @@ -0,0 +1,42 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fuzz + +import ( + "context" + "fmt" + "os" + "testing" +) + +func BenchmarkWorkerFuzzOverhead(b *testing.B) { + origEnv := os.Getenv("GODEBUG") + defer func() { os.Setenv("GODEBUG", origEnv) }() + os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv)) + + ws := &workerServer{ + fuzzFn: func(_ CorpusEntry) error { return nil }, + workerComm: workerComm{memMu: make(chan *sharedMem, 1)}, + } + + mem, err := sharedMemTempFile(workerSharedMemSize) + if err != nil { + b.Fatalf("failed to create temporary shared memory file: %s", err) + } + + initialVal := []interface{}{make([]byte, 32)} + encodedVals := marshalCorpusFile(initialVal...) + mem.setValue(encodedVals) + + ws.memMu <- mem + + b.ResetTimer() + for i := 0; i < b.N; i++ { + ws.m = newMutator() + mem.setValue(encodedVals) + + ws.fuzz(context.Background(), fuzzArgs{Limit: 1}) + } +} -- 2.48.1