metrics: unit tests for callback Gauges
Peter Bourgon
8 years ago
0 | 0 | package expvar_test |
1 | 1 | |
2 | 2 | import ( |
3 | stdexpvar "expvar" | |
4 | "fmt" | |
3 | 5 | "testing" |
4 | 6 | |
5 | 7 | "github.com/peterbourgon/gokit/metrics/expvar" |
15 | 17 | teststat.PopulateNormalHistogram(t, h, seed, mean, stdev) |
16 | 18 | teststat.AssertExpvarNormalHistogram(t, metricName, mean, stdev, quantiles) |
17 | 19 | } |
20 | ||
21 | func TestCallbackGauge(t *testing.T) { | |
22 | value := 42.43 | |
23 | metricName := "foo" | |
24 | expvar.PublishCallbackGauge(metricName, func() float64 { return value }) | |
25 | if want, have := fmt.Sprint(value), stdexpvar.Get(metricName).String(); want != have { | |
26 | t.Errorf("want %q, have %q", want, have) | |
27 | } | |
28 | } |
65 | 65 | } |
66 | 66 | } |
67 | 67 | |
68 | func TestPrometheusCallbackGauge(t *testing.T) { | |
69 | value := 123.456 | |
70 | cb := func() float64 { return value } | |
71 | prometheus.RegisterCallbackGauge("test", "prometheus_gauge", "bazbaz", "Help string.", cb) | |
72 | if want, have := strings.Join([]string{ | |
73 | `# HELP test_prometheus_gauge_bazbaz Help string.`, | |
74 | `# TYPE test_prometheus_gauge_bazbaz gauge`, | |
75 | `test_prometheus_gauge_bazbaz 123.456`, | |
76 | }, "\n"), teststat.ScrapePrometheus(t); !strings.Contains(have, want) { | |
77 | t.Errorf("metric stanza not found or incorrect\n%s", have) | |
78 | } | |
79 | } | |
80 | ||
68 | 81 | func TestPrometheusHistogram(t *testing.T) { |
69 | 82 | h := prometheus.NewHistogram("test", "prometheus_histogram", "foobar", "Qwerty asdf.", []string{}) |
70 | 83 |
77 | 77 | // It collects values every scrape interval from the callback. Values are |
78 | 78 | // buffered for the report interval or until the buffer exceeds a max packet |
79 | 79 | // size, whichever comes first. The report and scrape intervals may be the |
80 | // same. Fields are ignored. | |
80 | // same. The callback determines the value, and fields are ignored, so | |
81 | // NewCallbackGauge returns nothing. | |
81 | 82 | func NewCallbackGauge(w io.Writer, key string, reportInterval, scrapeInterval time.Duration, callback func() float64) { |
82 | 83 | go fwd(w, key, reportInterval, emitEvery(scrapeInterval, callback)) |
83 | 84 | } |
84 | 85 | |
85 | func emitEvery(d time.Duration, f func() float64) <-chan string { | |
86 | func emitEvery(d time.Duration, callback func() float64) <-chan string { | |
86 | 87 | c := make(chan string) |
87 | 88 | go func() { |
88 | for range time.Tick(d) { | |
89 | c <- fmt.Sprintf("%f|g", f()) | |
89 | for range tick(d) { | |
90 | c <- fmt.Sprintf("%f|g", callback()) | |
90 | 91 | } |
91 | 92 | }() |
92 | 93 | return c |
3 | 3 | |
4 | 4 | import ( |
5 | 5 | "bytes" |
6 | "fmt" | |
6 | 7 | "runtime" |
7 | 8 | "testing" |
8 | 9 | "time" |
37 | 38 | buf := &bytes.Buffer{} |
38 | 39 | g := NewGauge(buf, "test_statsd_gauge", time.Second) |
39 | 40 | |
40 | g.Add(1) // send command | |
41 | delta := 1.0 | |
42 | g.Add(delta) // send command | |
41 | 43 | runtime.Gosched() // yield to buffer write |
42 | 44 | ch <- time.Now() // signal flush |
43 | 45 | runtime.Gosched() // yield to flush |
44 | if want, have := "test_statsd_gauge:+1.000000|g\n", buf.String(); want != have { | |
46 | if want, have := fmt.Sprintf("test_statsd_gauge:+%f|g\n", delta), buf.String(); want != have { | |
45 | 47 | t.Errorf("want %q, have %q", want, have) |
46 | 48 | } |
47 | 49 | |
48 | 50 | buf.Reset() |
49 | 51 | |
50 | g.Add(-2) | |
52 | delta = -2.0 | |
53 | g.Add(delta) | |
51 | 54 | runtime.Gosched() |
52 | 55 | ch <- time.Now() |
53 | 56 | runtime.Gosched() |
54 | if want, have := "test_statsd_gauge:-2.000000|g\n", buf.String(); want != have { | |
57 | if want, have := fmt.Sprintf("test_statsd_gauge:%f|g\n", delta), buf.String(); want != have { | |
55 | 58 | t.Errorf("want %q, have %q", want, have) |
56 | 59 | } |
57 | 60 | |
58 | 61 | buf.Reset() |
59 | 62 | |
60 | g.Set(3) | |
63 | value := 3.0 | |
64 | g.Set(value) | |
61 | 65 | runtime.Gosched() |
62 | 66 | ch <- time.Now() |
63 | 67 | runtime.Gosched() |
64 | if want, have := "test_statsd_gauge:3.000000|g\n", buf.String(); want != have { | |
68 | if want, have := fmt.Sprintf("test_statsd_gauge:%f|g\n", value), buf.String(); want != have { | |
69 | t.Errorf("want %q, have %q", want, have) | |
70 | } | |
71 | } | |
72 | ||
73 | func TestCallbackGauge(t *testing.T) { | |
74 | ch := make(chan time.Time) | |
75 | tick = func(time.Duration) <-chan time.Time { return ch } | |
76 | defer func() { tick = time.Tick }() | |
77 | ||
78 | buf := &bytes.Buffer{} | |
79 | value := 55.55 | |
80 | cb := func() float64 { return value } | |
81 | NewCallbackGauge(buf, "test_statsd_callback_gauge", time.Second, time.Nanosecond, cb) | |
82 | ||
83 | ch <- time.Now() // signal emitter | |
84 | runtime.Gosched() // yield to emitter | |
85 | ch <- time.Now() // signal flush | |
86 | runtime.Gosched() // yield to flush | |
87 | ||
88 | if want, have := fmt.Sprintf("test_statsd_callback_gauge:%f|g\n", value), buf.String(); want != have { | |
65 | 89 | t.Errorf("want %q, have %q", want, have) |
66 | 90 | } |
67 | 91 | } |