OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / go-kit / kit / metrics / teststat / teststat.go
1 // Package teststat provides helpers for testing metrics backends.
2 package teststat
3
4 import (
5         "errors"
6         "fmt"
7         "math"
8         "math/rand"
9         "strings"
10
11         "github.com/go-kit/kit/metrics"
12 )
13
14 // TestCounter puts some deltas through the counter, and then calls the value
15 // func to check that the counter has the correct final value.
16 func TestCounter(counter metrics.Counter, value func() float64) error {
17         want := FillCounter(counter)
18         if have := value(); want != have {
19                 return fmt.Errorf("want %f, have %f", want, have)
20         }
21
22         return nil
23 }
24
25 // FillCounter puts some deltas through the counter and returns the total value.
26 func FillCounter(counter metrics.Counter) float64 {
27         a := rand.Perm(100)
28         n := rand.Intn(len(a))
29
30         var want float64
31         for i := 0; i < n; i++ {
32                 f := float64(a[i])
33                 counter.Add(f)
34                 want += f
35         }
36         return want
37 }
38
39 // TestGauge puts some values through the gauge, and then calls the value func
40 // to check that the gauge has the correct final value.
41 func TestGauge(gauge metrics.Gauge, value func() float64) error {
42         a := rand.Perm(100)
43         n := rand.Intn(len(a))
44
45         var want float64
46         for i := 0; i < n; i++ {
47                 f := float64(a[i])
48                 gauge.Set(f)
49                 want = f
50         }
51
52         for i := 0; i < n; i++ {
53                 f := float64(a[i])
54                 gauge.Add(f)
55                 want += f
56         }
57
58         if have := value(); want != have {
59                 return fmt.Errorf("want %f, have %f", want, have)
60         }
61
62         return nil
63 }
64
65 // TestHistogram puts some observations through the histogram, and then calls
66 // the quantiles func to checks that the histogram has computed the correct
67 // quantiles within some tolerance
68 func TestHistogram(histogram metrics.Histogram, quantiles func() (p50, p90, p95, p99 float64), tolerance float64) error {
69         PopulateNormalHistogram(histogram, rand.Int())
70
71         want50, want90, want95, want99 := normalQuantiles()
72         have50, have90, have95, have99 := quantiles()
73
74         var errs []string
75         if want, have := want50, have50; !cmp(want, have, tolerance) {
76                 errs = append(errs, fmt.Sprintf("p50: want %f, have %f", want, have))
77         }
78         if want, have := want90, have90; !cmp(want, have, tolerance) {
79                 errs = append(errs, fmt.Sprintf("p90: want %f, have %f", want, have))
80         }
81         if want, have := want95, have95; !cmp(want, have, tolerance) {
82                 errs = append(errs, fmt.Sprintf("p95: want %f, have %f", want, have))
83         }
84         if want, have := want99, have99; !cmp(want, have, tolerance) {
85                 errs = append(errs, fmt.Sprintf("p99: want %f, have %f", want, have))
86         }
87         if len(errs) > 0 {
88                 return errors.New(strings.Join(errs, "; "))
89         }
90
91         return nil
92 }
93
94 var (
95         // Count is the number of observations.
96         Count = 12345
97
98         // Mean is the center of the normal distribution of observations.
99         Mean = 500
100
101         // Stdev of the normal distribution of observations.
102         Stdev = 25
103 )
104
105 // ExpectedObservationsLessThan returns the number of observations that should
106 // have a value less than or equal to the given value, given a normal
107 // distribution of observations described by Count, Mean, and Stdev.
108 func ExpectedObservationsLessThan(bucket int64) int64 {
109         // https://code.google.com/p/gostat/source/browse/stat/normal.go
110         cdf := ((1.0 / 2.0) * (1 + math.Erf((float64(bucket)-float64(Mean))/(float64(Stdev)*math.Sqrt2))))
111         return int64(cdf * float64(Count))
112 }
113
114 func cmp(want, have, tol float64) bool {
115         if (math.Abs(want-have) / want) > tol {
116                 return false
117         }
118         return true
119 }