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