Skip to content

Commit 154b756

Browse files
authored
Merge pull request kubernetes#128166 from yongruilin/test-allow-label
test: add integration test for allow-metric-label
2 parents 3184eb3 + 105a3a2 commit 154b756

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

staging/src/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,33 @@ func Reset() {
416416
}
417417
}
418418

419+
// ResetLabelAllowLists resets the label allow lists for all metrics.
420+
// NOTE: This is only used for testing.
421+
func ResetLabelAllowLists() {
422+
for _, metric := range metrics {
423+
if counterVec, ok := metric.(*compbasemetrics.CounterVec); ok {
424+
counterVec.ResetLabelAllowLists()
425+
continue
426+
}
427+
if gaugeVec, ok := metric.(*compbasemetrics.GaugeVec); ok {
428+
gaugeVec.ResetLabelAllowLists()
429+
continue
430+
}
431+
if histogramVec, ok := metric.(*compbasemetrics.HistogramVec); ok {
432+
histogramVec.ResetLabelAllowLists()
433+
continue
434+
}
435+
if summaryVec, ok := metric.(*compbasemetrics.SummaryVec); ok {
436+
summaryVec.ResetLabelAllowLists()
437+
continue
438+
}
439+
if timingHistogramVec, ok := metric.(*compbasemetrics.TimingHistogramVec); ok {
440+
timingHistogramVec.ResetLabelAllowLists()
441+
continue
442+
}
443+
}
444+
}
445+
419446
// UpdateInflightRequestMetrics reports concurrency metrics classified by
420447
// mutating vs Readonly.
421448
func UpdateInflightRequestMetrics(phase string, nonmutating, mutating int) {

test/integration/metrics/metrics_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ import (
2121
"errors"
2222
"fmt"
2323
"runtime"
24+
"slices"
25+
"strings"
2426
"testing"
2527

2628
"github.com/prometheus/common/model"
2729
v1 "k8s.io/api/core/v1"
2830
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+
"k8s.io/apiserver/pkg/endpoints/metrics"
2932
clientset "k8s.io/client-go/kubernetes"
3033
restclient "k8s.io/client-go/rest"
34+
compbasemetrics "k8s.io/component-base/metrics"
3135
"k8s.io/component-base/metrics/testutil"
3236
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
3337
"k8s.io/kubernetes/test/integration/framework"
@@ -261,6 +265,101 @@ func TestAPIServerMetricsLabels(t *testing.T) {
261265
}
262266
}
263267

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+
264363
func TestAPIServerMetricsPods(t *testing.T) {
265364
callOrDie := func(_ interface{}, err error) {
266365
if err != nil {

0 commit comments

Comments
 (0)