From eb688e098f5abd095584d84a50dba1beeea97db5 Mon Sep 17 00:00:00 2001 From: mattjmcnaughton Date: Fri, 5 Jan 2018 08:40:24 -0500 Subject: [PATCH 1/2] Add RESTClient Custom metrics empty test Add testing for a previously untested path, which is tested when getting resource metrics. --- .../podautoscaler/metrics/rest_metrics_client_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/controller/podautoscaler/metrics/rest_metrics_client_test.go b/pkg/controller/podautoscaler/metrics/rest_metrics_client_test.go index 289b93f04d..e51c5309f8 100644 --- a/pkg/controller/podautoscaler/metrics/rest_metrics_client_test.go +++ b/pkg/controller/podautoscaler/metrics/rest_metrics_client_test.go @@ -249,6 +249,16 @@ func TestRESTClientQpsSumEqualZero(t *testing.T) { tc.runTest(t) } +func TestRESTClientQpsEmptyMetrics(t *testing.T) { + tc := restClientTestCase{ + metricName: "qps", + desiredError: fmt.Errorf("no metrics returned from custom metrics API"), + reportedMetricPoints: []metricPoint{}, + } + + tc.runTest(t) +} + func TestRESTClientCPUEmptyMetrics(t *testing.T) { tc := restClientTestCase{ resourceName: v1.ResourceCPU, From 5a165b03878d2712731b6f7b989583ca54d00414 Mon Sep 17 00:00:00 2001 From: mattjmcnaughton Date: Fri, 5 Jan 2018 09:05:54 -0500 Subject: [PATCH 2/2] Add test coverage for metrics/utilization.go Currently, there is no test coverage for this code. Since it does fairly important calculations, test coverage seems helpful. --- pkg/controller/podautoscaler/metrics/BUILD | 1 + .../podautoscaler/metrics/utilization_test.go | 149 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 pkg/controller/podautoscaler/metrics/utilization_test.go diff --git a/pkg/controller/podautoscaler/metrics/BUILD b/pkg/controller/podautoscaler/metrics/BUILD index 8592a56508..c9c11fe249 100644 --- a/pkg/controller/podautoscaler/metrics/BUILD +++ b/pkg/controller/podautoscaler/metrics/BUILD @@ -37,6 +37,7 @@ go_test( srcs = [ "legacy_metrics_client_test.go", "rest_metrics_client_test.go", + "utilization_test.go", ], embed = [":go_default_library"], importpath = "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics", diff --git a/pkg/controller/podautoscaler/metrics/utilization_test.go b/pkg/controller/podautoscaler/metrics/utilization_test.go new file mode 100644 index 0000000000..35e7df6eda --- /dev/null +++ b/pkg/controller/podautoscaler/metrics/utilization_test.go @@ -0,0 +1,149 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +type resourceUtilizationRatioTestCase struct { + metrics PodMetricsInfo + requests map[string]int64 + targetUtilization int32 + + expectedUtilizationRatio float64 + expectedCurrentUtilization int32 + expectedRawAverageValue int64 + expectedErr error +} + +func (tc *resourceUtilizationRatioTestCase) runTest(t *testing.T) { + actualUtilizationRatio, actualCurrentUtilization, actualRawAverageValue, actualErr := GetResourceUtilizationRatio(tc.metrics, tc.requests, tc.targetUtilization) + + if tc.expectedErr != nil { + assert.Error(t, actualErr, "there should be an error getting the utilization ratio") + assert.Contains(t, fmt.Sprintf("%v", actualErr), fmt.Sprintf("%v", tc.expectedErr), "the error message should be as expected") + return + } + + assert.NoError(t, actualErr, "there should be no error retrieving the utilization ratio") + assert.Equal(t, tc.expectedUtilizationRatio, actualUtilizationRatio, "the utilization ratios should be as expected") + assert.Equal(t, tc.expectedCurrentUtilization, actualCurrentUtilization, "the current utilization should be as expected") + assert.Equal(t, tc.expectedRawAverageValue, actualRawAverageValue, "the raw average value should be as expected") +} + +type metricUtilizationRatioTestCase struct { + metrics PodMetricsInfo + targetUtilization int64 + + expectedUtilizationRatio float64 + expectedCurrentUtilization int64 +} + +func (tc *metricUtilizationRatioTestCase) runTest(t *testing.T) { + actualUtilizationRatio, actualCurrentUtilization := GetMetricUtilizationRatio(tc.metrics, tc.targetUtilization) + + assert.Equal(t, tc.expectedUtilizationRatio, actualUtilizationRatio, "the utilization ratios should be as expected") + assert.Equal(t, tc.expectedCurrentUtilization, actualCurrentUtilization, "the current utilization should be as expected") +} + +func TestGetResourceUtilizationRatioBaseCase(t *testing.T) { + tc := resourceUtilizationRatioTestCase{ + metrics: PodMetricsInfo{ + "test-pod-0": 50, "test-pod-1": 76, + }, + requests: map[string]int64{ + "test-pod-0": 100, "test-pod-1": 100, + }, + targetUtilization: 50, + expectedUtilizationRatio: 1.26, + expectedCurrentUtilization: 63, + expectedRawAverageValue: 63, + expectedErr: nil, + } + + tc.runTest(t) +} + +func TestGetResourceUtilizationRatioIgnorePodsWithNoRequest(t *testing.T) { + tc := resourceUtilizationRatioTestCase{ + metrics: PodMetricsInfo{ + "test-pod-0": 50, "test-pod-1": 76, "test-pod-no-request": 100, + }, + requests: map[string]int64{ + "test-pod-0": 100, "test-pod-1": 100, + }, + targetUtilization: 50, + expectedUtilizationRatio: 1.26, + expectedCurrentUtilization: 63, + expectedRawAverageValue: 63, + expectedErr: nil, + } + + tc.runTest(t) +} + +func TestGetResourceUtilizationRatioExtraRequest(t *testing.T) { + tc := resourceUtilizationRatioTestCase{ + metrics: PodMetricsInfo{ + "test-pod-0": 50, "test-pod-1": 76, + }, + requests: map[string]int64{ + "test-pod-0": 100, "test-pod-1": 100, "test-pod-extra-request": 500, + }, + targetUtilization: 50, + expectedUtilizationRatio: 1.26, + expectedCurrentUtilization: 63, + expectedRawAverageValue: 63, + expectedErr: nil, + } + + tc.runTest(t) +} + +func TestGetResourceUtilizationRatioNoRequests(t *testing.T) { + tc := resourceUtilizationRatioTestCase{ + metrics: PodMetricsInfo{ + "test-pod-0": 50, "test-pod-1": 76, + }, + requests: map[string]int64{}, + targetUtilization: 50, + + expectedUtilizationRatio: 0, + expectedCurrentUtilization: 0, + expectedRawAverageValue: 0, + expectedErr: fmt.Errorf("no metrics returned matched known pods"), + } + + tc.runTest(t) +} + +func TestGetMetricUtilizationRatioBaseCase(t *testing.T) { + tc := metricUtilizationRatioTestCase{ + metrics: PodMetricsInfo{ + "test-pod-0": 5000, "test-pod-1": 10000, + }, + targetUtilization: 10000, + expectedUtilizationRatio: .75, + expectedCurrentUtilization: 7500, + } + + tc.runTest(t) +}