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