github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/corpus/prio_test.go (about) 1 // Copyright 2024 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 corpus 5 6 import ( 7 "context" 8 "math" 9 "math/rand" 10 "testing" 11 12 "github.com/google/syzkaller/prog" 13 "github.com/google/syzkaller/sys/targets" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestChooseProgram(t *testing.T) { 18 rs := rand.NewSource(0) 19 r := rand.New(rs) 20 target := getTarget(t, targets.TestOS, targets.TestArch64) 21 corpus := NewCorpus(context.Background()) 22 23 const ( 24 maxIters = 1000 25 sizeCorpus = 1000 26 eps = 0.01 27 ) 28 29 priorities := make(map[*prog.Prog]int64) 30 for i := 0; i < sizeCorpus; i++ { 31 sizeSig := i + 1 32 if sizeSig%250 == 0 { 33 sizeSig = 0 34 } 35 inp := generateInput(target, rs, sizeSig) 36 corpus.Save(inp) 37 priorities[inp.Prog] = int64(len(inp.Signal)) 38 } 39 counters := make(map[*prog.Prog]int) 40 for it := 0; it < maxIters; it++ { 41 counters[corpus.chooseProgram(r)]++ 42 } 43 for p, prio := range priorities { 44 prob := float64(prio) / float64(corpus.sumPrios) 45 diff := math.Abs(prob*maxIters - float64(counters[p])) 46 if diff > eps*maxIters { 47 t.Fatalf("the difference (%f) is higher than %f%%", diff, eps*100) 48 } 49 } 50 } 51 52 func TestFocusAreas(t *testing.T) { 53 target := getTarget(t, targets.TestOS, targets.TestArch64) 54 corpus := NewFocusedCorpus(context.Background(), nil, []FocusArea{ 55 { 56 CoverPCs: map[uint64]struct{}{ 57 0: {}, 58 1: {}, 59 2: {}, 60 }, 61 Weight: 10, 62 }, 63 { 64 CoverPCs: map[uint64]struct{}{ 65 2: {}, 66 3: {}, 67 }, 68 Weight: 30, 69 }, 70 { 71 CoverPCs: map[uint64]struct{}{ 72 4: {}, 73 5: {}, 74 }, 75 Weight: 60, 76 }, 77 }) 78 79 rs := rand.NewSource(0) 80 81 fillGroup := func(from, to, count int) map[*prog.Prog]bool { 82 ret := map[*prog.Prog]bool{} 83 for i := 0; i < count; i++ { 84 a := from + i%(to-from+1) 85 b := a + i%(to-a+1) 86 inp := generateRangedInput(target, rs, a, b) 87 ret[inp.Prog] = true 88 corpus.Save(inp) 89 } 90 return ret 91 } 92 93 first := fillGroup(0, 1, 10) 94 second := fillGroup(2, 3, 10) 95 third := fillGroup(4, 5, 10) 96 97 rnd := rand.New(rs) 98 different := map[*prog.Prog]bool{} 99 firstCount, secondCount, thirdCount := 0, 0, 0 100 const TOTAL = 10000 101 for i := 0; i < TOTAL; i++ { 102 p := corpus.ChooseProgram(rnd) 103 different[p] = true 104 105 if first[p] { 106 firstCount++ 107 } else if second[p] { 108 secondCount++ 109 } else if third[p] { 110 thirdCount++ 111 } 112 } 113 114 assert.Greater(t, len(different), 25) 115 // These must be proportional to the focus area weight distribution. 116 assert.InDelta(t, firstCount, TOTAL*0.1, TOTAL/25) 117 assert.InDelta(t, secondCount, TOTAL*0.3, TOTAL/25) 118 assert.InDelta(t, thirdCount, TOTAL*0.6, TOTAL/25) 119 }