github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/stats/set_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 stats 5 6 import ( 7 "fmt" 8 "math/rand" 9 "sync/atomic" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestSet(t *testing.T) { 17 a := assert.New(t) 18 set := newSet(4, false) 19 a.Empty(set.Collect(All)) 20 _, err := set.RenderHTML() 21 a.NoError(err) 22 23 v0 := set.Create("v0", "desc0") 24 a.Equal(v0.Val(), 0) 25 v0.Add(1) 26 a.Equal(v0.Val(), 1) 27 v0.Add(1) 28 a.Equal(v0.Val(), 2) 29 30 vv1 := 0 31 v1 := set.Create("v1", "desc1", Simple, func() int { return vv1 }) 32 a.Equal(v1.Val(), 0) 33 vv1 = 11 34 a.Equal(v1.Val(), 11) 35 a.Panics(func() { v1.Add(1) }) 36 37 v2 := set.Create("v2", "desc2", Console, func(v int, period time.Duration) string { 38 return fmt.Sprintf("v2 %v %v", v, period) 39 }) 40 v2.Add(100) 41 42 v3 := set.Create("v3", "desc3", Link("/v3"), NoGraph, Distribution{}) 43 a.Equal(v3.Val(), 0) 44 v3.Add(10) 45 a.Equal(v3.Val(), 10) 46 v3.Add(20) 47 a.Equal(v3.Val(), 15) 48 v3.Add(20) 49 a.Equal(v3.Val(), 16) 50 v3.Add(30) 51 a.Equal(v3.Val(), 20) 52 v3.Add(30) 53 a.Equal(v3.Val(), 22) 54 v3.Add(30) 55 v3.Add(30) 56 a.Equal(v3.Val(), 24) 57 58 v4 := set.Create("v4", "desc4", Rate{}, Graph("graph")) 59 v4.Add(10) 60 a.Equal(v4.Val(), 10) 61 v4.Add(10) 62 a.Equal(v4.Val(), 20) 63 64 a.Panics(func() { set.Create("v0", "desc0", float64(1)) }) 65 66 ui := set.Collect(All) 67 a.Equal(len(ui), 5) 68 a.Equal(ui[0], UI{"v2", "desc2", "", Console, "v2 100 1s", 100}) 69 a.Equal(ui[1], UI{"v1", "desc1", "", Simple, "11", 11}) 70 a.Equal(ui[2], UI{"v0", "desc0", "", All, "2", 2}) 71 a.Equal(ui[3], UI{"v3", "desc3", "/v3", All, "24", 24}) 72 a.Equal(ui[4], UI{"v4", "desc4", "", All, "20 (20/sec)", 20}) 73 74 ui1 := set.Collect(Simple) 75 a.Equal(len(ui1), 2) 76 a.Equal(ui1[0].Name, "v2") 77 a.Equal(ui1[1].Name, "v1") 78 79 ui2 := set.Collect(Console) 80 a.Equal(len(ui2), 1) 81 a.Equal(ui2[0].Name, "v2") 82 83 _, err = set.RenderHTML() 84 a.NoError(err) 85 } 86 87 func TestSetRateFormat(t *testing.T) { 88 a := assert.New(t) 89 set := newSet(4, false) 90 v := set.Create("v", "desc", Rate{}) 91 a.Equal(set.Collect(All)[0].Value, "0 (0/hour)") 92 v.Add(1) 93 a.Equal(set.Collect(All)[0].Value, "1 (60/min)") 94 v.Add(99) 95 a.Equal(set.Collect(All)[0].Value, "100 (100/sec)") 96 } 97 98 func TestSetHistoryCounter(t *testing.T) { 99 a := assert.New(t) 100 set := newSet(4, false) 101 v := set.Create("v0", "desc0") 102 set.tick() 103 hist := func() []float64 { return set.graphs["v0"].lines["v0"].data[:set.historyPos] } 104 step := func(n int) []float64 { 105 v.Add(n) 106 set.tick() 107 return hist() 108 } 109 a.Equal(hist(), []float64{0}) 110 v.Add(1) 111 v.Add(1) 112 a.Equal(hist(), []float64{0}) 113 set.tick() 114 a.Equal(hist(), []float64{0, 2}) 115 v.Add(3) 116 a.Equal(hist(), []float64{0, 2}) 117 set.tick() 118 a.Equal(hist(), []float64{0, 2, 5}) 119 a.Equal(step(-1), []float64{0, 2, 5, 4}) 120 // Compacted, each new history value will require 2 steps. 121 a.Equal(step(7), []float64{2, 5}) 122 a.Equal(step(-10), []float64{2, 5, 11}) 123 a.Equal(step(2), []float64{2, 5, 11}) 124 a.Equal(step(1), []float64{2, 5, 11, 4}) 125 // 4 steps for each new value. 126 a.Equal(step(1), []float64{5, 11}) 127 a.Equal(step(1), []float64{5, 11}) 128 a.Equal(step(1), []float64{5, 11}) 129 a.Equal(step(1), []float64{5, 11, 8}) 130 } 131 132 func TestSetHistoryRate(t *testing.T) { 133 a := assert.New(t) 134 set := newSet(4, false) 135 v := set.Create("v0", "desc0", Rate{}) 136 step := func(n int) []float64 { 137 v.Add(n) 138 set.tick() 139 return set.graphs["v0"].lines["v0"].data[:set.historyPos] 140 } 141 a.Equal(step(3), []float64{3}) 142 a.Equal(step(1), []float64{3, 1}) 143 a.Equal(step(2), []float64{3, 1, 2}) 144 a.Equal(step(5), []float64{3, 1, 2, 5}) 145 a.Equal(step(1), []float64{2, 3.5}) 146 a.Equal(step(2), []float64{2, 3.5, 1.5}) 147 a.Equal(step(2), []float64{2, 3.5, 1.5}) 148 a.Equal(step(4), []float64{2, 3.5, 1.5, 3}) 149 a.Equal(step(1), []float64{2.75, 2.25}) 150 a.Equal(step(2), []float64{2.75, 2.25}) 151 a.Equal(step(3), []float64{2.75, 2.25}) 152 a.Equal(step(4), []float64{2.75, 2.25, 2.5}) 153 } 154 155 func TestSetHistoryDistribution(t *testing.T) { 156 a := assert.New(t) 157 set := newSet(4, false) 158 v := set.Create("v0", "desc0", Distribution{}) 159 step := func(n int) [3][]float64 { 160 v.Add(n) 161 set.tick() 162 var history [3][]float64 163 for p, percent := range []int{10, 50, 90} { 164 history[p] = make([]float64, set.historyPos) 165 for i := 0; i < set.historyPos; i++ { 166 hist := set.graphs["v0"].lines["v0"].hist[i] 167 if hist != nil { 168 history[p][i] = hist.Quantile(float64(percent) / 100) 169 } 170 } 171 } 172 return history 173 } 174 a.Equal(step(3), [3][]float64{{3}, {3}, {3}}) 175 a.Equal(step(6), [3][]float64{{3, 6}, {3, 6}, {3, 6}}) 176 a.Equal(step(1), [3][]float64{{3, 6, 1}, {3, 6, 1}, {3, 6, 1}}) 177 a.Equal(step(2), [3][]float64{{3, 6, 1, 2}, {3, 6, 1, 2}, {3, 6, 1, 2}}) 178 a.Equal(step(1), [3][]float64{{3, 1}, {3, 1}, {3, 1}}) 179 a.Equal(step(10), [3][]float64{{3, 1, 1}, {3, 1, 10}, {3, 1, 10}}) 180 } 181 182 func TestSetStress(t *testing.T) { 183 set := newSet(4, false) 184 var stop atomic.Bool 185 var seq atomic.Uint64 186 start := func(f func()) { 187 go func() { 188 for !stop.Load() { 189 f() 190 } 191 }() 192 } 193 for p := 0; p < 2; p++ { 194 for _, opt := range []any{Link(""), NoGraph, Rate{}, Distribution{}} { 195 opt := opt 196 go func() { 197 v := set.Create(fmt.Sprintf("v%v", seq.Add(1)), "desc", opt) 198 for p1 := 0; p1 < 2; p1++ { 199 start(func() { v.Val() }) 200 start(func() { v.Add(rand.Intn(10000)) }) 201 } 202 }() 203 } 204 go func() { 205 var vv atomic.Uint64 206 v := set.Create(fmt.Sprintf("v%v", seq.Add(1)), "desc", 207 func() int { return int(vv.Load()) }) 208 for p1 := 0; p1 < 2; p1++ { 209 start(func() { v.Val() }) 210 start(func() { vv.Store(uint64(rand.Intn(10000))) }) 211 } 212 }() 213 start(func() { set.Collect(All) }) 214 start(func() { set.RenderHTML() }) 215 start(func() { set.tick() }) 216 } 217 time.Sleep(time.Second) 218 stop.Store(true) 219 }