mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Watch HPA v2 instead of v1.
This commit is contained in:
parent
b817efb042
commit
711f96e05e
@ -78,10 +78,10 @@ func startHPAControllerWithMetricsClient(ctx context.Context, controllerContext
|
|||||||
go podautoscaler.NewHorizontalController(
|
go podautoscaler.NewHorizontalController(
|
||||||
hpaClient.CoreV1(),
|
hpaClient.CoreV1(),
|
||||||
scaleClient,
|
scaleClient,
|
||||||
hpaClient.AutoscalingV1(),
|
hpaClient.AutoscalingV2(),
|
||||||
controllerContext.RESTMapper,
|
controllerContext.RESTMapper,
|
||||||
metricsClient,
|
metricsClient,
|
||||||
controllerContext.InformerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
|
controllerContext.InformerFactory.Autoscaling().V2().HorizontalPodAutoscalers(),
|
||||||
controllerContext.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
controllerContext.ComponentConfig.HPAController.HorizontalPodAutoscalerSyncPeriod.Duration,
|
controllerContext.ComponentConfig.HPAController.HorizontalPodAutoscalerSyncPeriod.Duration,
|
||||||
controllerContext.ComponentConfig.HPAController.HorizontalPodAutoscalerDownscaleStabilizationWindow.Duration,
|
controllerContext.ComponentConfig.HPAController.HorizontalPodAutoscalerDownscaleStabilizationWindow.Duration,
|
||||||
|
@ -35,19 +35,18 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
autoscalinginformers "k8s.io/client-go/informers/autoscaling/v1"
|
autoscalinginformers "k8s.io/client-go/informers/autoscaling/v2"
|
||||||
coreinformers "k8s.io/client-go/informers/core/v1"
|
coreinformers "k8s.io/client-go/informers/core/v1"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
autoscalingclient "k8s.io/client-go/kubernetes/typed/autoscaling/v1"
|
autoscalingclient "k8s.io/client-go/kubernetes/typed/autoscaling/v2"
|
||||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
autoscalinglisters "k8s.io/client-go/listers/autoscaling/v1"
|
autoscalinglisters "k8s.io/client-go/listers/autoscaling/v2"
|
||||||
corelisters "k8s.io/client-go/listers/core/v1"
|
corelisters "k8s.io/client-go/listers/core/v1"
|
||||||
scaleclient "k8s.io/client-go/scale"
|
scaleclient "k8s.io/client-go/scale"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
metricsclient "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
metricsclient "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||||
)
|
)
|
||||||
@ -571,16 +570,9 @@ func (a *HorizontalController) recordInitialRecommendation(currentReplicas int32
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *HorizontalController) reconcileAutoscaler(ctx context.Context, hpav1Shared *autoscalingv1.HorizontalPodAutoscaler, key string) error {
|
func (a *HorizontalController) reconcileAutoscaler(ctx context.Context, hpaShared *autoscalingv2.HorizontalPodAutoscaler, key string) error {
|
||||||
// make a copy so that we never mutate the shared informer cache (conversion can mutate the object)
|
// make a copy so that we never mutate the shared informer cache (conversion can mutate the object)
|
||||||
hpav1 := hpav1Shared.DeepCopy()
|
hpa := hpaShared.DeepCopy()
|
||||||
// then, convert to autoscaling/v2, which makes our lives easier when calculating metrics
|
|
||||||
hpaRaw, err := unsafeConvertToVersionVia(hpav1, autoscalingv2.SchemeGroupVersion)
|
|
||||||
if err != nil {
|
|
||||||
a.eventRecorder.Event(hpav1, v1.EventTypeWarning, "FailedConvertHPA", err.Error())
|
|
||||||
return fmt.Errorf("failed to convert the given HPA to %s: %v", autoscalingv2.SchemeGroupVersion.String(), err)
|
|
||||||
}
|
|
||||||
hpa := hpaRaw.(*autoscalingv2.HorizontalPodAutoscaler)
|
|
||||||
hpaStatusOriginal := hpa.Status.DeepCopy()
|
hpaStatusOriginal := hpa.Status.DeepCopy()
|
||||||
|
|
||||||
reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleTargetRef.Kind, hpa.Namespace, hpa.Spec.ScaleTargetRef.Name)
|
reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleTargetRef.Kind, hpa.Namespace, hpa.Spec.ScaleTargetRef.Name)
|
||||||
@ -1156,15 +1148,7 @@ func (a *HorizontalController) updateStatusIfNeeded(ctx context.Context, oldStat
|
|||||||
|
|
||||||
// updateStatus actually does the update request for the status of the given HPA
|
// updateStatus actually does the update request for the status of the given HPA
|
||||||
func (a *HorizontalController) updateStatus(ctx context.Context, hpa *autoscalingv2.HorizontalPodAutoscaler) error {
|
func (a *HorizontalController) updateStatus(ctx context.Context, hpa *autoscalingv2.HorizontalPodAutoscaler) error {
|
||||||
// convert back to autoscalingv1
|
_, err := a.hpaNamespacer.HorizontalPodAutoscalers(hpa.Namespace).UpdateStatus(ctx, hpa, metav1.UpdateOptions{})
|
||||||
hpaRaw, err := unsafeConvertToVersionVia(hpa, autoscalingv1.SchemeGroupVersion)
|
|
||||||
if err != nil {
|
|
||||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedConvertHPA", err.Error())
|
|
||||||
return fmt.Errorf("failed to convert the given HPA to %s: %v", autoscalingv2.SchemeGroupVersion.String(), err)
|
|
||||||
}
|
|
||||||
hpav1 := hpaRaw.(*autoscalingv1.HorizontalPodAutoscaler)
|
|
||||||
|
|
||||||
_, err = a.hpaNamespacer.HorizontalPodAutoscalers(hpav1.Namespace).UpdateStatus(ctx, hpav1, metav1.UpdateOptions{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedUpdateStatus", err.Error())
|
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedUpdateStatus", err.Error())
|
||||||
return fmt.Errorf("failed to update status for %s: %v", hpa.Name, err)
|
return fmt.Errorf("failed to update status for %s: %v", hpa.Name, err)
|
||||||
@ -1173,24 +1157,6 @@ func (a *HorizontalController) updateStatus(ctx context.Context, hpa *autoscalin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafeConvertToVersionVia is like Scheme.UnsafeConvertToVersion, but it does so via an internal version first.
|
|
||||||
// We use it since working with v2alpha1 is convenient here, but we want to use the v1 client (and
|
|
||||||
// can't just use the internal version). Note that conversion mutates the object, so you need to deepcopy
|
|
||||||
// *before* you call this if the input object came out of a shared cache.
|
|
||||||
func unsafeConvertToVersionVia(obj runtime.Object, externalVersion schema.GroupVersion) (runtime.Object, error) {
|
|
||||||
objInt, err := legacyscheme.Scheme.UnsafeConvertToVersion(obj, schema.GroupVersion{Group: externalVersion.Group, Version: runtime.APIVersionInternal})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to convert the given object to the internal version: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
objExt, err := legacyscheme.Scheme.UnsafeConvertToVersion(objInt, externalVersion)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to convert the given object back to the external version: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return objExt, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// setCondition sets the specific condition type on the given HPA to the specified value with the given reason
|
// setCondition sets the specific condition type on the given HPA to the specified value with the given reason
|
||||||
// and message. The message and args are treated like a format string. The condition will be added if it is
|
// and message. The message and args are treated like a format string. The condition will be added if it is
|
||||||
// not present.
|
// not present.
|
||||||
|
@ -18,7 +18,6 @@ package podautoscaler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
@ -40,7 +39,6 @@ import (
|
|||||||
scalefake "k8s.io/client-go/scale/fake"
|
scalefake "k8s.io/client-go/scale/fake"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
|
||||||
autoscalingapiv2 "k8s.io/kubernetes/pkg/apis/autoscaling/v2"
|
autoscalingapiv2 "k8s.io/kubernetes/pkg/apis/autoscaling/v2"
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||||
@ -74,7 +72,7 @@ var statusOk = []autoscalingv2.HorizontalPodAutoscalerCondition{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// statusOkWithOverrides returns the "ok" status with the given conditions as overridden
|
// statusOkWithOverrides returns the "ok" status with the given conditions as overridden
|
||||||
func statusOkWithOverrides(overrides ...autoscalingv2.HorizontalPodAutoscalerCondition) []autoscalingv1.HorizontalPodAutoscalerCondition {
|
func statusOkWithOverrides(overrides ...autoscalingv2.HorizontalPodAutoscalerCondition) []autoscalingv2.HorizontalPodAutoscalerCondition {
|
||||||
resv2 := make([]autoscalingv2.HorizontalPodAutoscalerCondition, len(statusOk))
|
resv2 := make([]autoscalingv2.HorizontalPodAutoscalerCondition, len(statusOk))
|
||||||
copy(resv2, statusOk)
|
copy(resv2, statusOk)
|
||||||
for _, override := range overrides {
|
for _, override := range overrides {
|
||||||
@ -82,10 +80,10 @@ func statusOkWithOverrides(overrides ...autoscalingv2.HorizontalPodAutoscalerCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copy to a v1 slice
|
// copy to a v1 slice
|
||||||
resv1 := make([]autoscalingv1.HorizontalPodAutoscalerCondition, len(resv2))
|
resv1 := make([]autoscalingv2.HorizontalPodAutoscalerCondition, len(resv2))
|
||||||
for i, cond := range resv2 {
|
for i, cond := range resv2 {
|
||||||
resv1[i] = autoscalingv1.HorizontalPodAutoscalerCondition{
|
resv1[i] = autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
Type: autoscalingv1.HorizontalPodAutoscalerConditionType(cond.Type),
|
Type: autoscalingv2.HorizontalPodAutoscalerConditionType(cond.Type),
|
||||||
Status: cond.Status,
|
Status: cond.Status,
|
||||||
Reason: cond.Reason,
|
Reason: cond.Reason,
|
||||||
}
|
}
|
||||||
@ -129,7 +127,7 @@ type testCase struct {
|
|||||||
useMetricsAPI bool
|
useMetricsAPI bool
|
||||||
metricsTarget []autoscalingv2.MetricSpec
|
metricsTarget []autoscalingv2.MetricSpec
|
||||||
expectedDesiredReplicas int32
|
expectedDesiredReplicas int32
|
||||||
expectedConditions []autoscalingv1.HorizontalPodAutoscalerCondition
|
expectedConditions []autoscalingv2.HorizontalPodAutoscalerCondition
|
||||||
// Channel with names of HPA objects which we have reconciled.
|
// Channel with names of HPA objects which we have reconciled.
|
||||||
processed chan string
|
processed chan string
|
||||||
|
|
||||||
@ -243,6 +241,7 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
|||||||
Resource: &autoscalingv2.ResourceMetricSource{
|
Resource: &autoscalingv2.ResourceMetricSource{
|
||||||
Name: v1.ResourceCPU,
|
Name: v1.ResourceCPU,
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.UtilizationMetricType,
|
||||||
AverageUtilization: &tc.CPUTarget,
|
AverageUtilization: &tc.CPUTarget,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -265,13 +264,7 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// and... convert to autoscaling v1 to return the right type
|
return true, obj, nil
|
||||||
objv1, err := unsafeConvertToVersionVia(obj, autoscalingv1.SchemeGroupVersion)
|
|
||||||
if err != nil {
|
|
||||||
return true, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, objv1, nil
|
|
||||||
})
|
})
|
||||||
|
|
||||||
fakeClient.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
fakeClient.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
||||||
@ -364,23 +357,20 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
|||||||
})
|
})
|
||||||
|
|
||||||
fakeClient.AddReactor("update", "horizontalpodautoscalers", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
fakeClient.AddReactor("update", "horizontalpodautoscalers", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
||||||
handled, obj, err := func() (handled bool, ret *autoscalingv1.HorizontalPodAutoscaler, err error) {
|
handled, obj, err := func() (handled bool, ret *autoscalingv2.HorizontalPodAutoscaler, err error) {
|
||||||
tc.Lock()
|
tc.Lock()
|
||||||
defer tc.Unlock()
|
defer tc.Unlock()
|
||||||
|
|
||||||
obj := action.(core.UpdateAction).GetObject().(*autoscalingv1.HorizontalPodAutoscaler)
|
obj := action.(core.UpdateAction).GetObject().(*autoscalingv2.HorizontalPodAutoscaler)
|
||||||
assert.Equal(t, namespace, obj.Namespace, "the HPA namespace should be as expected")
|
assert.Equal(t, namespace, obj.Namespace, "the HPA namespace should be as expected")
|
||||||
assert.Equal(t, hpaName, obj.Name, "the HPA name should be as expected")
|
assert.Equal(t, hpaName, obj.Name, "the HPA name should be as expected")
|
||||||
assert.Equal(t, tc.expectedDesiredReplicas, obj.Status.DesiredReplicas, "the desired replica count reported in the object status should be as expected")
|
assert.Equal(t, tc.expectedDesiredReplicas, obj.Status.DesiredReplicas, "the desired replica count reported in the object status should be as expected")
|
||||||
if tc.verifyCPUCurrent {
|
if tc.verifyCPUCurrent {
|
||||||
if assert.NotNil(t, obj.Status.CurrentCPUUtilizationPercentage, "the reported CPU utilization percentage should be non-nil") {
|
if utilization := findCpuUtilization(obj.Status.CurrentMetrics); assert.NotNil(t, utilization, "the reported CPU utilization percentage should be non-nil") {
|
||||||
assert.Equal(t, tc.CPUCurrent, *obj.Status.CurrentCPUUtilizationPercentage, "the report CPU utilization percentage should be as expected")
|
assert.Equal(t, tc.CPUCurrent, *utilization, "the report CPU utilization percentage should be as expected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var actualConditions []autoscalingv1.HorizontalPodAutoscalerCondition
|
actualConditions := obj.Status.Conditions
|
||||||
if err := json.Unmarshal([]byte(obj.ObjectMeta.Annotations[autoscaling.HorizontalPodAutoscalerConditionsAnnotation]), &actualConditions); err != nil {
|
|
||||||
return true, nil, err
|
|
||||||
}
|
|
||||||
// TODO: it's ok not to sort these because statusOk
|
// TODO: it's ok not to sort these because statusOk
|
||||||
// contains all the conditions, so we'll never be appending.
|
// contains all the conditions, so we'll never be appending.
|
||||||
// Default to statusOk when missing any specific conditions
|
// Default to statusOk when missing any specific conditions
|
||||||
@ -654,6 +644,25 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
|||||||
return fakeClient, fakeMetricsClient, fakeCMClient, fakeEMClient, fakeScaleClient
|
return fakeClient, fakeMetricsClient, fakeCMClient, fakeEMClient, fakeScaleClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findCpuUtilization(metricStatus []autoscalingv2.MetricStatus) (utilization *int32) {
|
||||||
|
for _, s := range metricStatus {
|
||||||
|
if s.Type != autoscalingv2.ResourceMetricSourceType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s.Resource == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s.Resource.Name != v1.ResourceCPU {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s.Resource.Current.AverageUtilization == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return s.Resource.Current.AverageUtilization
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tc *testCase) verifyResults(t *testing.T) {
|
func (tc *testCase) verifyResults(t *testing.T) {
|
||||||
tc.Lock()
|
tc.Lock()
|
||||||
defer tc.Unlock()
|
defer tc.Unlock()
|
||||||
@ -717,10 +726,10 @@ func (tc *testCase) setupController(t *testing.T) (*HorizontalController, inform
|
|||||||
hpaController := NewHorizontalController(
|
hpaController := NewHorizontalController(
|
||||||
eventClient.CoreV1(),
|
eventClient.CoreV1(),
|
||||||
testScaleClient,
|
testScaleClient,
|
||||||
testClient.AutoscalingV1(),
|
testClient.AutoscalingV2(),
|
||||||
testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Scheme),
|
testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Scheme),
|
||||||
metricsClient,
|
metricsClient,
|
||||||
informerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
|
informerFactory.Autoscaling().V2().HorizontalPodAutoscalers(),
|
||||||
informerFactory.Core().V1().Pods(),
|
informerFactory.Core().V1().Pods(),
|
||||||
100*time.Millisecond, // we need non-zero resync period to avoid race conditions
|
100*time.Millisecond, // we need non-zero resync period to avoid race conditions
|
||||||
defaultDownscalestabilizationWindow,
|
defaultDownscalestabilizationWindow,
|
||||||
@ -1000,6 +1009,7 @@ func TestScaleUpCM(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1028,6 +1038,7 @@ func TestScaleUpCMUnreadyAndHotCpuNoLessScale(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1058,6 +1069,7 @@ func TestScaleUpCMUnreadyandCpuHot(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1097,6 +1109,7 @@ func TestScaleUpHotCpuNoScaleWouldScaleDown(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1140,6 +1153,7 @@ func TestScaleUpCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1172,6 +1186,7 @@ func TestScaleUpFromZeroCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1204,6 +1219,7 @@ func TestScaleUpFromZeroIgnoresToleranceCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1236,6 +1252,7 @@ func TestScaleUpPerPodCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &targetAverageValue,
|
AverageValue: &targetAverageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1262,6 +1279,7 @@ func TestScaleUpCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(6666, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(6666, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1288,6 +1306,7 @@ func TestScaleUpPerPodCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: resource.NewMilliQuantity(2222, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(2222, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1415,9 +1434,9 @@ func TestScaleUpBothMetricsEmpty(t *testing.T) { // Switch to missing
|
|||||||
},
|
},
|
||||||
reportedLevels: []uint64{},
|
reportedLevels: []uint64{},
|
||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: "InvalidMetricSourceType"},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: "InvalidMetricSourceType"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -1466,6 +1485,7 @@ func TestScaleDownCM(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1500,6 +1520,7 @@ func TestScaleDownCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1534,6 +1555,7 @@ func TestScaleDownToZeroCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1568,6 +1590,7 @@ func TestScaleDownPerPodCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &targetAverageValue,
|
AverageValue: &targetAverageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1596,6 +1619,7 @@ func TestScaleDownCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(14400, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(14400, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1623,6 +1647,7 @@ func TestScaleDownToZeroCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(14400, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(14400, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1650,6 +1675,7 @@ func TestScaleDownPerPodCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: resource.NewMilliQuantity(3000, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(3000, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1776,6 +1802,7 @@ func TestToleranceCM(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1813,6 +1840,7 @@ func TestToleranceCMObject(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1845,6 +1873,7 @@ func TestToleranceCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(8666, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(8666, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1881,6 +1910,7 @@ func TestTolerancePerPodCMObject(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: resource.NewMilliQuantity(2200, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(2200, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1912,6 +1942,7 @@ func TestTolerancePerPodCMExternal(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: resource.NewMilliQuantity(2200, resource.DecimalSI),
|
AverageValue: resource.NewMilliQuantity(2200, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2001,9 +2032,9 @@ func TestZeroReplicas(t *testing.T) {
|
|||||||
reportedLevels: []uint64{},
|
reportedLevels: []uint64{},
|
||||||
reportedCPURequests: []resource.Quantity{},
|
reportedCPURequests: []resource.Quantity{},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: "ScalingDisabled"},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: "ScalingDisabled"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2020,8 +2051,8 @@ func TestTooFewReplicas(t *testing.T) {
|
|||||||
reportedLevels: []uint64{},
|
reportedLevels: []uint64{},
|
||||||
reportedCPURequests: []resource.Quantity{},
|
reportedCPURequests: []resource.Quantity{},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2038,8 +2069,8 @@ func TestTooManyReplicas(t *testing.T) {
|
|||||||
reportedLevels: []uint64{},
|
reportedLevels: []uint64{},
|
||||||
reportedCPURequests: []resource.Quantity{},
|
reportedCPURequests: []resource.Quantity{},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2112,9 +2143,9 @@ func TestEmptyMetrics(t *testing.T) {
|
|||||||
reportedLevels: []uint64{},
|
reportedLevels: []uint64{},
|
||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: "FailedGetResourceMetric"},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: "FailedGetResourceMetric"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2131,9 +2162,9 @@ func TestEmptyCPURequest(t *testing.T) {
|
|||||||
reportedLevels: []uint64{200},
|
reportedLevels: []uint64{200},
|
||||||
reportedCPURequests: []resource.Quantity{},
|
reportedCPURequests: []resource.Quantity{},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: "FailedGetResourceMetric"},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: "FailedGetResourceMetric"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2274,14 +2305,14 @@ func TestConditionInvalidSelectorMissing(t *testing.T) {
|
|||||||
reportedLevels: []uint64{100, 200, 300},
|
reportedLevels: []uint64{100, 200, 300},
|
||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.AbleToScale,
|
Type: autoscalingv2.AbleToScale,
|
||||||
Status: v1.ConditionTrue,
|
Status: v1.ConditionTrue,
|
||||||
Reason: "SucceededGetScale",
|
Reason: "SucceededGetScale",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.ScalingActive,
|
Type: autoscalingv2.ScalingActive,
|
||||||
Status: v1.ConditionFalse,
|
Status: v1.ConditionFalse,
|
||||||
Reason: "InvalidSelector",
|
Reason: "InvalidSelector",
|
||||||
},
|
},
|
||||||
@ -2320,14 +2351,14 @@ func TestConditionInvalidSelectorUnparsable(t *testing.T) {
|
|||||||
reportedLevels: []uint64{100, 200, 300},
|
reportedLevels: []uint64{100, 200, 300},
|
||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.AbleToScale,
|
Type: autoscalingv2.AbleToScale,
|
||||||
Status: v1.ConditionTrue,
|
Status: v1.ConditionTrue,
|
||||||
Reason: "SucceededGetScale",
|
Reason: "SucceededGetScale",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.ScalingActive,
|
Type: autoscalingv2.ScalingActive,
|
||||||
Status: v1.ConditionFalse,
|
Status: v1.ConditionFalse,
|
||||||
Reason: "InvalidSelector",
|
Reason: "InvalidSelector",
|
||||||
},
|
},
|
||||||
@ -2369,6 +2400,7 @@ func TestConditionFailedGetMetrics(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2387,6 +2419,7 @@ func TestConditionFailedGetMetrics(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: &targetValue,
|
Value: &targetValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2401,6 +2434,7 @@ func TestConditionFailedGetMetrics(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(300, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(300, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2435,9 +2469,9 @@ func TestConditionFailedGetMetrics(t *testing.T) {
|
|||||||
return true, &emapi.ExternalMetricValueList{}, fmt.Errorf("something went wrong")
|
return true, &emapi.ExternalMetricValueList{}, fmt.Errorf("something went wrong")
|
||||||
})
|
})
|
||||||
|
|
||||||
tc.expectedConditions = []autoscalingv1.HorizontalPodAutoscalerCondition{
|
tc.expectedConditions = []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: reason},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: reason},
|
||||||
}
|
}
|
||||||
if specs != nil {
|
if specs != nil {
|
||||||
tc.CPUTarget = 0
|
tc.CPUTarget = 0
|
||||||
@ -2463,14 +2497,14 @@ func TestConditionInvalidSourceType(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
reportedLevels: []uint64{20000},
|
reportedLevels: []uint64{20000},
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.AbleToScale,
|
Type: autoscalingv2.AbleToScale,
|
||||||
Status: v1.ConditionTrue,
|
Status: v1.ConditionTrue,
|
||||||
Reason: "SucceededGetScale",
|
Reason: "SucceededGetScale",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.ScalingActive,
|
Type: autoscalingv2.ScalingActive,
|
||||||
Status: v1.ConditionFalse,
|
Status: v1.ConditionFalse,
|
||||||
Reason: "InvalidMetricSourceType",
|
Reason: "InvalidMetricSourceType",
|
||||||
},
|
},
|
||||||
@ -2490,9 +2524,9 @@ func TestConditionFailedGetScale(t *testing.T) {
|
|||||||
reportedLevels: []uint64{100, 200, 300},
|
reportedLevels: []uint64{100, 200, 300},
|
||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("0.1"), resource.MustParse("0.1"), resource.MustParse("0.1")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{
|
{
|
||||||
Type: autoscalingv1.AbleToScale,
|
Type: autoscalingv2.AbleToScale,
|
||||||
Status: v1.ConditionFalse,
|
Status: v1.ConditionFalse,
|
||||||
Reason: "FailedGetScale",
|
Reason: "FailedGetScale",
|
||||||
},
|
},
|
||||||
@ -2555,6 +2589,7 @@ func TestNoBackoffUpscaleCM(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2599,6 +2634,7 @@ func TestNoBackoffUpscaleCMNoBackoffCpu(t *testing.T) {
|
|||||||
Name: "qps",
|
Name: "qps",
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.AverageValueMetricType,
|
||||||
AverageValue: &averageValue,
|
AverageValue: &averageValue,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2770,8 +2806,8 @@ func TestScaleUpRCImmediately(t *testing.T) {
|
|||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
lastScaleTime: &time,
|
lastScaleTime: &time,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2790,8 +2826,8 @@ func TestScaleDownRCImmediately(t *testing.T) {
|
|||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
lastScaleTime: &time,
|
lastScaleTime: &time,
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededRescale"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
@ -2831,6 +2867,8 @@ func TestAvoidUnnecessaryUpdates(t *testing.T) {
|
|||||||
tc.processed <- "test-hpa"
|
tc.processed <- "test-hpa"
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var eighty int32 = 80
|
||||||
|
|
||||||
quantity := resource.MustParse("400m")
|
quantity := resource.MustParse("400m")
|
||||||
obj := &autoscalingv2.HorizontalPodAutoscalerList{
|
obj := &autoscalingv2.HorizontalPodAutoscalerList{
|
||||||
Items: []autoscalingv2.HorizontalPodAutoscaler{
|
Items: []autoscalingv2.HorizontalPodAutoscaler{
|
||||||
@ -2846,7 +2884,21 @@ func TestAvoidUnnecessaryUpdates(t *testing.T) {
|
|||||||
Name: "test-rc",
|
Name: "test-rc",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
},
|
},
|
||||||
|
Metrics: []autoscalingv2.MetricSpec{{
|
||||||
|
Type: autoscalingv2.ResourceMetricSourceType,
|
||||||
|
Resource: &autoscalingv2.ResourceMetricSource{
|
||||||
|
Name: v1.ResourceCPU,
|
||||||
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.UtilizationMetricType,
|
||||||
|
// TODO: Change this to &tc.CPUTarget and the expected ScaleLimited
|
||||||
|
// condition to False. This test incorrectly leaves the v1
|
||||||
|
// HPA field TargetCPUUtilizization field blank and the
|
||||||
|
// controller defaults to a target of 80. So the test relies
|
||||||
|
// on downscale stabilization to prevent a scale change.
|
||||||
|
AverageUtilization: &eighty,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
MinReplicas: &tc.minReplicas,
|
MinReplicas: &tc.minReplicas,
|
||||||
MaxReplicas: tc.maxReplicas,
|
MaxReplicas: tc.maxReplicas,
|
||||||
},
|
},
|
||||||
@ -2893,13 +2945,8 @@ func TestAvoidUnnecessaryUpdates(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// and... convert to autoscaling v1 to return the right type
|
|
||||||
objv1, err := unsafeConvertToVersionVia(obj, autoscalingv1.SchemeGroupVersion)
|
|
||||||
if err != nil {
|
|
||||||
return true, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, objv1, nil
|
return true, obj, nil
|
||||||
})
|
})
|
||||||
testClient.PrependReactor("update", "horizontalpodautoscalers", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
testClient.PrependReactor("update", "horizontalpodautoscalers", func(action core.Action) (handled bool, ret runtime.Object, err error) {
|
||||||
assert.Fail(t, "should not have attempted to update the HPA when nothing changed")
|
assert.Fail(t, "should not have attempted to update the HPA when nothing changed")
|
||||||
@ -4024,6 +4071,7 @@ func TestScaleUpOneMetricEmpty(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(100, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4057,9 +4105,9 @@ func TestNoScaleDownOneMetricInvalid(t *testing.T) {
|
|||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
recommendations: []timestampedRecommendation{},
|
recommendations: []timestampedRecommendation{},
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: "InvalidMetricSourceType"},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: "InvalidMetricSourceType"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4083,6 +4131,7 @@ func TestNoScaleDownOneMetricEmpty(t *testing.T) {
|
|||||||
Selector: &metav1.LabelSelector{},
|
Selector: &metav1.LabelSelector{},
|
||||||
},
|
},
|
||||||
Target: autoscalingv2.MetricTarget{
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.ValueMetricType,
|
||||||
Value: resource.NewMilliQuantity(1000, resource.DecimalSI),
|
Value: resource.NewMilliQuantity(1000, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4092,9 +4141,9 @@ func TestNoScaleDownOneMetricEmpty(t *testing.T) {
|
|||||||
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
useMetricsAPI: true,
|
useMetricsAPI: true,
|
||||||
recommendations: []timestampedRecommendation{},
|
recommendations: []timestampedRecommendation{},
|
||||||
expectedConditions: []autoscalingv1.HorizontalPodAutoscalerCondition{
|
expectedConditions: []autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
{Type: autoscalingv1.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
{Type: autoscalingv2.AbleToScale, Status: v1.ConditionTrue, Reason: "SucceededGetScale"},
|
||||||
{Type: autoscalingv1.ScalingActive, Status: v1.ConditionFalse, Reason: "FailedGetExternalMetric"},
|
{Type: autoscalingv2.ScalingActive, Status: v1.ConditionFalse, Reason: "FailedGetExternalMetric"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, _, _, testEMClient, _ := tc.prepareTestClient(t)
|
_, _, _, testEMClient, _ := tc.prepareTestClient(t)
|
||||||
|
Loading…
Reference in New Issue
Block a user