1 package metrics
2
3 import (
4 "math/rand"
5 "runtime"
6 "testing"
7 "time"
8 )
9
10
11
12
13
14 func BenchmarkCompute1000(b *testing.B) {
15 s := make([]int64, 1000)
16 for i := 0; i < len(s); i++ {
17 s[i] = int64(i)
18 }
19 b.ResetTimer()
20 for i := 0; i < b.N; i++ {
21 SampleVariance(s)
22 }
23 }
24 func BenchmarkCompute1000000(b *testing.B) {
25 s := make([]int64, 1000000)
26 for i := 0; i < len(s); i++ {
27 s[i] = int64(i)
28 }
29 b.ResetTimer()
30 for i := 0; i < b.N; i++ {
31 SampleVariance(s)
32 }
33 }
34 func BenchmarkCopy1000(b *testing.B) {
35 s := make([]int64, 1000)
36 for i := 0; i < len(s); i++ {
37 s[i] = int64(i)
38 }
39 b.ResetTimer()
40 for i := 0; i < b.N; i++ {
41 sCopy := make([]int64, len(s))
42 copy(sCopy, s)
43 }
44 }
45 func BenchmarkCopy1000000(b *testing.B) {
46 s := make([]int64, 1000000)
47 for i := 0; i < len(s); i++ {
48 s[i] = int64(i)
49 }
50 b.ResetTimer()
51 for i := 0; i < b.N; i++ {
52 sCopy := make([]int64, len(s))
53 copy(sCopy, s)
54 }
55 }
56
57 func BenchmarkExpDecaySample257(b *testing.B) {
58 benchmarkSample(b, NewExpDecaySample(257, 0.015))
59 }
60
61 func BenchmarkExpDecaySample514(b *testing.B) {
62 benchmarkSample(b, NewExpDecaySample(514, 0.015))
63 }
64
65 func BenchmarkExpDecaySample1028(b *testing.B) {
66 benchmarkSample(b, NewExpDecaySample(1028, 0.015))
67 }
68
69 func BenchmarkUniformSample257(b *testing.B) {
70 benchmarkSample(b, NewUniformSample(257))
71 }
72
73 func BenchmarkUniformSample514(b *testing.B) {
74 benchmarkSample(b, NewUniformSample(514))
75 }
76
77 func BenchmarkUniformSample1028(b *testing.B) {
78 benchmarkSample(b, NewUniformSample(1028))
79 }
80
81 func TestExpDecaySample10(t *testing.T) {
82 rand.Seed(1)
83 s := NewExpDecaySample(100, 0.99)
84 for i := 0; i < 10; i++ {
85 s.Update(int64(i))
86 }
87 if size := s.Count(); 10 != size {
88 t.Errorf("s.Count(): 10 != %v\n", size)
89 }
90 if size := s.Size(); 10 != size {
91 t.Errorf("s.Size(): 10 != %v\n", size)
92 }
93 if l := len(s.Values()); 10 != l {
94 t.Errorf("len(s.Values()): 10 != %v\n", l)
95 }
96 for _, v := range s.Values() {
97 if v > 10 || v < 0 {
98 t.Errorf("out of range [0, 10): %v\n", v)
99 }
100 }
101 }
102
103 func TestExpDecaySample100(t *testing.T) {
104 rand.Seed(1)
105 s := NewExpDecaySample(1000, 0.01)
106 for i := 0; i < 100; i++ {
107 s.Update(int64(i))
108 }
109 if size := s.Count(); 100 != size {
110 t.Errorf("s.Count(): 100 != %v\n", size)
111 }
112 if size := s.Size(); 100 != size {
113 t.Errorf("s.Size(): 100 != %v\n", size)
114 }
115 if l := len(s.Values()); 100 != l {
116 t.Errorf("len(s.Values()): 100 != %v\n", l)
117 }
118 for _, v := range s.Values() {
119 if v > 100 || v < 0 {
120 t.Errorf("out of range [0, 100): %v\n", v)
121 }
122 }
123 }
124
125 func TestExpDecaySample1000(t *testing.T) {
126 rand.Seed(1)
127 s := NewExpDecaySample(100, 0.99)
128 for i := 0; i < 1000; i++ {
129 s.Update(int64(i))
130 }
131 if size := s.Count(); 1000 != size {
132 t.Errorf("s.Count(): 1000 != %v\n", size)
133 }
134 if size := s.Size(); 100 != size {
135 t.Errorf("s.Size(): 100 != %v\n", size)
136 }
137 if l := len(s.Values()); 100 != l {
138 t.Errorf("len(s.Values()): 100 != %v\n", l)
139 }
140 for _, v := range s.Values() {
141 if v > 1000 || v < 0 {
142 t.Errorf("out of range [0, 1000): %v\n", v)
143 }
144 }
145 }
146
147
148
149
150
151 func TestExpDecaySampleNanosecondRegression(t *testing.T) {
152 rand.Seed(1)
153 s := NewExpDecaySample(100, 0.99)
154 for i := 0; i < 100; i++ {
155 s.Update(10)
156 }
157 time.Sleep(1 * time.Millisecond)
158 for i := 0; i < 100; i++ {
159 s.Update(20)
160 }
161 v := s.Values()
162 avg := float64(0)
163 for i := 0; i < len(v); i++ {
164 avg += float64(v[i])
165 }
166 avg /= float64(len(v))
167 if avg > 16 || avg < 14 {
168 t.Errorf("out of range [14, 16]: %v\n", avg)
169 }
170 }
171
172 func TestExpDecaySampleRescale(t *testing.T) {
173 s := NewExpDecaySample(2, 0.001).(*ExpDecaySample)
174 s.update(time.Now(), 1)
175 s.update(time.Now().Add(time.Hour+time.Microsecond), 1)
176 for _, v := range s.values.Values() {
177 if v.k == 0.0 {
178 t.Fatal("v.k == 0.0")
179 }
180 }
181 }
182
183 func TestExpDecaySampleSnapshot(t *testing.T) {
184 now := time.Now()
185 rand.Seed(1)
186 s := NewExpDecaySample(100, 0.99)
187 for i := 1; i <= 10000; i++ {
188 s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
189 }
190 snapshot := s.Snapshot()
191 s.Update(1)
192 testExpDecaySampleStatistics(t, snapshot)
193 }
194
195 func TestExpDecaySampleStatistics(t *testing.T) {
196 now := time.Now()
197 rand.Seed(1)
198 s := NewExpDecaySample(100, 0.99)
199 for i := 1; i <= 10000; i++ {
200 s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
201 }
202 testExpDecaySampleStatistics(t, s)
203 }
204
205 func TestUniformSample(t *testing.T) {
206 rand.Seed(1)
207 s := NewUniformSample(100)
208 for i := 0; i < 1000; i++ {
209 s.Update(int64(i))
210 }
211 if size := s.Count(); 1000 != size {
212 t.Errorf("s.Count(): 1000 != %v\n", size)
213 }
214 if size := s.Size(); 100 != size {
215 t.Errorf("s.Size(): 100 != %v\n", size)
216 }
217 if l := len(s.Values()); 100 != l {
218 t.Errorf("len(s.Values()): 100 != %v\n", l)
219 }
220 for _, v := range s.Values() {
221 if v > 1000 || v < 0 {
222 t.Errorf("out of range [0, 100): %v\n", v)
223 }
224 }
225 }
226
227 func TestUniformSampleIncludesTail(t *testing.T) {
228 rand.Seed(1)
229 s := NewUniformSample(100)
230 max := 100
231 for i := 0; i < max; i++ {
232 s.Update(int64(i))
233 }
234 v := s.Values()
235 sum := 0
236 exp := (max - 1) * max / 2
237 for i := 0; i < len(v); i++ {
238 sum += int(v[i])
239 }
240 if exp != sum {
241 t.Errorf("sum: %v != %v\n", exp, sum)
242 }
243 }
244
245 func TestUniformSampleSnapshot(t *testing.T) {
246 s := NewUniformSample(100)
247 for i := 1; i <= 10000; i++ {
248 s.Update(int64(i))
249 }
250 snapshot := s.Snapshot()
251 s.Update(1)
252 testUniformSampleStatistics(t, snapshot)
253 }
254
255 func TestUniformSampleStatistics(t *testing.T) {
256 rand.Seed(1)
257 s := NewUniformSample(100)
258 for i := 1; i <= 10000; i++ {
259 s.Update(int64(i))
260 }
261 testUniformSampleStatistics(t, s)
262 }
263
264 func benchmarkSample(b *testing.B, s Sample) {
265 var memStats runtime.MemStats
266 runtime.ReadMemStats(&memStats)
267 pauseTotalNs := memStats.PauseTotalNs
268 b.ResetTimer()
269 for i := 0; i < b.N; i++ {
270 s.Update(1)
271 }
272 b.StopTimer()
273 runtime.GC()
274 runtime.ReadMemStats(&memStats)
275 b.Logf("GC cost: %d ns/op", int(memStats.PauseTotalNs-pauseTotalNs)/b.N)
276 }
277
278 func testExpDecaySampleStatistics(t *testing.T, s Sample) {
279 if count := s.Count(); 10000 != count {
280 t.Errorf("s.Count(): 10000 != %v\n", count)
281 }
282 if min := s.Min(); 107 != min {
283 t.Errorf("s.Min(): 107 != %v\n", min)
284 }
285 if max := s.Max(); 10000 != max {
286 t.Errorf("s.Max(): 10000 != %v\n", max)
287 }
288 if mean := s.Mean(); 4965.98 != mean {
289 t.Errorf("s.Mean(): 4965.98 != %v\n", mean)
290 }
291 if stdDev := s.StdDev(); 2959.825156930727 != stdDev {
292 t.Errorf("s.StdDev(): 2959.825156930727 != %v\n", stdDev)
293 }
294 ps := s.Percentiles([]float64{0.5, 0.75, 0.99})
295 if 4615 != ps[0] {
296 t.Errorf("median: 4615 != %v\n", ps[0])
297 }
298 if 7672 != ps[1] {
299 t.Errorf("75th percentile: 7672 != %v\n", ps[1])
300 }
301 if 9998.99 != ps[2] {
302 t.Errorf("99th percentile: 9998.99 != %v\n", ps[2])
303 }
304 }
305
306 func testUniformSampleStatistics(t *testing.T, s Sample) {
307 if count := s.Count(); 10000 != count {
308 t.Errorf("s.Count(): 10000 != %v\n", count)
309 }
310 if min := s.Min(); 37 != min {
311 t.Errorf("s.Min(): 37 != %v\n", min)
312 }
313 if max := s.Max(); 9989 != max {
314 t.Errorf("s.Max(): 9989 != %v\n", max)
315 }
316 if mean := s.Mean(); 4748.14 != mean {
317 t.Errorf("s.Mean(): 4748.14 != %v\n", mean)
318 }
319 if stdDev := s.StdDev(); 2826.684117548333 != stdDev {
320 t.Errorf("s.StdDev(): 2826.684117548333 != %v\n", stdDev)
321 }
322 ps := s.Percentiles([]float64{0.5, 0.75, 0.99})
323 if 4599 != ps[0] {
324 t.Errorf("median: 4599 != %v\n", ps[0])
325 }
326 if 7380.5 != ps[1] {
327 t.Errorf("75th percentile: 7380.5 != %v\n", ps[1])
328 }
329 if 9986.429999999998 != ps[2] {
330 t.Errorf("99th percentile: 9986.429999999998 != %v\n", ps[2])
331 }
332 }
333
334
335
336
337 func TestUniformSampleConcurrentUpdateCount(t *testing.T) {
338 if testing.Short() {
339 t.Skip("skipping in short mode")
340 }
341 s := NewUniformSample(100)
342 for i := 0; i < 100; i++ {
343 s.Update(int64(i))
344 }
345 quit := make(chan struct{})
346 go func() {
347 t := time.NewTicker(10 * time.Millisecond)
348 for {
349 select {
350 case <-t.C:
351 s.Update(rand.Int63())
352 case <-quit:
353 t.Stop()
354 return
355 }
356 }
357 }()
358 for i := 0; i < 1000; i++ {
359 s.Count()
360 time.Sleep(5 * time.Millisecond)
361 }
362 quit <- struct{}{}
363 }
364
View as plain text