1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package fuzz
6
7import (
8	"bytes"
9	"fmt"
10	"os"
11	"strconv"
12	"testing"
13)
14
15func BenchmarkMutatorBytes(b *testing.B) {
16	origEnv := os.Getenv("GODEBUG")
17	defer func() { os.Setenv("GODEBUG", origEnv) }()
18	os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv))
19	m := newMutator()
20
21	for _, size := range []int{
22		1,
23		10,
24		100,
25		1000,
26		10000,
27		100000,
28	} {
29		b.Run(strconv.Itoa(size), func(b *testing.B) {
30			buf := make([]byte, size)
31			b.ResetTimer()
32
33			for i := 0; i < b.N; i++ {
34				// resize buffer to the correct shape and reset the PCG
35				buf = buf[0:size]
36				m.r = newPcgRand()
37				m.mutate([]any{buf}, workerSharedMemSize)
38			}
39		})
40	}
41}
42
43func BenchmarkMutatorString(b *testing.B) {
44	origEnv := os.Getenv("GODEBUG")
45	defer func() { os.Setenv("GODEBUG", origEnv) }()
46	os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv))
47	m := newMutator()
48
49	for _, size := range []int{
50		1,
51		10,
52		100,
53		1000,
54		10000,
55		100000,
56	} {
57		b.Run(strconv.Itoa(size), func(b *testing.B) {
58			buf := make([]byte, size)
59			b.ResetTimer()
60
61			for i := 0; i < b.N; i++ {
62				// resize buffer to the correct shape and reset the PCG
63				buf = buf[0:size]
64				m.r = newPcgRand()
65				m.mutate([]any{string(buf)}, workerSharedMemSize)
66			}
67		})
68	}
69}
70
71func BenchmarkMutatorAllBasicTypes(b *testing.B) {
72	origEnv := os.Getenv("GODEBUG")
73	defer func() { os.Setenv("GODEBUG", origEnv) }()
74	os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv))
75	m := newMutator()
76
77	types := []any{
78		[]byte(""),
79		string(""),
80		false,
81		float32(0),
82		float64(0),
83		int(0),
84		int8(0),
85		int16(0),
86		int32(0),
87		int64(0),
88		uint8(0),
89		uint16(0),
90		uint32(0),
91		uint64(0),
92	}
93
94	for _, t := range types {
95		b.Run(fmt.Sprintf("%T", t), func(b *testing.B) {
96			for i := 0; i < b.N; i++ {
97				m.r = newPcgRand()
98				m.mutate([]any{t}, workerSharedMemSize)
99			}
100		})
101	}
102}
103
104func TestStringImmutability(t *testing.T) {
105	v := []any{"hello"}
106	m := newMutator()
107	m.mutate(v, 1024)
108	original := v[0].(string)
109	originalCopy := make([]byte, len(original))
110	copy(originalCopy, []byte(original))
111	for i := 0; i < 25; i++ {
112		m.mutate(v, 1024)
113	}
114	if !bytes.Equal([]byte(original), originalCopy) {
115		t.Fatalf("string was mutated: got %x, want %x", []byte(original), originalCopy)
116	}
117}
118