github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/testutil/testutil.go (about) 1 // Copyright 2022 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package testutil 5 6 import ( 7 "math/rand" 8 "os" 9 "reflect" 10 "strconv" 11 "testing" 12 "testing/quick" 13 "time" 14 ) 15 16 func IterCount() int { 17 iters := 1000 18 if testing.Short() { 19 iters /= 10 20 } 21 if RaceEnabled { 22 iters /= 10 23 } 24 return iters 25 } 26 27 func RandSource(t *testing.T) rand.Source { 28 seed := time.Now().UnixNano() 29 if fixed := os.Getenv("SYZ_SEED"); fixed != "" { 30 seed, _ = strconv.ParseInt(fixed, 0, 64) 31 } 32 if os.Getenv("CI") != "" { 33 seed = 0 // required for deterministic coverage reports 34 } 35 t.Logf("seed=%v", seed) 36 return rand.NewSource(seed) 37 } 38 39 func RandMountImage(r *rand.Rand) []byte { 40 const maxLen = 1 << 20 // 1 MB. 41 len := r.Intn(maxLen) 42 slice := make([]byte, len) 43 r.Read(slice) 44 return slice 45 } 46 47 // RandValue creates a random value of the same type as the argument typ. 48 // It recursively fills structs/slices/maps similar to testing/quick.Value, 49 // but it handles time.Time as well w/o panicing (unfortunately testing/quick panics on time.Time). 50 func RandValue(t *testing.T, typ any) any { 51 return randValue(t, rand.New(RandSource(t)), reflect.TypeOf(typ)).Interface() 52 } 53 54 func randValue(t *testing.T, rnd *rand.Rand, typ reflect.Type) reflect.Value { 55 v := reflect.New(typ).Elem() 56 switch typ.Kind() { 57 default: 58 ok := false 59 v, ok = quick.Value(typ, rnd) 60 if !ok { 61 t.Fatalf("failed to generate random value of type %v", typ) 62 } 63 case reflect.Slice: 64 size := rand.Intn(4) 65 v.Set(reflect.MakeSlice(typ, size, size)) 66 fallthrough 67 case reflect.Array: 68 for i := 0; i < v.Len(); i++ { 69 v.Index(i).Set(randValue(t, rnd, typ.Elem())) 70 } 71 case reflect.Struct: 72 if typ.String() == "time.Time" { 73 v = reflect.ValueOf(time.UnixMilli(rnd.Int63())) 74 } else { 75 for i := 0; i < v.NumField(); i++ { 76 v.Field(i).Set(randValue(t, rnd, typ.Field(i).Type)) 77 } 78 } 79 case reflect.Pointer: 80 v.SetZero() 81 if rand.Intn(2) == 0 { 82 v.Set(reflect.New(typ.Elem())) 83 v.Elem().Set(randValue(t, rnd, typ.Elem())) 84 } 85 case reflect.Map: 86 v.Set(reflect.MakeMap(typ)) 87 for i := rand.Intn(4); i > 0; i-- { 88 v.SetMapIndex(randValue(t, rnd, typ.Key()), randValue(t, rnd, typ.Elem())) 89 } 90 } 91 return v 92 } 93 94 type Writer struct { 95 testing.TB 96 } 97 98 func (w *Writer) Write(data []byte) (int, error) { 99 w.TB.Logf("%s", data) 100 return len(data), nil 101 }