k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/apis/autoscaling/v2beta1/defaults_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v2beta1_test 18 19 import ( 20 "reflect" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" 25 v1 "k8s.io/api/core/v1" 26 apiequality "k8s.io/apimachinery/pkg/api/equality" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 "k8s.io/apimachinery/pkg/runtime" 29 "k8s.io/kubernetes/pkg/api/legacyscheme" 30 "k8s.io/kubernetes/pkg/apis/autoscaling" 31 _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" 32 . "k8s.io/kubernetes/pkg/apis/autoscaling/v2beta1" 33 _ "k8s.io/kubernetes/pkg/apis/core/install" 34 utilpointer "k8s.io/utils/pointer" 35 ) 36 37 func TestSetDefaultHPA(t *testing.T) { 38 utilizationDefaultVal := int32(autoscaling.DefaultCPUUtilization) 39 defaultReplicas := utilpointer.Int32(1) 40 defaultTemplate := []autoscalingv2beta1.MetricSpec{ 41 { 42 Type: autoscalingv2beta1.ResourceMetricSourceType, 43 Resource: &autoscalingv2beta1.ResourceMetricSource{ 44 Name: v1.ResourceCPU, 45 TargetAverageUtilization: &utilizationDefaultVal, 46 }, 47 }, 48 } 49 50 tests := []struct { 51 original *autoscalingv2beta1.HorizontalPodAutoscaler 52 expected *autoscalingv2beta1.HorizontalPodAutoscaler 53 }{ 54 { // MinReplicas default value 55 original: &autoscalingv2beta1.HorizontalPodAutoscaler{ 56 Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{ 57 Metrics: defaultTemplate, 58 }, 59 }, 60 expected: &autoscalingv2beta1.HorizontalPodAutoscaler{ 61 Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{ 62 MinReplicas: defaultReplicas, 63 Metrics: defaultTemplate, 64 }, 65 }, 66 }, 67 { // MinReplicas update 68 original: &autoscalingv2beta1.HorizontalPodAutoscaler{ 69 Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{ 70 MinReplicas: utilpointer.Int32(3), 71 Metrics: defaultTemplate, 72 }, 73 }, 74 expected: &autoscalingv2beta1.HorizontalPodAutoscaler{ 75 Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{ 76 MinReplicas: utilpointer.Int32(3), 77 Metrics: defaultTemplate, 78 }, 79 }, 80 }, 81 { // Metrics default value 82 original: &autoscalingv2beta1.HorizontalPodAutoscaler{ 83 Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{ 84 MinReplicas: defaultReplicas, 85 }, 86 }, 87 expected: &autoscalingv2beta1.HorizontalPodAutoscaler{ 88 Spec: autoscalingv2beta1.HorizontalPodAutoscalerSpec{ 89 MinReplicas: defaultReplicas, 90 Metrics: defaultTemplate, 91 }, 92 }, 93 }, 94 } 95 96 for i, test := range tests { 97 original := test.original 98 expected := test.expected 99 obj2 := roundTrip(t, runtime.Object(original)) 100 got, ok := obj2.(*autoscalingv2beta1.HorizontalPodAutoscaler) 101 if !ok { 102 t.Fatalf("(%d) unexpected object: %v", i, obj2) 103 } 104 if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) { 105 t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec) 106 } 107 } 108 } 109 110 func TestHorizontalPodAutoscalerAnnotations(t *testing.T) { 111 tests := []struct { 112 hpa autoscalingv2beta1.HorizontalPodAutoscaler 113 test string 114 }{ 115 { 116 hpa: autoscalingv2beta1.HorizontalPodAutoscaler{ 117 ObjectMeta: metav1.ObjectMeta{ 118 Annotations: map[string]string{ 119 autoscaling.HorizontalPodAutoscalerConditionsAnnotation: "", 120 autoscaling.MetricSpecsAnnotation: "", 121 autoscaling.BehaviorSpecsAnnotation: "", 122 autoscaling.MetricStatusesAnnotation: "", 123 }, 124 }, 125 }, 126 test: "test empty value for Annotations", 127 }, 128 { 129 hpa: autoscalingv2beta1.HorizontalPodAutoscaler{ 130 ObjectMeta: metav1.ObjectMeta{ 131 Annotations: map[string]string{ 132 autoscaling.HorizontalPodAutoscalerConditionsAnnotation: "abc", 133 autoscaling.MetricSpecsAnnotation: "abc", 134 autoscaling.BehaviorSpecsAnnotation: "abc", 135 autoscaling.MetricStatusesAnnotation: "abc", 136 }, 137 }, 138 }, 139 test: "test random value for Annotations", 140 }, 141 { 142 hpa: autoscalingv2beta1.HorizontalPodAutoscaler{ 143 ObjectMeta: metav1.ObjectMeta{ 144 Annotations: map[string]string{ 145 autoscaling.HorizontalPodAutoscalerConditionsAnnotation: "[]", 146 autoscaling.MetricSpecsAnnotation: "[]", 147 autoscaling.BehaviorSpecsAnnotation: "[]", 148 autoscaling.MetricStatusesAnnotation: "[]", 149 }, 150 }, 151 }, 152 test: "test empty array value for Annotations", 153 }, 154 } 155 156 for _, test := range tests { 157 hpa := &test.hpa 158 hpaBeforeMuatate := *hpa.DeepCopy() 159 obj := roundTrip(t, runtime.Object(hpa)) 160 final_obj, ok := obj.(*autoscalingv2beta1.HorizontalPodAutoscaler) 161 if !ok { 162 t.Fatalf("unexpected object: %v", obj) 163 } 164 if !reflect.DeepEqual(*hpa, hpaBeforeMuatate) { 165 t.Errorf("diff: %v", cmp.Diff(*hpa, hpaBeforeMuatate)) 166 t.Errorf("expected: %#v\n actual: %#v", *hpa, hpaBeforeMuatate) 167 } 168 169 if len(final_obj.ObjectMeta.Annotations) != 0 { 170 t.Fatalf("unexpected annotations: %v", final_obj.ObjectMeta.Annotations) 171 } 172 } 173 } 174 175 func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { 176 data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj) 177 if err != nil { 178 t.Errorf("%v\n %#v", err, obj) 179 return nil 180 } 181 obj2, err := runtime.Decode(legacyscheme.Codecs.UniversalDecoder(), data) 182 if err != nil { 183 t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) 184 return nil 185 } 186 obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) 187 err = legacyscheme.Scheme.Convert(obj2, obj3, nil) 188 if err != nil { 189 t.Errorf("%v\nSource: %#v", err, obj2) 190 return nil 191 } 192 return obj3 193 }