1
2 package teststat
3
4 import (
5 "errors"
6 "fmt"
7 "math"
8 "math/rand"
9 "reflect"
10 "sort"
11 "strings"
12
13 "github.com/go-kit/kit/metrics"
14 )
15
16
17
18 func TestCounter(counter metrics.Counter, value func() float64) error {
19 want := FillCounter(counter)
20 if have := value(); want != have {
21 return fmt.Errorf("want %f, have %f", want, have)
22 }
23
24 return nil
25 }
26
27
28 func FillCounter(counter metrics.Counter) float64 {
29 a := rand.Perm(100)
30 n := rand.Intn(len(a))
31
32 var want float64
33 for i := 0; i < n; i++ {
34 f := float64(a[i])
35 counter.Add(f)
36 want += f
37 }
38 return want
39 }
40
41
42
43 func TestGauge(gauge metrics.Gauge, value func() []float64) error {
44 a := rand.Perm(100)
45 n := rand.Intn(len(a))
46
47 var want []float64
48 for i := 0; i < n; i++ {
49 f := float64(a[i])
50 gauge.Set(f)
51 want = append(want, f)
52 }
53
54 for i := 0; i < n; i++ {
55 f := float64(a[i])
56 gauge.Add(f)
57 want = append(want, want[len(want)-1]+f)
58 }
59
60 have := value()
61
62 switch len(have) {
63 case 0:
64 return fmt.Errorf("got 0 values")
65 case 1:
66 if have[0] != want[len(want)-1] {
67 return fmt.Errorf("want %f, have %f", want, have)
68 }
69 default:
70 sort.Float64s(want)
71 sort.Float64s(have)
72 if !reflect.DeepEqual(want, have) {
73 return fmt.Errorf("want %f, have %f", want, have)
74 }
75 }
76
77 return nil
78 }
79
80
81
82
83 func TestHistogram(histogram metrics.Histogram, quantiles func() (p50, p90, p95, p99 float64), tolerance float64) error {
84 PopulateNormalHistogram(histogram, rand.Int())
85
86 want50, want90, want95, want99 := normalQuantiles()
87 have50, have90, have95, have99 := quantiles()
88
89 var errs []string
90 if want, have := want50, have50; !cmp(want, have, tolerance) {
91 errs = append(errs, fmt.Sprintf("p50: want %f, have %f", want, have))
92 }
93 if want, have := want90, have90; !cmp(want, have, tolerance) {
94 errs = append(errs, fmt.Sprintf("p90: want %f, have %f", want, have))
95 }
96 if want, have := want95, have95; !cmp(want, have, tolerance) {
97 errs = append(errs, fmt.Sprintf("p95: want %f, have %f", want, have))
98 }
99 if want, have := want99, have99; !cmp(want, have, tolerance) {
100 errs = append(errs, fmt.Sprintf("p99: want %f, have %f", want, have))
101 }
102 if len(errs) > 0 {
103 return errors.New(strings.Join(errs, "; "))
104 }
105
106 return nil
107 }
108
109 var (
110
111 Count = 12345
112
113
114 Mean = 500
115
116
117 Stdev = 25
118 )
119
120
121
122
123 func ExpectedObservationsLessThan(bucket int64) int64 {
124
125 cdf := ((1.0 / 2.0) * (1 + math.Erf((float64(bucket)-float64(Mean))/(float64(Stdev)*math.Sqrt2))))
126 return int64(cdf * float64(Count))
127 }
128
129 func cmp(want, have, tol float64) bool {
130 if (math.Abs(want-have) / want) > tol {
131 return false
132 }
133 return true
134 }
135
View as plain text