1
16
17 package metrics
18
19 import (
20 "testing"
21
22 "github.com/blang/semver/v4"
23 "github.com/prometheus/client_golang/prometheus"
24 "github.com/stretchr/testify/assert"
25
26 apimachineryversion "k8s.io/apimachinery/pkg/version"
27 )
28
29 func TestHistogram(t *testing.T) {
30 v115 := semver.MustParse("1.15.0")
31 var tests = []struct {
32 desc string
33 *HistogramOpts
34 registryVersion *semver.Version
35 expectedMetricCount int
36 expectedHelp string
37 }{
38 {
39 desc: "Test non deprecated",
40 HistogramOpts: &HistogramOpts{
41 Namespace: "namespace",
42 Name: "metric_test_name",
43 Subsystem: "subsystem",
44 Help: "histogram help message",
45 Buckets: prometheus.DefBuckets,
46 },
47 registryVersion: &v115,
48 expectedMetricCount: 1,
49 expectedHelp: "[ALPHA] histogram help message",
50 },
51 {
52 desc: "Test deprecated",
53 HistogramOpts: &HistogramOpts{
54 Namespace: "namespace",
55 Name: "metric_test_name",
56 Subsystem: "subsystem",
57 Help: "histogram help message",
58 DeprecatedVersion: "1.15.0",
59 Buckets: prometheus.DefBuckets,
60 },
61 registryVersion: &v115,
62 expectedMetricCount: 1,
63 expectedHelp: "[ALPHA] (Deprecated since 1.15.0) histogram help message",
64 },
65 {
66 desc: "Test hidden",
67 HistogramOpts: &HistogramOpts{
68 Namespace: "namespace",
69 Name: "metric_test_name",
70 Subsystem: "subsystem",
71 Help: "histogram help message",
72 DeprecatedVersion: "1.14.0",
73 Buckets: prometheus.DefBuckets,
74 },
75 registryVersion: &v115,
76 expectedMetricCount: 0,
77 expectedHelp: "histogram help message",
78 },
79 }
80
81 for _, test := range tests {
82 t.Run(test.desc, func(t *testing.T) {
83 registry := newKubeRegistry(apimachineryversion.Info{
84 Major: "1",
85 Minor: "15",
86 GitVersion: "v1.15.0-alpha-1.12345",
87 })
88 c := NewHistogram(test.HistogramOpts)
89 registry.MustRegister(c)
90 cm := c.ObserverMetric.(prometheus.Metric)
91
92 metricChan := make(chan prometheus.Metric, 2)
93 c.Collect(metricChan)
94 close(metricChan)
95 m1 := <-metricChan
96 if m1 != cm {
97 t.Error("Unexpected metric", m1, cm)
98 }
99 m2, ok := <-metricChan
100 if ok {
101 t.Error("Unexpected second metric", m2)
102 }
103
104 ms, err := registry.Gather()
105 assert.Equalf(t, test.expectedMetricCount, len(ms), "Got %v metrics, Want: %v metrics", len(ms), test.expectedMetricCount)
106 assert.Nil(t, err, "Gather failed %v", err)
107
108 for _, metric := range ms {
109 assert.Equalf(t, test.expectedHelp, metric.GetHelp(), "Got %s as help message, want %s", metric.GetHelp(), test.expectedHelp)
110 }
111
112
113 c.Observe(1)
114 c.Observe(2)
115 c.Observe(3)
116 c.Observe(1.5)
117 expected := 4
118 ms, err = registry.Gather()
119 assert.Nil(t, err, "Gather failed %v", err)
120
121 for _, mf := range ms {
122 for _, m := range mf.GetMetric() {
123 assert.Equalf(t, expected, int(m.GetHistogram().GetSampleCount()), "Got %v, want %v as the sample count", m.GetHistogram().GetSampleCount(), expected)
124 }
125 }
126 })
127 }
128 }
129
130 func TestHistogramVec(t *testing.T) {
131 v115 := semver.MustParse("1.15.0")
132 var tests = []struct {
133 desc string
134 *HistogramOpts
135 labels []string
136 registryVersion *semver.Version
137 expectedMetricCount int
138 expectedHelp string
139 }{
140 {
141 desc: "Test non deprecated",
142 HistogramOpts: &HistogramOpts{
143 Namespace: "namespace",
144 Name: "metric_test_name",
145 Subsystem: "subsystem",
146 Help: "histogram help message",
147 Buckets: prometheus.DefBuckets,
148 },
149 labels: []string{"label_a", "label_b"},
150 registryVersion: &v115,
151 expectedMetricCount: 1,
152 expectedHelp: "[ALPHA] histogram help message",
153 },
154 {
155 desc: "Test deprecated",
156 HistogramOpts: &HistogramOpts{
157 Namespace: "namespace",
158 Name: "metric_test_name",
159 Subsystem: "subsystem",
160 Help: "histogram help message",
161 DeprecatedVersion: "1.15.0",
162 Buckets: prometheus.DefBuckets,
163 },
164 labels: []string{"label_a", "label_b"},
165 registryVersion: &v115,
166 expectedMetricCount: 1,
167 expectedHelp: "[ALPHA] (Deprecated since 1.15.0) histogram help message",
168 },
169 {
170 desc: "Test hidden",
171 HistogramOpts: &HistogramOpts{
172 Namespace: "namespace",
173 Name: "metric_test_name",
174 Subsystem: "subsystem",
175 Help: "histogram help message",
176 DeprecatedVersion: "1.14.0",
177 Buckets: prometheus.DefBuckets,
178 },
179 labels: []string{"label_a", "label_b"},
180 registryVersion: &v115,
181 expectedMetricCount: 0,
182 expectedHelp: "histogram help message",
183 },
184 }
185
186 for _, test := range tests {
187 t.Run(test.desc, func(t *testing.T) {
188 registry := newKubeRegistry(apimachineryversion.Info{
189 Major: "1",
190 Minor: "15",
191 GitVersion: "v1.15.0-alpha-1.12345",
192 })
193 c := NewHistogramVec(test.HistogramOpts, test.labels)
194 registry.MustRegister(c)
195 ov12 := c.WithLabelValues("1", "2")
196 cm1 := ov12.(prometheus.Metric)
197 ov12.Observe(1.0)
198
199 if test.expectedMetricCount > 0 {
200 metricChan := make(chan prometheus.Metric, 2)
201 c.Collect(metricChan)
202 close(metricChan)
203 m1 := <-metricChan
204 if m1 != cm1 {
205 t.Error("Unexpected metric", m1, cm1)
206 }
207 m2, ok := <-metricChan
208 if ok {
209 t.Error("Unexpected second metric", m2)
210 }
211 }
212
213 ms, err := registry.Gather()
214 assert.Equalf(t, test.expectedMetricCount, len(ms), "Got %v metrics, Want: %v metrics", len(ms), test.expectedMetricCount)
215 assert.Nil(t, err, "Gather failed %v", err)
216 for _, metric := range ms {
217 if metric.GetHelp() != test.expectedHelp {
218 assert.Equalf(t, test.expectedHelp, metric.GetHelp(), "Got %s as help message, want %s", metric.GetHelp(), test.expectedHelp)
219 }
220 }
221
222
223 c.WithLabelValues("1", "3").Observe(1.0)
224 c.WithLabelValues("2", "3").Observe(1.0)
225 ms, err = registry.Gather()
226 assert.Nil(t, err, "Gather failed %v", err)
227
228 for _, mf := range ms {
229 assert.Equalf(t, 3, len(mf.GetMetric()), "Got %v metrics, wanted 3 as the count", len(mf.GetMetric()))
230 for _, m := range mf.GetMetric() {
231 assert.Equalf(t, uint64(1), m.GetHistogram().GetSampleCount(), "Got %v metrics, expected histogram sample count to equal 1", m.GetHistogram().GetSampleCount())
232 }
233 }
234 })
235 }
236 }
237
238 func TestHistogramWithLabelValueAllowList(t *testing.T) {
239 labelAllowValues := map[string]string{
240 "namespace_subsystem_metric_allowlist_test,label_a": "allowed",
241 }
242 labels := []string{"label_a", "label_b"}
243 opts := &HistogramOpts{
244 Namespace: "namespace",
245 Name: "metric_allowlist_test",
246 Subsystem: "subsystem",
247 }
248 var tests = []struct {
249 desc string
250 labelValues [][]string
251 expectMetricValues map[string]uint64
252 }{
253 {
254 desc: "Test no unexpected input",
255 labelValues: [][]string{{"allowed", "b1"}, {"allowed", "b2"}},
256 expectMetricValues: map[string]uint64{
257 "allowed b1": 1.0,
258 "allowed b2": 1.0,
259 },
260 },
261 {
262 desc: "Test unexpected input",
263 labelValues: [][]string{{"allowed", "b1"}, {"not_allowed", "b1"}},
264 expectMetricValues: map[string]uint64{
265 "allowed b1": 1.0,
266 "unexpected b1": 1.0,
267 },
268 },
269 }
270
271 for _, test := range tests {
272 t.Run(test.desc, func(t *testing.T) {
273 SetLabelAllowListFromCLI(labelAllowValues)
274 registry := newKubeRegistry(apimachineryversion.Info{
275 Major: "1",
276 Minor: "15",
277 GitVersion: "v1.15.0-alpha-1.12345",
278 })
279 c := NewHistogramVec(opts, labels)
280 registry.MustRegister(c)
281
282 for _, lv := range test.labelValues {
283 c.WithLabelValues(lv...).Observe(1.0)
284 }
285 mfs, err := registry.Gather()
286 assert.Nil(t, err, "Gather failed %v", err)
287
288 for _, mf := range mfs {
289 if *mf.Name != BuildFQName(opts.Namespace, opts.Subsystem, opts.Name) {
290 continue
291 }
292 mfMetric := mf.GetMetric()
293
294 for _, m := range mfMetric {
295 var aValue, bValue string
296 for _, l := range m.Label {
297 if *l.Name == "label_a" {
298 aValue = *l.Value
299 }
300 if *l.Name == "label_b" {
301 bValue = *l.Value
302 }
303 }
304 labelValuePair := aValue + " " + bValue
305 expectedValue, ok := test.expectMetricValues[labelValuePair]
306 assert.True(t, ok, "Got unexpected label values, lable_a is %v, label_b is %v", aValue, bValue)
307 actualValue := m.GetHistogram().GetSampleCount()
308 assert.Equalf(t, expectedValue, actualValue, "Got %v, wanted %v as the count while setting label_a to %v and label b to %v", actualValue, expectedValue, aValue, bValue)
309 }
310 }
311 })
312 }
313 }
314
View as plain text