diff --git a/hack/.staticcheck_failures b/hack/.staticcheck_failures index 6021171d132..2eba7d32d85 100644 --- a/hack/.staticcheck_failures +++ b/hack/.staticcheck_failures @@ -1,5 +1,4 @@ cluster/images/etcd/migrate -pkg/controller/podautoscaler pkg/controller/replicaset pkg/volume/testing test/e2e/autoscaling diff --git a/pkg/controller/podautoscaler/horizontal.go b/pkg/controller/podautoscaler/horizontal.go index 5d3b8f80a99..59893133e13 100644 --- a/pkg/controller/podautoscaler/horizontal.go +++ b/pkg/controller/podautoscaler/horizontal.go @@ -459,7 +459,6 @@ func (a *HorizontalController) computeStatusForResourceMetricGeneric(currentRepl if target.AverageUtilization == nil { errMsg := "invalid resource metric source: neither a utilization target nor a value target was set" - err = fmt.Errorf(errMsg) return 0, nil, time.Time{}, "", condition, fmt.Errorf(errMsg) } diff --git a/pkg/controller/podautoscaler/horizontal_test.go b/pkg/controller/podautoscaler/horizontal_test.go index d4eb7938c1c..c69aa7c268b 100644 --- a/pkg/controller/podautoscaler/horizontal_test.go +++ b/pkg/controller/podautoscaler/horizontal_test.go @@ -2594,32 +2594,6 @@ func TestConditionFailedUpdateScale(t *testing.T) { tc.runTest(t) } -func NoTestBackoffUpscale(t *testing.T) { - time := metav1.Time{Time: time.Now()} - tc := testCase{ - minReplicas: 1, - maxReplicas: 5, - specReplicas: 3, - statusReplicas: 3, - expectedDesiredReplicas: 3, - CPUTarget: 100, - reportedLevels: []uint64{150, 150, 150}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")}, - useMetricsAPI: true, - lastScaleTime: &time, - expectedConditions: statusOkWithOverrides(autoscalingv2.HorizontalPodAutoscalerCondition{ - Type: autoscalingv2.AbleToScale, - Status: v1.ConditionTrue, - Reason: "ReadyForNewScale", - }, autoscalingv2.HorizontalPodAutoscalerCondition{ - Type: autoscalingv2.AbleToScale, - Status: v1.ConditionTrue, - Reason: "SucceededRescale", - }), - } - tc.runTest(t) -} - func TestNoBackoffUpscaleCM(t *testing.T) { averageValue := resource.MustParse("15.0") time := metav1.Time{Time: time.Now()} diff --git a/pkg/controller/podautoscaler/legacy_horizontal_test.go b/pkg/controller/podautoscaler/legacy_horizontal_test.go index 4bf795928c6..75a1b19affa 100644 --- a/pkg/controller/podautoscaler/legacy_horizontal_test.go +++ b/pkg/controller/podautoscaler/legacy_horizontal_test.go @@ -21,7 +21,6 @@ import ( "encoding/json" "fmt" "io" - "math" "strconv" "strings" "sync" @@ -754,111 +753,6 @@ func TestLegacyScaleDownIgnoresUnreadyPods(t *testing.T) { tc.runTest(t) } -func LegacyTestTolerance(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 5, - initialReplicas: 3, - desiredReplicas: 3, - CPUTarget: 100, - reportedLevels: []uint64{1010, 1030, 1020}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestToleranceCM(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 5, - initialReplicas: 3, - desiredReplicas: 3, - metricsTarget: []autoscalingv2.MetricSpec{ - { - Type: autoscalingv2.PodsMetricSourceType, - Pods: &autoscalingv2.PodsMetricSource{ - MetricName: "qps", - TargetAverageValue: resource.MustParse("20.0"), - }, - }, - }, - reportedLevels: []uint64{20, 21, 21}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")}, - } - tc.runTest(t) -} - -func LegacyTestMinReplicas(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 2, - maxReplicas: 5, - initialReplicas: 3, - desiredReplicas: 2, - CPUTarget: 90, - reportedLevels: []uint64{10, 95, 10}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestZeroReplicas(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 3, - maxReplicas: 5, - initialReplicas: 0, - desiredReplicas: 0, - CPUTarget: 90, - reportedLevels: []uint64{}, - reportedCPURequests: []resource.Quantity{}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestTooFewReplicas(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 3, - maxReplicas: 5, - initialReplicas: 2, - desiredReplicas: 3, - CPUTarget: 90, - reportedLevels: []uint64{}, - reportedCPURequests: []resource.Quantity{}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestTooManyReplicas(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 3, - maxReplicas: 5, - initialReplicas: 10, - desiredReplicas: 5, - CPUTarget: 90, - reportedLevels: []uint64{}, - reportedCPURequests: []resource.Quantity{}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestMaxReplicas(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 2, - maxReplicas: 5, - initialReplicas: 3, - desiredReplicas: 5, - CPUTarget: 90, - reportedLevels: []uint64{8000, 9500, 1000}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - func TestLegacySuperfluousMetrics(t *testing.T) { tc := legacyTestCase{ minReplicas: 2, @@ -873,174 +767,6 @@ func TestLegacySuperfluousMetrics(t *testing.T) { tc.runTest(t) } -func LegacyTestMissingMetrics(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 2, - maxReplicas: 6, - initialReplicas: 4, - desiredReplicas: 3, - CPUTarget: 100, - reportedLevels: []uint64{400, 95}, - reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestEmptyMetrics(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 2, - maxReplicas: 6, - initialReplicas: 4, - desiredReplicas: 4, - CPUTarget: 100, - reportedLevels: []uint64{}, - reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestEmptyCPURequest(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 5, - initialReplicas: 1, - desiredReplicas: 1, - CPUTarget: 100, - reportedLevels: []uint64{200}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestEventCreated(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 5, - initialReplicas: 1, - desiredReplicas: 2, - CPUTarget: 50, - reportedLevels: []uint64{200}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.2")}, - verifyEvents: true, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestEventNotCreated(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 5, - initialReplicas: 2, - desiredReplicas: 2, - CPUTarget: 50, - reportedLevels: []uint64{200, 200}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.4"), resource.MustParse("0.4")}, - verifyEvents: true, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestMissingReports(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 5, - initialReplicas: 4, - desiredReplicas: 2, - CPUTarget: 50, - reportedLevels: []uint64{200}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.2")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -func LegacyTestUpscaleCap(t *testing.T) { - tc := legacyTestCase{ - minReplicas: 1, - maxReplicas: 100, - initialReplicas: 3, - desiredReplicas: 6, - CPUTarget: 10, - reportedLevels: []uint64{100, 200, 300}, - reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")}, - useMetricsAPI: true, - } - tc.runTest(t) -} - -// TestComputedToleranceAlgImplementation is a regression test which -// back-calculates a minimal percentage for downscaling based on a small percentage -// increase in pod utilization which is calibrated against the tolerance value. -func LegacyTestComputedToleranceAlgImplementation(t *testing.T) { - - startPods := int32(10) - // 150 mCPU per pod. - totalUsedCPUOfAllPods := uint64(startPods * 150) - // Each pod starts out asking for 2X what is really needed. - // This means we will have a 50% ratio of used/requested - totalRequestedCPUOfAllPods := int32(2 * totalUsedCPUOfAllPods) - requestedToUsed := float64(totalRequestedCPUOfAllPods / int32(totalUsedCPUOfAllPods)) - // Spread the amount we ask over 10 pods. We can add some jitter later in reportedLevels. - perPodRequested := totalRequestedCPUOfAllPods / startPods - - // Force a minimal scaling event by satisfying (tolerance < 1 - resourcesUsedRatio). - target := math.Abs(1/(requestedToUsed*(1-defaultTestingTolerance))) + .01 - finalCPUPercentTarget := int32(target * 100) - resourcesUsedRatio := float64(totalUsedCPUOfAllPods) / float64(float64(totalRequestedCPUOfAllPods)*target) - - // i.e. .60 * 20 -> scaled down expectation. - finalPods := int32(math.Ceil(resourcesUsedRatio * float64(startPods))) - - // To breach tolerance we will create a utilization ratio difference of tolerance to usageRatioToleranceValue) - tc := legacyTestCase{ - minReplicas: 0, - maxReplicas: 1000, - initialReplicas: startPods, - desiredReplicas: finalPods, - CPUTarget: finalCPUPercentTarget, - reportedLevels: []uint64{ - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - totalUsedCPUOfAllPods / 10, - }, - reportedCPURequests: []resource.Quantity{ - resource.MustParse(fmt.Sprint(perPodRequested+100) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested-100) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested+10) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested-10) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested+2) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested-2) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested+1) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested-1) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested) + "m"), - resource.MustParse(fmt.Sprint(perPodRequested) + "m"), - }, - useMetricsAPI: true, - } - - tc.runTest(t) - - // Reuse the data structure above, now testing "unscaling". - // Now, we test that no scaling happens if we are in a very close margin to the tolerance - target = math.Abs(1/(requestedToUsed*(1-defaultTestingTolerance))) + .004 - finalCPUPercentTarget = int32(target * 100) - tc.CPUTarget = finalCPUPercentTarget - tc.initialReplicas = startPods - tc.desiredReplicas = startPods - tc.runTest(t) -} - func TestLegacyScaleUpRCImmediately(t *testing.T) { time := metav1.Time{Time: time.Now()} tc := legacyTestCase{ diff --git a/pkg/controller/podautoscaler/replica_calculator_test.go b/pkg/controller/podautoscaler/replica_calculator_test.go index 304054665ad..dc683334000 100644 --- a/pkg/controller/podautoscaler/replica_calculator_test.go +++ b/pkg/controller/podautoscaler/replica_calculator_test.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/api/meta/testrestmapper" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" @@ -90,10 +89,9 @@ type replicaCalcTestCase struct { timestamp time.Time - resource *resourceInfo - metric *metricInfo - metricLabelSelector labels.Selector - container string + resource *resourceInfo + metric *metricInfo + container string podReadiness []v1.ConditionStatus podStartTime []metav1.Time