diff --git a/staging/src/k8s.io/component-base/metrics/BUILD b/staging/src/k8s.io/component-base/metrics/BUILD index ea0fcfcd5c5..16385904f00 100644 --- a/staging/src/k8s.io/component-base/metrics/BUILD +++ b/staging/src/k8s.io/component-base/metrics/BUILD @@ -94,8 +94,6 @@ package_group( "//staging/src/k8s.io/apiserver/pkg/admission/metrics", "//staging/src/k8s.io/apiserver/pkg/util/flowcontrol/metrics", "//staging/src/k8s.io/component-base/metrics/...", - "//test/e2e", - "//test/e2e/storage", "//test/e2e_node", "//vendor/...", ], diff --git a/staging/src/k8s.io/component-base/metrics/testutil/metrics.go b/staging/src/k8s.io/component-base/metrics/testutil/metrics.go index 6221c62d9ae..9b154dfad32 100644 --- a/staging/src/k8s.io/component-base/metrics/testutil/metrics.go +++ b/staging/src/k8s.io/component-base/metrics/testutil/metrics.go @@ -147,3 +147,34 @@ func ComputeHistogramDelta(before, after model.Samples, label model.LabelName) { func makeKey(a, b model.LabelValue) string { return string(a) + "___" + string(b) } + +// GetMetricValuesForLabel returns value of metric for a given dimension +func GetMetricValuesForLabel(ms Metrics, metricName, label string) map[string]int64 { + samples, found := ms[metricName] + result := make(map[string]int64, len(samples)) + if !found { + return result + } + for _, sample := range samples { + count := int64(sample.Value) + dimensionName := string(sample.Metric[model.LabelName(label)]) + result[dimensionName] = count + } + return result +} + +// ValidateMetrics verifies if every sample of metric has all expected labels +func ValidateMetrics(metrics Metrics, metricName string, expectedLabels ...string) error { + samples, ok := metrics[metricName] + if !ok { + return fmt.Errorf("metric %q was not found in metrics", metricName) + } + for _, sample := range samples { + for _, l := range expectedLabels { + if _, ok := sample.Metric[model.LabelName(l)]; !ok { + return fmt.Errorf("metric %q is missing label %q, sample: %q", metricName, l, sample.String()) + } + } + } + return nil +} diff --git a/test/e2e/storage/BUILD b/test/e2e/storage/BUILD index 82c21abb29a..fa47c0928cf 100644 --- a/test/e2e/storage/BUILD +++ b/test/e2e/storage/BUILD @@ -87,7 +87,6 @@ go_library( "//vendor/github.com/aws/aws-sdk-go/service/ec2:go_default_library", "//vendor/github.com/onsi/ginkgo:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library", - "//vendor/github.com/prometheus/common/model:go_default_library", "//vendor/google.golang.org/api/googleapi:go_default_library", ], ) diff --git a/test/e2e/storage/volume_metrics.go b/test/e2e/storage/volume_metrics.go index cf1e789b7f0..eaef9afb367 100644 --- a/test/e2e/storage/volume_metrics.go +++ b/test/e2e/storage/volume_metrics.go @@ -23,7 +23,6 @@ import ( "github.com/onsi/ginkgo" "github.com/onsi/gomega" - "github.com/prometheus/common/model" v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" @@ -283,8 +282,8 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() { metricKey := "volume_operation_total_seconds_count" dimensions := []string{"operation_name", "plugin_name"} - valid := hasValidMetrics(testutil.Metrics(controllerMetrics), metricKey, dimensions...) - framework.ExpectEqual(valid, true, "Invalid metric in P/V Controller metrics: %q", metricKey) + err = testutil.ValidateMetrics(testutil.Metrics(controllerMetrics), metricKey, dimensions...) + framework.ExpectNoError(err, "Invalid metric in P/V Controller metrics: %q", metricKey) framework.Logf("Deleting pod %q/%q", pod.Namespace, pod.Name) framework.ExpectNoError(e2epod.DeletePodWithWait(c, pod)) @@ -313,8 +312,8 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() { // Metrics should have dimensions plugin_name and state available totalVolumesKey := "volume_manager_total_volumes" dimensions := []string{"state", "plugin_name"} - valid := hasValidMetrics(testutil.Metrics(kubeMetrics), totalVolumesKey, dimensions...) - framework.ExpectEqual(valid, true, "Invalid metric in Volume Manager metrics: %q", totalVolumesKey) + err = testutil.ValidateMetrics(testutil.Metrics(kubeMetrics), totalVolumesKey, dimensions...) + framework.ExpectNoError(err, "Invalid metric in Volume Manager metrics: %q", totalVolumesKey) framework.Logf("Deleting pod %q/%q", pod.Namespace, pod.Name) framework.ExpectNoError(e2epod.DeletePodWithWait(c, pod)) @@ -441,7 +440,7 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() { // Concretely, we expect the difference of the updated values and original values for each // test suit are equal to expectValues. actualValues := calculateRelativeValues(originMetricValues[i], - getPVControllerMetrics(controllerMetrics, metric.name, metric.dimension)) + testutil.GetMetricValuesForLabel(testutil.Metrics(controllerMetrics), metric.name, metric.dimension)) framework.ExpectEqual(actualValues, expectValues, "Wrong pv controller metric %s(%s): wanted %v, got %v", metric.name, metric.dimension, expectValues, actualValues) } @@ -460,7 +459,7 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() { framework.ExpectNoError(err, "Error getting c-m metricValues: %v", err) for _, metric := range metrics { originMetricValues = append(originMetricValues, - getPVControllerMetrics(controllerMetrics, metric.name, metric.dimension)) + testutil.GetMetricValuesForLabel(testutil.Metrics(controllerMetrics), metric.name, metric.dimension)) } }) @@ -696,27 +695,12 @@ func waitForPVControllerSync(metricsGrabber *metrics.Grabber, metricName, dimens framework.Logf("Error fetching controller-manager metrics") return false, err } - return len(getPVControllerMetrics(updatedMetrics, metricName, dimension)) > 0, nil + return len(testutil.GetMetricValuesForLabel(testutil.Metrics(updatedMetrics), metricName, dimension)) > 0, nil } waitErr := wait.ExponentialBackoff(backoff, verifyMetricFunc) framework.ExpectNoError(waitErr, "Unable to get pv controller metrics") } -func getPVControllerMetrics(ms metrics.ControllerManagerMetrics, metricName, dimension string) map[string]int64 { - result := make(map[string]int64) - for method, samples := range ms { - if method != metricName { - continue - } - for _, sample := range samples { - count := int64(sample.Value) - dimensionName := string(sample.Metric[model.LabelName(dimension)]) - result[dimensionName] = count - } - } - return result -} - func calculateRelativeValues(originValues, updatedValues map[string]int64) map[string]int64 { relativeValues := make(map[string]int64) for key, value := range updatedValues { @@ -733,26 +717,6 @@ func calculateRelativeValues(originValues, updatedValues map[string]int64) map[s return relativeValues } -func hasValidMetrics(metrics testutil.Metrics, metricKey string, dimensions ...string) bool { - var errCount int - framework.Logf("Looking for sample in metric %q", metricKey) - samples, ok := metrics[metricKey] - if !ok { - framework.Logf("Key %q was not found in metrics", metricKey) - return false - } - for _, sample := range samples { - framework.Logf("Found sample %q", sample.String()) - for _, d := range dimensions { - if _, ok := sample.Metric[model.LabelName(d)]; !ok { - framework.Logf("Error getting dimension %q for metric %q, sample %q", d, metricKey, sample.String()) - errCount++ - } - } - } - return errCount == 0 -} - func getStatesMetrics(metricKey string, givenMetrics testutil.Metrics) map[string]map[string]int64 { states := make(map[string]map[string]int64) for _, sample := range givenMetrics[metricKey] { @@ -776,8 +740,9 @@ func waitForADControllerStatesMetrics(metricsGrabber *metrics.Grabber, metricNam e2eskipper.Skipf("Could not get controller-manager metrics - skipping") return false, err } - if !hasValidMetrics(testutil.Metrics(updatedMetrics), metricName, dimensions...) { - return false, fmt.Errorf("could not get valid metrics for %q", metricName) + err = testutil.ValidateMetrics(testutil.Metrics(updatedMetrics), metricName, dimensions...) + if err != nil { + return false, fmt.Errorf("could not get valid metrics: %v ", err) } states := getStatesMetrics(metricName, testutil.Metrics(updatedMetrics)) for _, name := range stateNames {