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
|
// Copyright 2022 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package testutil
import (
"math/rand"
"os"
"reflect"
"strconv"
"testing"
"testing/quick"
"time"
)
func IterCount() int {
iters := 1000
if testing.Short() {
iters /= 10
}
if RaceEnabled {
iters /= 10
}
return iters
}
func RandSource(t *testing.T) rand.Source {
seed := time.Now().UnixNano()
if fixed := os.Getenv("SYZ_SEED"); fixed != "" {
seed, _ = strconv.ParseInt(fixed, 0, 64)
}
if os.Getenv("CI") != "" {
seed = 0 // required for deterministic coverage reports
}
t.Logf("seed=%v", seed)
return rand.NewSource(seed)
}
func RandMountImage(r *rand.Rand) []byte {
const maxLen = 1 << 20 // 1 MB.
len := r.Intn(maxLen)
slice := make([]byte, len)
r.Read(slice)
return slice
}
// RandValue creates a random value of the same type as the argument typ.
// It recursively fills structs/slices/maps similar to testing/quick.Value,
// but it handles time.Time as well w/o panicing (unfortunately testing/quick panics on time.Time).
func RandValue(t *testing.T, typ any) any {
return randValue(t, rand.New(RandSource(t)), reflect.TypeOf(typ)).Interface()
}
func randValue(t *testing.T, rnd *rand.Rand, typ reflect.Type) reflect.Value {
v := reflect.New(typ).Elem()
switch typ.Kind() {
default:
ok := false
v, ok = quick.Value(typ, rnd)
if !ok {
t.Fatalf("failed to generate random value of type %v", typ)
}
case reflect.Slice:
size := rand.Intn(4)
v.Set(reflect.MakeSlice(typ, size, size))
fallthrough
case reflect.Array:
for i := 0; i < v.Len(); i++ {
v.Index(i).Set(randValue(t, rnd, typ.Elem()))
}
case reflect.Struct:
if typ.String() == "time.Time" {
v = reflect.ValueOf(time.UnixMilli(rnd.Int63()))
} else {
for i := 0; i < v.NumField(); i++ {
v.Field(i).Set(randValue(t, rnd, typ.Field(i).Type))
}
}
case reflect.Pointer:
v.SetZero()
if rand.Intn(2) == 0 {
v.Set(reflect.New(typ.Elem()))
v.Elem().Set(randValue(t, rnd, typ.Elem()))
}
case reflect.Map:
v.Set(reflect.MakeMap(typ))
for i := rand.Intn(4); i > 0; i-- {
v.SetMapIndex(randValue(t, rnd, typ.Key()), randValue(t, rnd, typ.Elem()))
}
}
return v
}
type Writer struct {
testing.TB
}
func (w *Writer) Write(data []byte) (int, error) {
w.TB.Logf("%s", data)
return len(data), nil
}
|