@@ -21,13 +21,17 @@ import (
21
21
"errors"
22
22
"fmt"
23
23
"runtime"
24
+ "slices"
25
+ "strings"
24
26
"testing"
25
27
26
28
"github.com/prometheus/common/model"
27
29
v1 "k8s.io/api/core/v1"
28
30
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31
+ "k8s.io/apiserver/pkg/endpoints/metrics"
29
32
clientset "k8s.io/client-go/kubernetes"
30
33
restclient "k8s.io/client-go/rest"
34
+ compbasemetrics "k8s.io/component-base/metrics"
31
35
"k8s.io/component-base/metrics/testutil"
32
36
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
33
37
"k8s.io/kubernetes/test/integration/framework"
@@ -261,6 +265,101 @@ func TestAPIServerMetricsLabels(t *testing.T) {
261
265
}
262
266
}
263
267
268
+ func TestAPIServerMetricsLabelsWithAllowList (t * testing.T ) {
269
+ testCases := []struct {
270
+ name string
271
+ metricName string
272
+ labelName model.LabelName
273
+ allowValues model.LabelValues
274
+ isHistogram bool
275
+ }{
276
+ {
277
+ name : "check CounterVec metric" ,
278
+ metricName : "apiserver_request_total" ,
279
+ labelName : "code" ,
280
+ allowValues : model.LabelValues {"201" , "500" },
281
+ },
282
+ {
283
+ name : "check GaugeVec metric" ,
284
+ metricName : "apiserver_current_inflight_requests" ,
285
+ labelName : "request_kind" ,
286
+ allowValues : model.LabelValues {"mutating" },
287
+ },
288
+ {
289
+ name : "check Histogram metric" ,
290
+ metricName : "apiserver_request_duration_seconds" ,
291
+ labelName : "verb" ,
292
+ allowValues : model.LabelValues {"POST" , "LIST" },
293
+ isHistogram : true ,
294
+ },
295
+ }
296
+
297
+ // Assemble the allow-metric-labels flag.
298
+ var allowMetricLabelFlagStrs []string
299
+ for _ , tc := range testCases {
300
+ var allowValuesStr []string
301
+ for _ , allowValue := range tc .allowValues {
302
+ allowValuesStr = append (allowValuesStr , string (allowValue ))
303
+ }
304
+ allowMetricLabelFlagStrs = append (allowMetricLabelFlagStrs , fmt .Sprintf ("\" %s,%s=%s\" " , tc .metricName , tc .labelName , strings .Join (allowValuesStr , "," )))
305
+ }
306
+ allowMetricLabelsFlag := "--allow-metric-labels=" + strings .Join (allowMetricLabelFlagStrs , "," )
307
+
308
+ testServerFlags := framework .DefaultTestServerFlags ()
309
+ testServerFlags = append (testServerFlags , allowMetricLabelsFlag )
310
+
311
+ // TODO: have a better way to setup and teardown for all the other tests.
312
+ metrics .Reset ()
313
+ defer metrics .Reset ()
314
+ metrics .ResetLabelAllowLists ()
315
+ defer metrics .ResetLabelAllowLists ()
316
+ defer compbasemetrics .ResetLabelValueAllowLists ()
317
+
318
+ // KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE allows for APIs pending removal to not block tests
319
+ t .Setenv ("KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE" , "true" )
320
+ s := kubeapiservertesting .StartTestServerOrDie (t , nil , testServerFlags , framework .SharedEtcd ())
321
+ defer s .TearDownFn ()
322
+
323
+ metrics , err := scrapeMetrics (s )
324
+ if err != nil {
325
+ t .Fatal (err )
326
+ }
327
+ for _ , tc := range testCases {
328
+ t .Run (tc .name , func (t * testing.T ) {
329
+ metricName := tc .metricName
330
+ if tc .isHistogram {
331
+ metricName += "_sum"
332
+ }
333
+ samples , found := metrics [metricName ]
334
+ if ! found {
335
+ t .Fatalf ("metric %q not found" , metricName )
336
+ }
337
+ for _ , sample := range samples {
338
+ if value , ok := sample .Metric [tc .labelName ]; ok {
339
+ if ! slices .Contains (tc .allowValues , value ) && value != "unexpected" {
340
+ t .Fatalf ("value %q is not allowed for label %q" , value , tc .labelName )
341
+ }
342
+ }
343
+ }
344
+ })
345
+
346
+ }
347
+
348
+ t .Run ("check cardinality_enforcement_unexpected_categorizations_total" , func (t * testing.T ) {
349
+ samples , found := metrics ["cardinality_enforcement_unexpected_categorizations_total" ]
350
+ if ! found {
351
+ t .Fatal ("metric cardinality_enforcement_unexpected_categorizations_total not found" )
352
+ }
353
+ if len (samples ) != 1 {
354
+ t .Fatalf ("Unexpected number of samples in cardinality_enforcement_unexpected_categorizations_total" )
355
+ }
356
+ if samples [0 ].Value <= 0 {
357
+ t .Fatalf ("Unexpected non-positive cardinality_enforcement_unexpected_categorizations_total, got: %s" , samples [0 ].Value )
358
+ }
359
+
360
+ })
361
+ }
362
+
264
363
func TestAPIServerMetricsPods (t * testing.T ) {
265
364
callOrDie := func (_ interface {}, err error ) {
266
365
if err != nil {
0 commit comments