master
go 116 lines 3.07 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package metrix
4
5 import (
6 "math"
7 "testing"
8 )
9
10 func TestValueValidationScenarios(t *testing.T) {
11 tests := map[string]struct {
12 run func(t *testing.T)
13 }{
14 "collector gauge rejects NaN and Inf": {
15 run: func(t *testing.T) {
16 s := NewCollectorStore()
17 cc := cycleController(t, s)
18 g := s.Write().SnapshotMeter("svc").Gauge("load")
19
20 cc.BeginCycle()
21 expectPanic(t, func() { g.Observe(math.NaN()) })
22 cc.AbortCycle()
23
24 cc.BeginCycle()
25 expectPanic(t, func() { g.Observe(math.Inf(1)) })
26 cc.AbortCycle()
27 },
28 },
29 "collector counter rejects NaN and Inf": {
30 run: func(t *testing.T) {
31 s := NewCollectorStore()
32 cc := cycleController(t, s)
33 sc := s.Write().SnapshotMeter("svc").Counter("total")
34 st := s.Write().StatefulMeter("svc").Counter("total_stateful")
35
36 cc.BeginCycle()
37 expectPanic(t, func() { sc.ObserveTotal(math.NaN()) })
38 cc.AbortCycle()
39
40 cc.BeginCycle()
41 expectPanic(t, func() { st.Add(math.Inf(1)) })
42 cc.AbortCycle()
43 },
44 },
45 "collector summary and histogram reject non-finite samples": {
46 run: func(t *testing.T) {
47 s := NewCollectorStore()
48 cc := cycleController(t, s)
49 sum := s.Write().StatefulMeter("svc").Summary("latency")
50 hist := s.Write().StatefulMeter("svc").Histogram("duration", WithHistogramBounds(1, 2))
51
52 cc.BeginCycle()
53 expectPanic(t, func() { sum.Observe(math.Inf(1)) })
54 cc.AbortCycle()
55
56 cc.BeginCycle()
57 expectPanic(t, func() { hist.Observe(math.NaN()) })
58 cc.AbortCycle()
59 },
60 },
61 "collector point APIs reject non-finite values": {
62 run: func(t *testing.T) {
63 s := NewCollectorStore()
64 cc := cycleController(t, s)
65 sum := s.Write().SnapshotMeter("svc").Summary("latency", WithSummaryQuantiles(0.5))
66 hist := s.Write().SnapshotMeter("svc").Histogram("duration", WithHistogramBounds(1, 2))
67
68 cc.BeginCycle()
69 expectPanic(t, func() {
70 sum.ObservePoint(SummaryPoint{
71 Count: 1,
72 Sum: 1,
73 Quantiles: []QuantilePoint{
74 // A NaN quantile value is accepted (stored, then rendered
75 // downstream as a gap), so only an Inf value panics here.
76 {Quantile: 0.5, Value: math.Inf(1)},
77 },
78 })
79 })
80 cc.AbortCycle()
81
82 cc.BeginCycle()
83 expectPanic(t, func() {
84 hist.ObservePoint(HistogramPoint{
85 Count: 1,
86 Sum: math.Inf(1),
87 Buckets: []BucketPoint{
88 {UpperBound: 1, CumulativeCount: 1},
89 {UpperBound: 2, CumulativeCount: 1},
90 },
91 })
92 })
93 cc.AbortCycle()
94 },
95 },
96 "runtime scalar writes reject NaN and Inf": {
97 run: func(t *testing.T) {
98 s := NewRuntimeStore()
99 m := s.Write().StatefulMeter("runtime")
100 g := m.Gauge("heap")
101 c := m.Counter("events_total")
102 h := m.Histogram("latency", WithHistogramBounds(1, 2))
103 sum := m.Summary("duration")
104
105 expectPanic(t, func() { g.Set(math.NaN()) })
106 expectPanic(t, func() { c.Add(math.Inf(1)) })
107 expectPanic(t, func() { h.Observe(math.Inf(1)) })
108 expectPanic(t, func() { sum.Observe(math.NaN()) })
109 },
110 },
111 }
112
113 for name, tc := range tests {
114 t.Run(name, tc.run)
115 }
116 }