mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1655 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			1655 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2016 The Kubernetes Authors.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package validation
 | 
						|
 | 
						|
import (
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"k8s.io/apimachinery/pkg/api/resource"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						|
	featuregatetesting "k8s.io/component-base/featuregate/testing"
 | 
						|
	"k8s.io/kubernetes/pkg/apis/autoscaling"
 | 
						|
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						|
	"k8s.io/kubernetes/pkg/features"
 | 
						|
	utilpointer "k8s.io/utils/pointer"
 | 
						|
)
 | 
						|
 | 
						|
func TestValidateScale(t *testing.T) {
 | 
						|
	successCases := []autoscaling.Scale{{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "frontend",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.ScaleSpec{
 | 
						|
			Replicas: 1,
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "frontend",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.ScaleSpec{
 | 
						|
			Replicas: 10,
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "frontend",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.ScaleSpec{
 | 
						|
			Replicas: 0,
 | 
						|
		},
 | 
						|
	}}
 | 
						|
 | 
						|
	for _, successCase := range successCases {
 | 
						|
		if errs := ValidateScale(&successCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	errorCases := []struct {
 | 
						|
		scale autoscaling.Scale
 | 
						|
		msg   string
 | 
						|
	}{{
 | 
						|
		scale: autoscaling.Scale{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      "frontend",
 | 
						|
				Namespace: metav1.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: autoscaling.ScaleSpec{
 | 
						|
				Replicas: -1,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must be greater than or equal to 0",
 | 
						|
	}}
 | 
						|
 | 
						|
	for _, c := range errorCases {
 | 
						|
		if errs := ValidateScale(&c.scale); len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %s", c.msg)
 | 
						|
		} else if !strings.Contains(errs[0].Error(), c.msg) {
 | 
						|
			t.Errorf("unexpected error: %v, expected: %s", errs[0], c.msg)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateBehavior(t *testing.T) {
 | 
						|
	maxPolicy := autoscaling.MaxPolicySelect
 | 
						|
	minPolicy := autoscaling.MinPolicySelect
 | 
						|
	disabledPolicy := autoscaling.DisabledPolicySelect
 | 
						|
	incorrectPolicy := autoscaling.ScalingPolicySelect("incorrect")
 | 
						|
	simplePoliciesList := []autoscaling.HPAScalingPolicy{{
 | 
						|
		Type:          autoscaling.PercentScalingPolicy,
 | 
						|
		Value:         10,
 | 
						|
		PeriodSeconds: 1,
 | 
						|
	}, {
 | 
						|
		Type:          autoscaling.PodsScalingPolicy,
 | 
						|
		Value:         1,
 | 
						|
		PeriodSeconds: 1800,
 | 
						|
	}}
 | 
						|
	successCases := []autoscaling.HorizontalPodAutoscalerBehavior{{
 | 
						|
		ScaleUp:   nil,
 | 
						|
		ScaleDown: nil,
 | 
						|
	}, {
 | 
						|
		ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
			StabilizationWindowSeconds: utilpointer.Int32(3600),
 | 
						|
			SelectPolicy:               &minPolicy,
 | 
						|
			Policies:                   simplePoliciesList,
 | 
						|
		},
 | 
						|
		ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
			StabilizationWindowSeconds: utilpointer.Int32(0),
 | 
						|
			SelectPolicy:               &disabledPolicy,
 | 
						|
			Policies:                   simplePoliciesList,
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
			StabilizationWindowSeconds: utilpointer.Int32(120),
 | 
						|
			SelectPolicy:               &maxPolicy,
 | 
						|
			Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
				Type:          autoscaling.PodsScalingPolicy,
 | 
						|
				Value:         1,
 | 
						|
				PeriodSeconds: 2,
 | 
						|
			}, {
 | 
						|
				Type:          autoscaling.PercentScalingPolicy,
 | 
						|
				Value:         3,
 | 
						|
				PeriodSeconds: 4,
 | 
						|
			}, {
 | 
						|
				Type:          autoscaling.PodsScalingPolicy,
 | 
						|
				Value:         5,
 | 
						|
				PeriodSeconds: 6,
 | 
						|
			}, {
 | 
						|
				Type:          autoscaling.PercentScalingPolicy,
 | 
						|
				Value:         7,
 | 
						|
				PeriodSeconds: 8,
 | 
						|
			}},
 | 
						|
		},
 | 
						|
		ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
			StabilizationWindowSeconds: utilpointer.Int32(120),
 | 
						|
			SelectPolicy:               &maxPolicy,
 | 
						|
			Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
				Type:          autoscaling.PodsScalingPolicy,
 | 
						|
				Value:         1,
 | 
						|
				PeriodSeconds: 2,
 | 
						|
			}, {
 | 
						|
				Type:          autoscaling.PercentScalingPolicy,
 | 
						|
				Value:         3,
 | 
						|
				PeriodSeconds: 4,
 | 
						|
			}, {
 | 
						|
				Type:          autoscaling.PodsScalingPolicy,
 | 
						|
				Value:         5,
 | 
						|
				PeriodSeconds: 6,
 | 
						|
			}, {
 | 
						|
				Type:          autoscaling.PercentScalingPolicy,
 | 
						|
				Value:         7,
 | 
						|
				PeriodSeconds: 8,
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}}
 | 
						|
	for _, behavior := range successCases {
 | 
						|
		hpa := prepareHPAWithBehavior(behavior)
 | 
						|
		if errs := ValidateHorizontalPodAutoscaler(&hpa); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	errorCases := []struct {
 | 
						|
		behavior autoscaling.HorizontalPodAutoscalerBehavior
 | 
						|
		msg      string
 | 
						|
	}{{
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				SelectPolicy: &minPolicy,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.policies: Required value: must specify at least one Policy",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				StabilizationWindowSeconds: utilpointer.Int32(3601),
 | 
						|
				SelectPolicy:               &minPolicy,
 | 
						|
				Policies:                   simplePoliciesList,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.stabilizationWindowSeconds: Invalid value: 3601: must be less than or equal to 3600",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					Value:         7,
 | 
						|
					PeriodSeconds: 1801,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.policies[0].periodSeconds: Invalid value: 1801: must be less than or equal to 1800",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				SelectPolicy: &incorrectPolicy,
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					Value:         7,
 | 
						|
					PeriodSeconds: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: `spec.behavior.scaleUp.selectPolicy: Unsupported value: "incorrect": supported values: "Disabled", "Max", "Min"`,
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.HPAScalingPolicyType("hm"),
 | 
						|
					Value:         7,
 | 
						|
					PeriodSeconds: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: `spec.behavior.scaleUp.policies[0].type: Unsupported value: "hm": supported values: "Percent", "Pods"`,
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:  autoscaling.PodsScalingPolicy,
 | 
						|
					Value: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.policies[0].periodSeconds: Invalid value: 0: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					PeriodSeconds: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.policies[0].value: Invalid value: 0: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					PeriodSeconds: -1,
 | 
						|
					Value:         1,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.policies[0].periodSeconds: Invalid value: -1: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleUp: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					PeriodSeconds: 1,
 | 
						|
					Value:         -1,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleUp.policies[0].value: Invalid value: -1: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				SelectPolicy: &minPolicy,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.policies: Required value: must specify at least one Policy",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				StabilizationWindowSeconds: utilpointer.Int32(3601),
 | 
						|
				SelectPolicy:               &minPolicy,
 | 
						|
				Policies:                   simplePoliciesList,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.stabilizationWindowSeconds: Invalid value: 3601: must be less than or equal to 3600",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PercentScalingPolicy,
 | 
						|
					Value:         7,
 | 
						|
					PeriodSeconds: 1801,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.policies[0].periodSeconds: Invalid value: 1801: must be less than or equal to 1800",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				SelectPolicy: &incorrectPolicy,
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					Value:         7,
 | 
						|
					PeriodSeconds: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: `spec.behavior.scaleDown.selectPolicy: Unsupported value: "incorrect": supported values: "Disabled", "Max", "Min"`,
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.HPAScalingPolicyType("hm"),
 | 
						|
					Value:         7,
 | 
						|
					PeriodSeconds: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: `spec.behavior.scaleDown.policies[0].type: Unsupported value: "hm": supported values: "Percent", "Pods"`,
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:  autoscaling.PodsScalingPolicy,
 | 
						|
					Value: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.policies[0].periodSeconds: Invalid value: 0: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					PeriodSeconds: 8,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.policies[0].value: Invalid value: 0: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					PeriodSeconds: -1,
 | 
						|
					Value:         1,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.policies[0].periodSeconds: Invalid value: -1: must be greater than zero",
 | 
						|
	}, {
 | 
						|
		behavior: autoscaling.HorizontalPodAutoscalerBehavior{
 | 
						|
			ScaleDown: &autoscaling.HPAScalingRules{
 | 
						|
				Policies: []autoscaling.HPAScalingPolicy{{
 | 
						|
					Type:          autoscaling.PodsScalingPolicy,
 | 
						|
					PeriodSeconds: 1,
 | 
						|
					Value:         -1,
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "spec.behavior.scaleDown.policies[0].value: Invalid value: -1: must be greater than zero",
 | 
						|
	}}
 | 
						|
	for _, c := range errorCases {
 | 
						|
		hpa := prepareHPAWithBehavior(c.behavior)
 | 
						|
		if errs := ValidateHorizontalPodAutoscaler(&hpa); len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %s", c.msg)
 | 
						|
		} else if !strings.Contains(errs[0].Error(), c.msg) {
 | 
						|
			t.Errorf("unexpected error: %v, expected: %s", errs[0], c.msg)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func prepareHPAWithBehavior(b autoscaling.HorizontalPodAutoscalerBehavior) autoscaling.HorizontalPodAutoscaler {
 | 
						|
	return autoscaling.HorizontalPodAutoscaler{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ResourceMetricSourceType,
 | 
						|
				Resource: &autoscaling.ResourceMetricSource{
 | 
						|
					Name: api.ResourceCPU,
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:               autoscaling.UtilizationMetricType,
 | 
						|
						AverageUtilization: utilpointer.Int32(70),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
			Behavior: &b,
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateHorizontalPodAutoscaler(t *testing.T) {
 | 
						|
	metricLabelSelector, err := metav1.ParseToLabelSelector("label=value")
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("unable to parse label selector: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	successCases := []autoscaling.HorizontalPodAutoscaler{{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ResourceMetricSourceType,
 | 
						|
				Resource: &autoscaling.ResourceMetricSource{
 | 
						|
					Name: api.ResourceCPU,
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:               autoscaling.UtilizationMetricType,
 | 
						|
						AverageUtilization: utilpointer.Int32(70),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ResourceMetricSourceType,
 | 
						|
				Resource: &autoscaling.ResourceMetricSource{
 | 
						|
					Name: api.ResourceCPU,
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:         autoscaling.AverageValueMetricType,
 | 
						|
						AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.PodsMetricSourceType,
 | 
						|
				Pods: &autoscaling.PodsMetricSource{
 | 
						|
					Metric: autoscaling.MetricIdentifier{
 | 
						|
						Name: "somemetric",
 | 
						|
					},
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:         autoscaling.AverageValueMetricType,
 | 
						|
						AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
				ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
					Name:      api.ResourceCPU,
 | 
						|
					Container: "test-container",
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:               autoscaling.UtilizationMetricType,
 | 
						|
						AverageUtilization: utilpointer.Int32(70),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
				ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
					Name:      api.ResourceCPU,
 | 
						|
					Container: "test-container",
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:         autoscaling.AverageValueMetricType,
 | 
						|
						AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ObjectMetricSourceType,
 | 
						|
				Object: &autoscaling.ObjectMetricSource{
 | 
						|
					DescribedObject: autoscaling.CrossVersionObjectReference{
 | 
						|
						Kind: "ReplicationController",
 | 
						|
						Name: "myrc",
 | 
						|
					},
 | 
						|
					Metric: autoscaling.MetricIdentifier{
 | 
						|
						Name: "somemetric",
 | 
						|
					},
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:  autoscaling.ValueMetricType,
 | 
						|
						Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ExternalMetricSourceType,
 | 
						|
				External: &autoscaling.ExternalMetricSource{
 | 
						|
					Metric: autoscaling.MetricIdentifier{
 | 
						|
						Name:     "somemetric",
 | 
						|
						Selector: metricLabelSelector,
 | 
						|
					},
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:  autoscaling.ValueMetricType,
 | 
						|
						Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      "myautoscaler",
 | 
						|
			Namespace: metav1.NamespaceDefault,
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(1),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ExternalMetricSourceType,
 | 
						|
				External: &autoscaling.ExternalMetricSource{
 | 
						|
					Metric: autoscaling.MetricIdentifier{
 | 
						|
						Name:     "somemetric",
 | 
						|
						Selector: metricLabelSelector,
 | 
						|
					},
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:         autoscaling.AverageValueMetricType,
 | 
						|
						AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}}
 | 
						|
	for _, successCase := range successCases {
 | 
						|
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	errorCases := []struct {
 | 
						|
		horizontalPodAutoscaler autoscaling.HorizontalPodAutoscaler
 | 
						|
		msg                     string
 | 
						|
	}{{
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.kind: Required",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.kind: Required",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "..", Name: "myrc"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.kind: Invalid",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "..", Name: "myrc"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.kind: Invalid",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.name: Required",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.name: Required",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController", Name: ".."},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.name: Invalid",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController", Name: ".."},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "scaleTargetRef.name: Invalid",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: metav1.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{},
 | 
						|
				MinReplicas:    utilpointer.Int32(-1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must be greater than or equal to 1",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: metav1.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{},
 | 
						|
				MinReplicas:    utilpointer.Int32(7),
 | 
						|
				MaxReplicas:    5,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must be greater than or equal to `minReplicas`",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: metav1.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
							AverageValue:       resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "may not set both a target raw value and a target utilization",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: metav1.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
							AverageValue:       resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "may not set both a target raw value and a target utilization",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a resource name",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a resource name",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      "InvalidResource",
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(70),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "Invalid value: InvalidResource: must be a standard resource type or fully qualified",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(-10),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must be greater than 0",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(-10),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must be greater than 0",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(-10),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a container",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "---***",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:               autoscaling.UtilizationMetricType,
 | 
						|
							AverageUtilization: utilpointer.Int32(-10),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "Invalid value: \"---***\"",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ResourceMetricSourceType,
 | 
						|
					Resource: &autoscaling.ResourceMetricSource{
 | 
						|
						Name: api.ResourceCPU,
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type: autoscaling.ValueMetricType,
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must set either a target raw value or a target utilization",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ContainerResourceMetricSourceType,
 | 
						|
					ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
						Name:      api.ResourceCPU,
 | 
						|
						Container: "test-application",
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type: autoscaling.ValueMetricType,
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must set either a target raw value or a target utilization",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.PodsMetricSourceType,
 | 
						|
					Pods: &autoscaling.PodsMetricSource{
 | 
						|
						Metric: autoscaling.MetricIdentifier{},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:         autoscaling.ValueMetricType,
 | 
						|
							AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a metric name",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.PodsMetricSourceType,
 | 
						|
					Pods: &autoscaling.PodsMetricSource{
 | 
						|
						Metric: autoscaling.MetricIdentifier{
 | 
						|
							Name: "somemetric",
 | 
						|
						},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type: autoscaling.ValueMetricType,
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a positive target averageValue",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ObjectMetricSourceType,
 | 
						|
					Object: &autoscaling.ObjectMetricSource{
 | 
						|
						DescribedObject: autoscaling.CrossVersionObjectReference{
 | 
						|
							Kind: "ReplicationController",
 | 
						|
							Name: "myrc",
 | 
						|
						},
 | 
						|
						Metric: autoscaling.MetricIdentifier{
 | 
						|
							Name: "somemetric",
 | 
						|
						},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type: autoscaling.ValueMetricType,
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must set either a target value or averageValue",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ObjectMetricSourceType,
 | 
						|
					Object: &autoscaling.ObjectMetricSource{
 | 
						|
						DescribedObject: autoscaling.CrossVersionObjectReference{
 | 
						|
							Name: "myrc",
 | 
						|
						},
 | 
						|
						Metric: autoscaling.MetricIdentifier{
 | 
						|
							Name: "somemetric",
 | 
						|
						},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:  autoscaling.ValueMetricType,
 | 
						|
							Value: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "object.describedObject.kind: Required",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ObjectMetricSourceType,
 | 
						|
					Object: &autoscaling.ObjectMetricSource{
 | 
						|
						DescribedObject: autoscaling.CrossVersionObjectReference{
 | 
						|
							Kind: "ReplicationController",
 | 
						|
							Name: "myrc",
 | 
						|
						},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:  autoscaling.ValueMetricType,
 | 
						|
							Value: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a metric name",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ExternalMetricSourceType,
 | 
						|
					External: &autoscaling.ExternalMetricSource{
 | 
						|
						Metric: autoscaling.MetricIdentifier{
 | 
						|
							Selector: metricLabelSelector,
 | 
						|
						},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:  autoscaling.ValueMetricType,
 | 
						|
							Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "must specify a metric name",
 | 
						|
	}, {
 | 
						|
		horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
			ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
				MinReplicas:    utilpointer.Int32(1),
 | 
						|
				MaxReplicas:    5,
 | 
						|
				Metrics: []autoscaling.MetricSpec{{
 | 
						|
					Type: autoscaling.ExternalMetricSourceType,
 | 
						|
					External: &autoscaling.ExternalMetricSource{
 | 
						|
						Metric: autoscaling.MetricIdentifier{
 | 
						|
							Name:     "foo/../",
 | 
						|
							Selector: metricLabelSelector,
 | 
						|
						},
 | 
						|
						Target: autoscaling.MetricTarget{
 | 
						|
							Type:  autoscaling.ValueMetricType,
 | 
						|
							Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
						},
 | 
						|
					},
 | 
						|
				}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		msg: "'/'",
 | 
						|
	},
 | 
						|
 | 
						|
		{
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type: autoscaling.ValueMetricType,
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must set either a target value for metric or a per-pod target",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type:  autoscaling.ValueMetricType,
 | 
						|
								Value: resource.NewMilliQuantity(-300, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must be positive",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type:         autoscaling.ValueMetricType,
 | 
						|
								AverageValue: resource.NewMilliQuantity(-300, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must be positive",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type:         autoscaling.ValueMetricType,
 | 
						|
								Value:        resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
								AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "may not set both a target value for metric and a per-pod target",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type:  "boogity",
 | 
						|
								Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must be either Utilization, Value, or AverageValue",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must specify a metric target type",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ExternalMetricSourceType,
 | 
						|
						External: &autoscaling.ExternalMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name:     "somemetric",
 | 
						|
								Selector: metricLabelSelector,
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must specify a metric target",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{
 | 
						|
						{},
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must specify a metric source type",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.MetricSourceType("InvalidType"),
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "type: Unsupported value",
 | 
						|
		}, {
 | 
						|
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5,
 | 
						|
					Metrics: []autoscaling.MetricSpec{{
 | 
						|
						Type: autoscaling.ResourceMetricSourceType,
 | 
						|
						Resource: &autoscaling.ResourceMetricSource{
 | 
						|
							Name: api.ResourceCPU,
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type:         autoscaling.AverageValueMetricType,
 | 
						|
								AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
						Pods: &autoscaling.PodsMetricSource{
 | 
						|
							Metric: autoscaling.MetricIdentifier{
 | 
						|
								Name: "somemetric",
 | 
						|
							},
 | 
						|
							Target: autoscaling.MetricTarget{
 | 
						|
								Type:         autoscaling.AverageValueMetricType,
 | 
						|
								AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			msg: "must populate the given metric source only",
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, c := range errorCases {
 | 
						|
		errs := ValidateHorizontalPodAutoscaler(&c.horizontalPodAutoscaler)
 | 
						|
		if len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %q", c.msg)
 | 
						|
		} else if !strings.Contains(errs[0].Error(), c.msg) {
 | 
						|
			t.Errorf("unexpected error: %q, expected: %q", errs[0], c.msg)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	sourceTypes := map[autoscaling.MetricSourceType]autoscaling.MetricSpec{
 | 
						|
		autoscaling.ResourceMetricSourceType: {
 | 
						|
			Resource: &autoscaling.ResourceMetricSource{
 | 
						|
				Name: api.ResourceCPU,
 | 
						|
				Target: autoscaling.MetricTarget{
 | 
						|
					Type:         autoscaling.AverageValueMetricType,
 | 
						|
					AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		autoscaling.ContainerResourceMetricSourceType: {
 | 
						|
			ContainerResource: &autoscaling.ContainerResourceMetricSource{
 | 
						|
				Name:      api.ResourceCPU,
 | 
						|
				Container: "test-application",
 | 
						|
				Target: autoscaling.MetricTarget{
 | 
						|
					Type:         autoscaling.AverageValueMetricType,
 | 
						|
					AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		autoscaling.PodsMetricSourceType: {
 | 
						|
			Pods: &autoscaling.PodsMetricSource{
 | 
						|
				Metric: autoscaling.MetricIdentifier{
 | 
						|
					Name: "somemetric",
 | 
						|
				},
 | 
						|
				Target: autoscaling.MetricTarget{
 | 
						|
					Type:         autoscaling.AverageValueMetricType,
 | 
						|
					AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		autoscaling.ObjectMetricSourceType: {
 | 
						|
			Object: &autoscaling.ObjectMetricSource{
 | 
						|
				DescribedObject: autoscaling.CrossVersionObjectReference{
 | 
						|
					Kind: "ReplicationController",
 | 
						|
					Name: "myrc",
 | 
						|
				},
 | 
						|
				Metric: autoscaling.MetricIdentifier{
 | 
						|
					Name: "somemetric",
 | 
						|
				},
 | 
						|
				Target: autoscaling.MetricTarget{
 | 
						|
					Type:  autoscaling.ValueMetricType,
 | 
						|
					Value: resource.NewMilliQuantity(100, resource.DecimalSI),
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for correctType, spec := range sourceTypes {
 | 
						|
		for incorrectType := range sourceTypes {
 | 
						|
			if correctType == incorrectType {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			spec.Type = incorrectType
 | 
						|
 | 
						|
			errs := ValidateHorizontalPodAutoscaler(&autoscaling.HorizontalPodAutoscaler{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
 | 
						|
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
 | 
						|
					MinReplicas:    utilpointer.Int32(1),
 | 
						|
					MaxReplicas:    5, Metrics: []autoscaling.MetricSpec{spec},
 | 
						|
				},
 | 
						|
			})
 | 
						|
 | 
						|
			expectedMsg := "must populate information for the given metric source"
 | 
						|
 | 
						|
			if len(errs) == 0 {
 | 
						|
				t.Errorf("expected failure with type of %v and spec for %v", incorrectType, correctType)
 | 
						|
			} else if !strings.Contains(errs[0].Error(), expectedMsg) {
 | 
						|
				t.Errorf("unexpected error: %q, expected %q", errs[0], expectedMsg)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func prepareMinReplicasCases(t *testing.T, minReplicas int32) []autoscaling.HorizontalPodAutoscaler {
 | 
						|
	metricLabelSelector, err := metav1.ParseToLabelSelector("label=value")
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("unable to parse label selector: %v", err)
 | 
						|
	}
 | 
						|
	minReplicasCases := []autoscaling.HorizontalPodAutoscaler{{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:            "myautoscaler",
 | 
						|
			Namespace:       metav1.NamespaceDefault,
 | 
						|
			ResourceVersion: "theversion",
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(minReplicas),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ObjectMetricSourceType,
 | 
						|
				Object: &autoscaling.ObjectMetricSource{
 | 
						|
					DescribedObject: autoscaling.CrossVersionObjectReference{
 | 
						|
						Kind: "ReplicationController",
 | 
						|
						Name: "myrc",
 | 
						|
					},
 | 
						|
					Metric: autoscaling.MetricIdentifier{
 | 
						|
						Name: "somemetric",
 | 
						|
					},
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:  autoscaling.ValueMetricType,
 | 
						|
						Value: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:            "myautoscaler",
 | 
						|
			Namespace:       metav1.NamespaceDefault,
 | 
						|
			ResourceVersion: "theversion",
 | 
						|
		},
 | 
						|
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
 | 
						|
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
 | 
						|
				Kind: "ReplicationController",
 | 
						|
				Name: "myrc",
 | 
						|
			},
 | 
						|
			MinReplicas: utilpointer.Int32(minReplicas),
 | 
						|
			MaxReplicas: 5,
 | 
						|
			Metrics: []autoscaling.MetricSpec{{
 | 
						|
				Type: autoscaling.ExternalMetricSourceType,
 | 
						|
				External: &autoscaling.ExternalMetricSource{
 | 
						|
					Metric: autoscaling.MetricIdentifier{
 | 
						|
						Name:     "somemetric",
 | 
						|
						Selector: metricLabelSelector,
 | 
						|
					},
 | 
						|
					Target: autoscaling.MetricTarget{
 | 
						|
						Type:         autoscaling.AverageValueMetricType,
 | 
						|
						AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
 | 
						|
					},
 | 
						|
				},
 | 
						|
			}},
 | 
						|
		},
 | 
						|
	}}
 | 
						|
	return minReplicasCases
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateHorizontalPodAutoscalerScaleToZeroEnabled(t *testing.T) {
 | 
						|
	// Enable HPAScaleToZero feature gate.
 | 
						|
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, true)()
 | 
						|
 | 
						|
	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
 | 
						|
	for _, successCase := range zeroMinReplicasCases {
 | 
						|
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateHorizontalPodAutoscalerScaleToZeroDisabled(t *testing.T) {
 | 
						|
	// Disable HPAScaleToZero feature gate.
 | 
						|
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, false)()
 | 
						|
 | 
						|
	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
 | 
						|
	errorMsg := "must be greater than or equal to 1"
 | 
						|
 | 
						|
	for _, errorCase := range zeroMinReplicasCases {
 | 
						|
		errs := ValidateHorizontalPodAutoscaler(&errorCase)
 | 
						|
		if len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %q", errorMsg)
 | 
						|
		} else if !strings.Contains(errs[0].Error(), errorMsg) {
 | 
						|
			t.Errorf("unexpected error: %q, expected: %q", errs[0], errorMsg)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	nonZeroMinReplicasCases := prepareMinReplicasCases(t, 1)
 | 
						|
 | 
						|
	for _, successCase := range nonZeroMinReplicasCases {
 | 
						|
		successCase.Spec.MinReplicas = utilpointer.Int32(1)
 | 
						|
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateHorizontalPodAutoscalerUpdateScaleToZeroEnabled(t *testing.T) {
 | 
						|
	// Enable HPAScaleToZero feature gate.
 | 
						|
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, true)()
 | 
						|
 | 
						|
	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
 | 
						|
	nonZeroMinReplicasCases := prepareMinReplicasCases(t, 1)
 | 
						|
 | 
						|
	for i, zeroCase := range zeroMinReplicasCases {
 | 
						|
		nonZeroCase := nonZeroMinReplicasCases[i]
 | 
						|
 | 
						|
		if errs := ValidateHorizontalPodAutoscalerUpdate(&nonZeroCase, &zeroCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
 | 
						|
		if errs := ValidateHorizontalPodAutoscalerUpdate(&zeroCase, &nonZeroCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateHorizontalPodAutoscalerScaleToZeroUpdateDisabled(t *testing.T) {
 | 
						|
	// Disable HPAScaleToZero feature gate.
 | 
						|
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, false)()
 | 
						|
 | 
						|
	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
 | 
						|
	nonZeroMinReplicasCases := prepareMinReplicasCases(t, 1)
 | 
						|
	errorMsg := "must be greater than or equal to 1"
 | 
						|
 | 
						|
	for i, zeroCase := range zeroMinReplicasCases {
 | 
						|
		nonZeroCase := nonZeroMinReplicasCases[i]
 | 
						|
		errs := ValidateHorizontalPodAutoscalerUpdate(&zeroCase, &nonZeroCase)
 | 
						|
 | 
						|
		if len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %q", errorMsg)
 | 
						|
		} else if !strings.Contains(errs[0].Error(), errorMsg) {
 | 
						|
			t.Errorf("unexpected error: %q, expected: %q", errs[0], errorMsg)
 | 
						|
		}
 | 
						|
 | 
						|
		if errs := ValidateHorizontalPodAutoscalerUpdate(&zeroCase, &zeroCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
 | 
						|
		if errs := ValidateHorizontalPodAutoscalerUpdate(&nonZeroCase, &zeroCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |