mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Implement autoscaling/v2beta2 features in HPA controller
This commit is contained in:
parent
a79916fa84
commit
c7102ee5dc
@ -1,10 +1,4 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
@ -15,13 +9,14 @@ go_library(
|
||||
"replica_calculator.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/controller/podautoscaler",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/v1/pod:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/podautoscaler/metrics:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
@ -66,6 +61,7 @@ go_test(
|
||||
"//pkg/controller/podautoscaler/metrics:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
@ -80,7 +76,7 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/scale/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/external_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1beta1:go_default_library",
|
||||
@ -107,4 +103,5 @@ filegroup(
|
||||
"//pkg/controller/podautoscaler/metrics:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@ -218,12 +218,24 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori
|
||||
|
||||
switch metricSpec.Type {
|
||||
case autoscalingv2.ObjectMetricSourceType:
|
||||
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForObjectMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i])
|
||||
metricSelector, err := metav1.LabelSelectorAsSelector(metricSpec.Object.Metric.Selector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetObjectMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err)
|
||||
}
|
||||
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForObjectMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i], metricSelector)
|
||||
if err != nil {
|
||||
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err)
|
||||
}
|
||||
case autoscalingv2.PodsMetricSourceType:
|
||||
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForPodsMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i])
|
||||
metricSelector, err := metav1.LabelSelectorAsSelector(metricSpec.Pods.Metric.Selector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetPodsMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetPodsMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get pods metric value: %v", err)
|
||||
}
|
||||
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForPodsMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i], metricSelector)
|
||||
if err != nil {
|
||||
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err)
|
||||
}
|
||||
@ -270,8 +282,8 @@ func (a *HorizontalController) reconcileKey(key string) error {
|
||||
}
|
||||
|
||||
// computeStatusForObjectMetric computes the desired number of replicas for the specified metric of type ObjectMetricSourceType.
|
||||
func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (int32, time.Time, string, error) {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectMetricReplicas(currentReplicas, metricSpec.Object.TargetValue.MilliValue(), metricSpec.Object.MetricName, hpa.Namespace, &metricSpec.Object.Target, selector)
|
||||
func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (int32, time.Time, string, error) {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectMetricReplicas(currentReplicas, metricSpec.Object.Target.Value.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, selector, metricSelector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetObjectMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
@ -280,17 +292,22 @@ func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int3
|
||||
*status = autoscalingv2.MetricStatus{
|
||||
Type: autoscalingv2.ObjectMetricSourceType,
|
||||
Object: &autoscalingv2.ObjectMetricStatus{
|
||||
Target: metricSpec.Object.Target,
|
||||
MetricName: metricSpec.Object.MetricName,
|
||||
CurrentValue: *resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
DescribedObject: metricSpec.Object.DescribedObject,
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: metricSpec.Object.Metric.Name,
|
||||
Selector: metricSpec.Object.Metric.Selector,
|
||||
},
|
||||
Current: autoscalingv2.MetricValueStatus{
|
||||
Value: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("%s metric %s", metricSpec.Object.Target.Kind, metricSpec.Object.MetricName), nil
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("%s metric %s", metricSpec.Object.DescribedObject.Kind, metricSpec.Object.Metric.Name), nil
|
||||
}
|
||||
|
||||
// computeStatusForPodsMetric computes the desired number of replicas for the specified metric of type PodsMetricSourceType.
|
||||
func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (int32, time.Time, string, error) {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetMetricReplicas(currentReplicas, metricSpec.Pods.TargetAverageValue.MilliValue(), metricSpec.Pods.MetricName, hpa.Namespace, selector)
|
||||
func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (int32, time.Time, string, error) {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetMetricReplicas(currentReplicas, metricSpec.Pods.Target.AverageValue.MilliValue(), metricSpec.Pods.Metric.Name, hpa.Namespace, selector, metricSelector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetPodsMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetPodsMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
@ -299,19 +316,24 @@ func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32,
|
||||
*status = autoscalingv2.MetricStatus{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricStatus{
|
||||
MetricName: metricSpec.Pods.MetricName,
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: metricSpec.Pods.Metric.Name,
|
||||
Selector: metricSpec.Pods.Metric.Selector,
|
||||
},
|
||||
Current: autoscalingv2.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("pods metric %s", metricSpec.Pods.MetricName), nil
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("pods metric %s", metricSpec.Pods.Metric.Name), nil
|
||||
}
|
||||
|
||||
// computeStatusForResourceMetric computes the desired number of replicas for the specified metric of type ResourceMetricSourceType.
|
||||
func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (int32, time.Time, string, error) {
|
||||
if metricSpec.Resource.TargetAverageValue != nil {
|
||||
if metricSpec.Resource.Target.AverageValue != nil {
|
||||
var rawProposal int64
|
||||
replicaCountProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetRawResourceReplicas(currentReplicas, metricSpec.Resource.TargetAverageValue.MilliValue(), metricSpec.Resource.Name, hpa.Namespace, selector)
|
||||
replicaCountProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetRawResourceReplicas(currentReplicas, metricSpec.Resource.Target.AverageValue.MilliValue(), metricSpec.Resource.Name, hpa.Namespace, selector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetResourceMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetResourceMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
@ -321,19 +343,21 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in
|
||||
status = &autoscalingv2.MetricStatus{
|
||||
Type: autoscalingv2.ResourceMetricSourceType,
|
||||
Resource: &autoscalingv2.ResourceMetricStatus{
|
||||
Name: metricSpec.Resource.Name,
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
||||
Name: metricSpec.Resource.Name,
|
||||
Current: autoscalingv2.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
return replicaCountProposal, timestampProposal, metricNameProposal, nil
|
||||
} else {
|
||||
if metricSpec.Resource.TargetAverageUtilization == nil {
|
||||
if metricSpec.Resource.Target.AverageUtilization == nil {
|
||||
errMsg := "invalid resource metric source: neither a utilization target nor a value target was set"
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetResourceMetric", errMsg)
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetResourceMetric", "the HPA was unable to compute the replica count: %s", errMsg)
|
||||
return 0, time.Time{}, "", fmt.Errorf(errMsg)
|
||||
}
|
||||
targetUtilization := *metricSpec.Resource.TargetAverageUtilization
|
||||
targetUtilization := *metricSpec.Resource.Target.AverageUtilization
|
||||
var percentageProposal int32
|
||||
var rawProposal int64
|
||||
replicaCountProposal, percentageProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetResourceReplicas(currentReplicas, targetUtilization, metricSpec.Resource.Name, hpa.Namespace, selector)
|
||||
@ -347,8 +371,10 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in
|
||||
Type: autoscalingv2.ResourceMetricSourceType,
|
||||
Resource: &autoscalingv2.ResourceMetricStatus{
|
||||
Name: metricSpec.Resource.Name,
|
||||
CurrentAverageUtilization: &percentageProposal,
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
||||
Current: autoscalingv2.MetricValueStatus{
|
||||
AverageUtilization: &percentageProposal,
|
||||
AverageValue: resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
return replicaCountProposal, timestampProposal, metricNameProposal, nil
|
||||
@ -357,39 +383,47 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in
|
||||
|
||||
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
|
||||
func (a *HorizontalController) computeStatusForExternalMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (int32, time.Time, string, error) {
|
||||
if metricSpec.External.TargetAverageValue != nil {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalPerPodMetricReplicas(currentReplicas, metricSpec.External.TargetAverageValue.MilliValue(), metricSpec.External.MetricName, hpa.Namespace, metricSpec.External.MetricSelector)
|
||||
if metricSpec.External.Target.AverageValue != nil {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalPerPodMetricReplicas(currentReplicas, metricSpec.External.Target.AverageValue.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetExternalMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
return 0, time.Time{}, "", fmt.Errorf("failed to get %s external metric: %v", metricSpec.External.MetricName, err)
|
||||
return 0, time.Time{}, "", fmt.Errorf("failed to get %s external metric: %v", metricSpec.External.Metric.Name, err)
|
||||
}
|
||||
*status = autoscalingv2.MetricStatus{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricStatus{
|
||||
MetricSelector: metricSpec.External.MetricSelector,
|
||||
MetricName: metricSpec.External.MetricName,
|
||||
CurrentAverageValue: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: metricSpec.External.Metric.Name,
|
||||
Selector: metricSpec.External.Metric.Selector,
|
||||
},
|
||||
Current: autoscalingv2.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.MetricName, metricSpec.External.MetricSelector), nil
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.Metric.Name, metricSpec.External.Metric.Selector), nil
|
||||
}
|
||||
if metricSpec.External.TargetValue != nil {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalMetricReplicas(currentReplicas, metricSpec.External.TargetValue.MilliValue(), metricSpec.External.MetricName, hpa.Namespace, metricSpec.External.MetricSelector, selector)
|
||||
if metricSpec.External.Target.Value != nil {
|
||||
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalMetricReplicas(currentReplicas, metricSpec.External.Target.Value.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector, selector)
|
||||
if err != nil {
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", err.Error())
|
||||
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetExternalMetric", "the HPA was unable to compute the replica count: %v", err)
|
||||
return 0, time.Time{}, "", fmt.Errorf("failed to get external metric %s: %v", metricSpec.External.MetricName, err)
|
||||
return 0, time.Time{}, "", fmt.Errorf("failed to get external metric %s: %v", metricSpec.External.Metric.Name, err)
|
||||
}
|
||||
*status = autoscalingv2.MetricStatus{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricStatus{
|
||||
MetricSelector: metricSpec.External.MetricSelector,
|
||||
MetricName: metricSpec.External.MetricName,
|
||||
CurrentValue: *resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: metricSpec.External.Metric.Name,
|
||||
Selector: metricSpec.External.Metric.Selector,
|
||||
},
|
||||
Current: autoscalingv2.MetricValueStatus{
|
||||
Value: resource.NewMilliQuantity(utilizationProposal, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.MetricName, metricSpec.External.MetricSelector), nil
|
||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.Metric.Name, metricSpec.External.Metric.Selector), nil
|
||||
}
|
||||
errMsg := "invalid external metric source: neither a value target nor an average value target was set"
|
||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", errMsg)
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@ -42,7 +42,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||
cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
emapi "k8s.io/metrics/pkg/apis/external_metrics/v1beta1"
|
||||
metricsapi "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
metricsfake "k8s.io/metrics/pkg/client/clientset/versioned/fake"
|
||||
@ -214,7 +214,9 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
||||
Type: autoscalingv2.ResourceMetricSourceType,
|
||||
Resource: &autoscalingv2.ResourceMetricSource{
|
||||
Name: v1.ResourceCPU,
|
||||
TargetAverageUtilization: &tc.CPUTarget,
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageUtilization: &tc.CPUTarget,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -507,9 +509,11 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
||||
Name: fmt.Sprintf("%s-%d", podNamePrefix, i),
|
||||
Namespace: namespace,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: time.Now()},
|
||||
MetricName: "qps",
|
||||
Value: *resource.NewMilliQuantity(int64(level), resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: time.Now()},
|
||||
Metric: cmapi.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Value: *resource.NewMilliQuantity(int64(level), resource.DecimalSI),
|
||||
}
|
||||
metrics.Items = append(metrics.Items, podMetric)
|
||||
}
|
||||
@ -522,8 +526,8 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
||||
metrics := &cmapi.MetricValueList{}
|
||||
var matchedTarget *autoscalingv2.MetricSpec
|
||||
for i, target := range tc.metricsTarget {
|
||||
if target.Type == autoscalingv2.ObjectMetricSourceType && name == target.Object.Target.Name {
|
||||
gk := schema.FromAPIVersionAndKind(target.Object.Target.APIVersion, target.Object.Target.Kind).GroupKind()
|
||||
if target.Type == autoscalingv2.ObjectMetricSourceType && name == target.Object.DescribedObject.Name {
|
||||
gk := schema.FromAPIVersionAndKind(target.Object.DescribedObject.APIVersion, target.Object.DescribedObject.Kind).GroupKind()
|
||||
mapping, err := mapper.RESTMapping(gk)
|
||||
if err != nil {
|
||||
t.Logf("unable to get mapping for %s: %v", gk.String(), err)
|
||||
@ -542,13 +546,15 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
||||
metrics.Items = []cmapi.MetricValue{
|
||||
{
|
||||
DescribedObject: v1.ObjectReference{
|
||||
Kind: matchedTarget.Object.Target.Kind,
|
||||
APIVersion: matchedTarget.Object.Target.APIVersion,
|
||||
Kind: matchedTarget.Object.DescribedObject.Kind,
|
||||
APIVersion: matchedTarget.Object.DescribedObject.APIVersion,
|
||||
Name: name,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: time.Now()},
|
||||
MetricName: "qps",
|
||||
Value: *resource.NewMilliQuantity(int64(tc.reportedLevels[0]), resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: time.Now()},
|
||||
Metric: cmapi.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Value: *resource.NewMilliQuantity(int64(tc.reportedLevels[0]), resource.DecimalSI),
|
||||
},
|
||||
}
|
||||
|
||||
@ -847,6 +853,7 @@ func TestScaleUpReplicaSet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleUpCM(t *testing.T) {
|
||||
averageValue := resource.MustParse("15.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -857,8 +864,12 @@ func TestScaleUpCM(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -869,6 +880,7 @@ func TestScaleUpCM(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleUpCMUnreadyAndHotCpuNoLessScale(t *testing.T) {
|
||||
averageValue := resource.MustParse("15.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -879,8 +891,12 @@ func TestScaleUpCMUnreadyAndHotCpuNoLessScale(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -893,6 +909,7 @@ func TestScaleUpCMUnreadyAndHotCpuNoLessScale(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleUpCMUnreadyandCpuHot(t *testing.T) {
|
||||
averageValue := resource.MustParse("15.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -903,8 +920,12 @@ func TestScaleUpCMUnreadyandCpuHot(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -926,6 +947,7 @@ func TestScaleUpCMUnreadyandCpuHot(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleUpHotCpuNoScaleWouldScaleDown(t *testing.T) {
|
||||
averageValue := resource.MustParse("15.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -936,8 +958,12 @@ func TestScaleUpHotCpuNoScaleWouldScaleDown(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -958,6 +984,7 @@ func TestScaleUpHotCpuNoScaleWouldScaleDown(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleUpCMObject(t *testing.T) {
|
||||
targetValue := resource.MustParse("15.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -968,13 +995,17 @@ func TestScaleUpCMObject(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ObjectMetricSourceType,
|
||||
Object: &autoscalingv2.ObjectMetricSource{
|
||||
Target: autoscalingv2.CrossVersionObjectReference{
|
||||
DescribedObject: autoscalingv2.CrossVersionObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Deployment",
|
||||
Name: "some-deployment",
|
||||
},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: &targetValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -993,9 +1024,13 @@ func TestScaleUpCMExternal(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.NewMilliQuantity(6666, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: resource.NewMilliQuantity(6666, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1014,9 +1049,13 @@ func TestScaleUpPerPodCMExternal(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.NewMilliQuantity(2222, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: resource.NewMilliQuantity(2222, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1041,6 +1080,7 @@ func TestScaleDown(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleDownCM(t *testing.T) {
|
||||
averageValue := resource.MustParse("20.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -1051,8 +1091,12 @@ func TestScaleDownCM(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("20.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1063,6 +1107,7 @@ func TestScaleDownCM(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScaleDownCMObject(t *testing.T) {
|
||||
targetValue := resource.MustParse("20.0")
|
||||
tc := testCase{
|
||||
minReplicas: 2,
|
||||
maxReplicas: 6,
|
||||
@ -1073,13 +1118,17 @@ func TestScaleDownCMObject(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ObjectMetricSourceType,
|
||||
Object: &autoscalingv2.ObjectMetricSource{
|
||||
Target: autoscalingv2.CrossVersionObjectReference{
|
||||
DescribedObject: autoscalingv2.CrossVersionObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Deployment",
|
||||
Name: "some-deployment",
|
||||
},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.MustParse("20.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: &targetValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1099,9 +1148,13 @@ func TestScaleDownCMExternal(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.NewMilliQuantity(14400, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: resource.NewMilliQuantity(14400, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1120,9 +1173,13 @@ func TestScaleDownPerPodCMExternal(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.NewMilliQuantity(3000, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: resource.NewMilliQuantity(3000, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1203,6 +1260,7 @@ func TestTolerance(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestToleranceCM(t *testing.T) {
|
||||
averageValue := resource.MustParse("20.0")
|
||||
tc := testCase{
|
||||
minReplicas: 1,
|
||||
maxReplicas: 5,
|
||||
@ -1212,8 +1270,12 @@ func TestToleranceCM(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("20.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1229,6 +1291,7 @@ func TestToleranceCM(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestToleranceCMObject(t *testing.T) {
|
||||
targetValue := resource.MustParse("20.0")
|
||||
tc := testCase{
|
||||
minReplicas: 1,
|
||||
maxReplicas: 5,
|
||||
@ -1238,13 +1301,17 @@ func TestToleranceCMObject(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ObjectMetricSourceType,
|
||||
Object: &autoscalingv2.ObjectMetricSource{
|
||||
Target: autoscalingv2.CrossVersionObjectReference{
|
||||
DescribedObject: autoscalingv2.CrossVersionObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Deployment",
|
||||
Name: "some-deployment",
|
||||
},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.MustParse("20.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: &targetValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1269,9 +1336,13 @@ func TestToleranceCMExternal(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.NewMilliQuantity(8666, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: resource.NewMilliQuantity(8666, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1295,9 +1366,13 @@ func TestTolerancePerPodCMExternal(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.NewMilliQuantity(2200, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: resource.NewMilliQuantity(2200, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1669,14 +1744,20 @@ func TestConditionInvalidSelectorUnparsable(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConditionFailedGetMetrics(t *testing.T) {
|
||||
targetValue := resource.MustParse("15.0")
|
||||
averageValue := resource.MustParse("15.0")
|
||||
metricsTargets := map[string][]autoscalingv2.MetricSpec{
|
||||
"FailedGetResourceMetric": nil,
|
||||
"FailedGetPodsMetric": {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1684,13 +1765,17 @@ func TestConditionFailedGetMetrics(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ObjectMetricSourceType,
|
||||
Object: &autoscalingv2.ObjectMetricSource{
|
||||
Target: autoscalingv2.CrossVersionObjectReference{
|
||||
DescribedObject: autoscalingv2.CrossVersionObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Deployment",
|
||||
Name: "some-deployment",
|
||||
},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: &targetValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1698,9 +1783,13 @@ func TestConditionFailedGetMetrics(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.ExternalMetricSourceType,
|
||||
External: &autoscalingv2.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{},
|
||||
MetricName: "qps",
|
||||
TargetValue: resource.NewMilliQuantity(300, resource.DecimalSI),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
Selector: &metav1.LabelSelector{},
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
Value: resource.NewMilliQuantity(300, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1857,6 +1946,7 @@ func NoTestBackoffUpscale(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNoBackoffUpscaleCM(t *testing.T) {
|
||||
averageValue := resource.MustParse("15.0")
|
||||
time := metav1.Time{Time: time.Now()}
|
||||
tc := testCase{
|
||||
minReplicas: 1,
|
||||
@ -1868,8 +1958,12 @@ func TestNoBackoffUpscaleCM(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1895,6 +1989,7 @@ func TestNoBackoffUpscaleCM(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNoBackoffUpscaleCMNoBackoffCpu(t *testing.T) {
|
||||
averageValue := resource.MustParse("15.0")
|
||||
time := metav1.Time{Time: time.Now()}
|
||||
tc := testCase{
|
||||
minReplicas: 1,
|
||||
@ -1906,8 +2001,12 @@ func TestNoBackoffUpscaleCMNoBackoffCpu(t *testing.T) {
|
||||
{
|
||||
Type: autoscalingv2.PodsMetricSourceType,
|
||||
Pods: &autoscalingv2.PodsMetricSource{
|
||||
MetricName: "qps",
|
||||
TargetAverageValue: resource.MustParse("15.0"),
|
||||
Metric: autoscalingv2.MetricIdentifier{
|
||||
Name: "qps",
|
||||
},
|
||||
Target: autoscalingv2.MetricTarget{
|
||||
AverageValue: &averageValue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -210,7 +210,7 @@ func (tc *legacyReplicaCalcTestCase) runTest(t *testing.T) {
|
||||
assert.True(t, tc.timestamp.Equal(outTimestamp), "timestamp should be as expected")
|
||||
|
||||
} else {
|
||||
outReplicas, outUtilization, outTimestamp, err := replicaCalc.GetMetricReplicas(tc.currentReplicas, tc.metric.targetUtilization, tc.metric.name, testNamespace, selector)
|
||||
outReplicas, outUtilization, outTimestamp, err := replicaCalc.GetMetricReplicas(tc.currentReplicas, tc.metric.targetUtilization, tc.metric.name, testNamespace, selector, nil)
|
||||
|
||||
if tc.expectedError != nil {
|
||||
require.Error(t, err, "there should be an error calculating the replica count")
|
||||
|
@ -1,10 +1,4 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
@ -15,15 +9,16 @@ go_library(
|
||||
"utilization.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics:go_default_library",
|
||||
@ -44,7 +39,7 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
@ -55,7 +50,7 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/external_metrics/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1beta1:go_default_library",
|
||||
@ -78,4 +73,5 @@ filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ package metrics
|
||||
import (
|
||||
"time"
|
||||
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
@ -37,11 +37,11 @@ type MetricsClient interface {
|
||||
|
||||
// GetRawMetric gets the given metric (and an associated oldest timestamp)
|
||||
// for all pods matching the specified selector in the given namespace
|
||||
GetRawMetric(metricName string, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error)
|
||||
GetRawMetric(metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (PodMetricsInfo, time.Time, error)
|
||||
|
||||
// GetObjectMetric gets the given metric (and an associated timestamp) for the given
|
||||
// object in the given namespace
|
||||
GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference) (int64, time.Time, error)
|
||||
GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (int64, time.Time, error)
|
||||
|
||||
// GetExternalMetric gets all the values of a given external metric
|
||||
// that match the specified selector.
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
heapster "k8s.io/heapster/metrics/api/v1/types"
|
||||
metricsapi "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -109,7 +109,7 @@ func (h *HeapsterMetricsClient) GetResourceMetric(resource v1.ResourceName, name
|
||||
return res, timestamp, nil
|
||||
}
|
||||
|
||||
func (h *HeapsterMetricsClient) GetRawMetric(metricName string, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error) {
|
||||
func (h *HeapsterMetricsClient) GetRawMetric(metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (PodMetricsInfo, time.Time, error) {
|
||||
podList, err := h.podsGetter.Pods(namespace).List(metav1.ListOptions{LabelSelector: selector.String()})
|
||||
if err != nil {
|
||||
return nil, time.Time{}, fmt.Errorf("failed to get pod list while fetching metrics: %v", err)
|
||||
@ -173,7 +173,7 @@ func (h *HeapsterMetricsClient) GetRawMetric(metricName string, namespace string
|
||||
return res, *timestamp, nil
|
||||
}
|
||||
|
||||
func (h *HeapsterMetricsClient) GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference) (int64, time.Time, error) {
|
||||
func (h *HeapsterMetricsClient) GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (int64, time.Time, error) {
|
||||
return 0, time.Time{}, fmt.Errorf("object metrics are not yet supported")
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,11 @@ type testCase struct {
|
||||
reportedMetricsPoints [][]metricPoint
|
||||
reportedPodMetrics [][]int64
|
||||
|
||||
namespace string
|
||||
selector labels.Selector
|
||||
resourceName v1.ResourceName
|
||||
metricName string
|
||||
namespace string
|
||||
selector labels.Selector
|
||||
metricSelector labels.Selector
|
||||
resourceName v1.ResourceName
|
||||
metricName string
|
||||
}
|
||||
|
||||
func (tc *testCase) prepareTestClient(t *testing.T) *fake.Clientset {
|
||||
@ -211,7 +212,7 @@ func (tc *testCase) runTest(t *testing.T) {
|
||||
info, timestamp, err := metricsClient.GetResourceMetric(tc.resourceName, tc.namespace, tc.selector)
|
||||
tc.verifyResults(t, info, timestamp, err)
|
||||
} else {
|
||||
info, timestamp, err := metricsClient.GetRawMetric(tc.metricName, tc.namespace, tc.selector)
|
||||
info, timestamp, err := metricsClient.GetRawMetric(tc.metricName, tc.namespace, tc.selector, tc.metricSelector)
|
||||
tc.verifyResults(t, info, timestamp, err)
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,12 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
customapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
customapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
resourceclient "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1"
|
||||
customclient "k8s.io/metrics/pkg/client/custom_metrics"
|
||||
externalclient "k8s.io/metrics/pkg/client/external_metrics"
|
||||
@ -101,8 +101,8 @@ type customMetricsClient struct {
|
||||
|
||||
// GetRawMetric gets the given metric (and an associated oldest timestamp)
|
||||
// for all pods matching the specified selector in the given namespace
|
||||
func (c *customMetricsClient) GetRawMetric(metricName string, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error) {
|
||||
metrics, err := c.client.NamespacedMetrics(namespace).GetForObjects(schema.GroupKind{Kind: "Pod"}, selector, metricName)
|
||||
func (c *customMetricsClient) GetRawMetric(metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (PodMetricsInfo, time.Time, error) {
|
||||
metrics, err := c.client.NamespacedMetrics(namespace).GetForObjects(schema.GroupKind{Kind: "Pod"}, selector, metricName, metricSelector)
|
||||
if err != nil {
|
||||
return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from custom metrics API: %v", err)
|
||||
}
|
||||
@ -123,7 +123,7 @@ func (c *customMetricsClient) GetRawMetric(metricName string, namespace string,
|
||||
|
||||
// GetObjectMetric gets the given metric (and an associated timestamp) for the given
|
||||
// object in the given namespace
|
||||
func (c *customMetricsClient) GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference) (int64, time.Time, error) {
|
||||
func (c *customMetricsClient) GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (int64, time.Time, error) {
|
||||
gvk := schema.FromAPIVersionAndKind(objectRef.APIVersion, objectRef.Kind)
|
||||
var metricValue *customapi.MetricValue
|
||||
var err error
|
||||
@ -131,9 +131,9 @@ func (c *customMetricsClient) GetObjectMetric(metricName string, namespace strin
|
||||
// handle namespace separately
|
||||
// NB: we ignore namespace name here, since CrossVersionObjectReference isn't
|
||||
// supposed to allow you to escape your namespace
|
||||
metricValue, err = c.client.RootScopedMetrics().GetForObject(gvk.GroupKind(), namespace, metricName)
|
||||
metricValue, err = c.client.RootScopedMetrics().GetForObject(gvk.GroupKind(), namespace, metricName, metricSelector)
|
||||
} else {
|
||||
metricValue, err = c.client.NamespacedMetrics(namespace).GetForObject(gvk.GroupKind(), objectRef.Name, metricName)
|
||||
metricValue, err = c.client.NamespacedMetrics(namespace).GetForObject(gvk.GroupKind(), objectRef.Name, metricName, metricSelector)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
autoscalingapi "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingapi "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@ -32,7 +32,7 @@ import (
|
||||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
emapi "k8s.io/metrics/pkg/apis/external_metrics/v1beta1"
|
||||
metricsapi "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
metricsfake "k8s.io/metrics/pkg/client/clientset/versioned/fake"
|
||||
@ -143,9 +143,11 @@ func (tc *restClientTestCase) prepareTestClient(t *testing.T) (*metricsfake.Clie
|
||||
APIVersion: "v1",
|
||||
Name: fmt.Sprintf("%s-%d", podNamePrefix, i),
|
||||
},
|
||||
Value: *resource.NewMilliQuantity(int64(metricPoint.level), resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: timestamp},
|
||||
MetricName: tc.metricName,
|
||||
Value: *resource.NewMilliQuantity(int64(metricPoint.level), resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: timestamp},
|
||||
Metric: cmapi.MetricIdentifier{
|
||||
Name: tc.metricName,
|
||||
},
|
||||
}
|
||||
|
||||
metrics.Items = append(metrics.Items, metric)
|
||||
@ -176,9 +178,11 @@ func (tc *restClientTestCase) prepareTestClient(t *testing.T) (*metricsfake.Clie
|
||||
APIVersion: tc.singleObject.APIVersion,
|
||||
Name: tc.singleObject.Name,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: timestamp},
|
||||
MetricName: tc.metricName,
|
||||
Value: *resource.NewMilliQuantity(int64(metricPoint.level), resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: timestamp},
|
||||
Metric: cmapi.MetricIdentifier{
|
||||
Name: tc.metricName,
|
||||
},
|
||||
Value: *resource.NewMilliQuantity(int64(metricPoint.level), resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -227,10 +231,10 @@ func (tc *restClientTestCase) runTest(t *testing.T) {
|
||||
}
|
||||
tc.verifyResults(t, info, timestamp, err)
|
||||
} else if tc.singleObject == nil {
|
||||
info, timestamp, err := metricsClient.GetRawMetric(tc.metricName, tc.namespace, tc.selector)
|
||||
info, timestamp, err := metricsClient.GetRawMetric(tc.metricName, tc.namespace, tc.selector, tc.metricLabelSelector)
|
||||
tc.verifyResults(t, info, timestamp, err)
|
||||
} else {
|
||||
val, timestamp, err := metricsClient.GetObjectMetric(tc.metricName, tc.namespace, tc.singleObject)
|
||||
val, timestamp, err := metricsClient.GetObjectMetric(tc.metricName, tc.namespace, tc.singleObject, tc.metricLabelSelector)
|
||||
info := PodMetricsInfo{tc.singleObject.Name: val}
|
||||
tc.verifyResults(t, info, timestamp, err)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -159,8 +159,8 @@ func (c *ReplicaCalculator) GetRawResourceReplicas(currentReplicas int32, target
|
||||
// GetMetricReplicas calculates the desired replica count based on a target metric utilization
|
||||
// (as a milli-value) for pods matching the given selector in the given namespace, and the
|
||||
// current replica count
|
||||
func (c *ReplicaCalculator) GetMetricReplicas(currentReplicas int32, targetUtilization int64, metricName string, namespace string, selector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
||||
metrics, timestamp, err := c.metricsClient.GetRawMetric(metricName, namespace, selector)
|
||||
func (c *ReplicaCalculator) GetMetricReplicas(currentReplicas int32, targetUtilization int64, metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
||||
metrics, timestamp, err := c.metricsClient.GetRawMetric(metricName, namespace, selector, metricSelector)
|
||||
if err != nil {
|
||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v", metricName, err)
|
||||
}
|
||||
@ -238,8 +238,8 @@ func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMet
|
||||
|
||||
// GetObjectMetricReplicas calculates the desired replica count based on a target metric utilization (as a milli-value)
|
||||
// for the given object in the given namespace, and the current replica count.
|
||||
func (c *ReplicaCalculator) GetObjectMetricReplicas(currentReplicas int32, targetUtilization int64, metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, selector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
||||
utilization, timestamp, err = c.metricsClient.GetObjectMetric(metricName, namespace, objectRef)
|
||||
func (c *ReplicaCalculator) GetObjectMetricReplicas(currentReplicas int32, targetUtilization int64, metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
||||
utilization, timestamp, err = c.metricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
|
||||
if err != nil {
|
||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
|
||||
}
|
||||
|
@ -22,20 +22,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
"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"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||
metricsclient "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||
cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta1"
|
||||
cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||
emapi "k8s.io/metrics/pkg/apis/external_metrics/v1beta1"
|
||||
metricsapi "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
metricsfake "k8s.io/metrics/pkg/client/clientset/versioned/fake"
|
||||
@ -86,8 +86,9 @@ type replicaCalcTestCase struct {
|
||||
|
||||
timestamp time.Time
|
||||
|
||||
resource *resourceInfo
|
||||
metric *metricInfo
|
||||
resource *resourceInfo
|
||||
metric *metricInfo
|
||||
metricLabelSelector labels.Selector
|
||||
|
||||
podReadiness []v1.ConditionStatus
|
||||
podStartTime []metav1.Time
|
||||
@ -235,9 +236,11 @@ func (tc *replicaCalcTestCase) prepareTestCMClient(t *testing.T) *cmfake.FakeCus
|
||||
Name: fmt.Sprintf("%s-%d", podNamePrefix, i),
|
||||
Namespace: testNamespace,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: tc.timestamp},
|
||||
MetricName: tc.metric.name,
|
||||
Value: *resource.NewMilliQuantity(level, resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: tc.timestamp},
|
||||
Metric: cmapi.MetricIdentifier{
|
||||
Name: tc.metric.name,
|
||||
},
|
||||
Value: *resource.NewMilliQuantity(level, resource.DecimalSI),
|
||||
}
|
||||
metrics.Items = append(metrics.Items, podMetric)
|
||||
}
|
||||
@ -265,9 +268,11 @@ func (tc *replicaCalcTestCase) prepareTestCMClient(t *testing.T) *cmfake.FakeCus
|
||||
APIVersion: tc.metric.singleObject.APIVersion,
|
||||
Name: name,
|
||||
},
|
||||
Timestamp: metav1.Time{Time: tc.timestamp},
|
||||
MetricName: tc.metric.name,
|
||||
Value: *resource.NewMilliQuantity(int64(tc.metric.levels[0]), resource.DecimalSI),
|
||||
Timestamp: metav1.Time{Time: tc.timestamp},
|
||||
Metric: cmapi.MetricIdentifier{
|
||||
Name: tc.metric.name,
|
||||
},
|
||||
Value: *resource.NewMilliQuantity(int64(tc.metric.levels[0]), resource.DecimalSI),
|
||||
},
|
||||
}
|
||||
|
||||
@ -322,7 +327,7 @@ func (tc *replicaCalcTestCase) prepareTestClient(t *testing.T) (*fake.Clientset,
|
||||
|
||||
func (tc *replicaCalcTestCase) runTest(t *testing.T) {
|
||||
testClient, testMetricsClient, testCMClient, testEMClient := tc.prepareTestClient(t)
|
||||
metricsClient := metrics.NewRESTMetricsClient(testMetricsClient.MetricsV1beta1(), testCMClient, testEMClient)
|
||||
metricsClient := metricsclient.NewRESTMetricsClient(testMetricsClient.MetricsV1beta1(), testCMClient, testEMClient)
|
||||
|
||||
replicaCalc := NewReplicaCalculator(metricsClient, testClient.Core(), defaultTestingTolerance, defaultTestingCpuTaintAfterStart, defaultTestingDelayOfInitialReadinessStatus)
|
||||
|
||||
@ -357,7 +362,7 @@ func (tc *replicaCalcTestCase) runTest(t *testing.T) {
|
||||
if tc.metric.singleObject == nil {
|
||||
t.Fatal("Metric specified as objectMetric but metric.singleObject is nil.")
|
||||
}
|
||||
outReplicas, outUtilization, outTimestamp, err = replicaCalc.GetObjectMetricReplicas(tc.currentReplicas, tc.metric.targetUtilization, tc.metric.name, testNamespace, tc.metric.singleObject, selector)
|
||||
outReplicas, outUtilization, outTimestamp, err = replicaCalc.GetObjectMetricReplicas(tc.currentReplicas, tc.metric.targetUtilization, tc.metric.name, testNamespace, tc.metric.singleObject, selector, nil)
|
||||
case externalMetric:
|
||||
if tc.metric.selector == nil {
|
||||
t.Fatal("Metric specified as externalMetric but metric.selector is nil.")
|
||||
@ -376,7 +381,7 @@ func (tc *replicaCalcTestCase) runTest(t *testing.T) {
|
||||
|
||||
outReplicas, outUtilization, outTimestamp, err = replicaCalc.GetExternalPerPodMetricReplicas(tc.currentReplicas, tc.metric.perPodTargetUtilization, tc.metric.name, testNamespace, tc.metric.selector)
|
||||
case podMetric:
|
||||
outReplicas, outUtilization, outTimestamp, err = replicaCalc.GetMetricReplicas(tc.currentReplicas, tc.metric.targetUtilization, tc.metric.name, testNamespace, selector)
|
||||
outReplicas, outUtilization, outTimestamp, err = replicaCalc.GetMetricReplicas(tc.currentReplicas, tc.metric.targetUtilization, tc.metric.name, testNamespace, selector, nil)
|
||||
default:
|
||||
t.Fatalf("Unknown metric type: %d", tc.metric.metricType)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user