1/* 2Copyright 2016 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package v1_test 18 19import ( 20 "reflect" 21 "testing" 22 23 autoscalingv1 "k8s.io/api/autoscaling/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/apimachinery/pkg/util/diff" 27 "k8s.io/kubernetes/pkg/api/legacyscheme" 28 "k8s.io/kubernetes/pkg/apis/autoscaling" 29 _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" 30 . "k8s.io/kubernetes/pkg/apis/autoscaling/v1" 31 _ "k8s.io/kubernetes/pkg/apis/core/install" 32 utilpointer "k8s.io/utils/pointer" 33) 34 35func TestSetDefaultHPA(t *testing.T) { 36 tests := []struct { 37 hpa autoscalingv1.HorizontalPodAutoscaler 38 expectReplicas int32 39 test string 40 }{ 41 { 42 hpa: autoscalingv1.HorizontalPodAutoscaler{}, 43 expectReplicas: 1, 44 test: "unspecified min replicas, use the default value", 45 }, 46 { 47 hpa: autoscalingv1.HorizontalPodAutoscaler{ 48 Spec: autoscalingv1.HorizontalPodAutoscalerSpec{ 49 MinReplicas: utilpointer.Int32Ptr(3), 50 }, 51 }, 52 expectReplicas: 3, 53 test: "set min replicas to 3", 54 }, 55 } 56 57 for _, test := range tests { 58 hpa := &test.hpa 59 obj2 := roundTrip(t, runtime.Object(hpa)) 60 hpa2, ok := obj2.(*autoscalingv1.HorizontalPodAutoscaler) 61 if !ok { 62 t.Fatalf("unexpected object: %v", obj2) 63 } 64 if hpa2.Spec.MinReplicas == nil { 65 t.Errorf("unexpected nil MinReplicas") 66 } else if test.expectReplicas != *hpa2.Spec.MinReplicas { 67 t.Errorf("expected: %d MinReplicas, got: %d", test.expectReplicas, *hpa2.Spec.MinReplicas) 68 } 69 } 70} 71 72func TestHorizontalPodAutoscalerAnnotations(t *testing.T) { 73 tests := []struct { 74 hpa autoscalingv1.HorizontalPodAutoscaler 75 test string 76 }{ 77 { 78 hpa: autoscalingv1.HorizontalPodAutoscaler{ 79 ObjectMeta: metav1.ObjectMeta{ 80 Annotations: map[string]string{ 81 autoscaling.HorizontalPodAutoscalerConditionsAnnotation: "", 82 autoscaling.MetricSpecsAnnotation: "", 83 autoscaling.BehaviorSpecsAnnotation: "", 84 autoscaling.MetricStatusesAnnotation: "", 85 }, 86 }, 87 }, 88 test: "test empty value for Annotations", 89 }, 90 { 91 hpa: autoscalingv1.HorizontalPodAutoscaler{ 92 ObjectMeta: metav1.ObjectMeta{ 93 Annotations: map[string]string{ 94 autoscaling.HorizontalPodAutoscalerConditionsAnnotation: "abc", 95 autoscaling.MetricSpecsAnnotation: "abc", 96 autoscaling.BehaviorSpecsAnnotation: "abc", 97 autoscaling.MetricStatusesAnnotation: "abc", 98 }, 99 }, 100 }, 101 test: "test random value for Annotations", 102 }, 103 { 104 hpa: autoscalingv1.HorizontalPodAutoscaler{ 105 ObjectMeta: metav1.ObjectMeta{ 106 Annotations: map[string]string{ 107 autoscaling.HorizontalPodAutoscalerConditionsAnnotation: "[]", 108 autoscaling.MetricSpecsAnnotation: "[]", 109 autoscaling.BehaviorSpecsAnnotation: "[]", 110 autoscaling.MetricStatusesAnnotation: "[]", 111 }, 112 }, 113 }, 114 test: "test empty array value for Annotations", 115 }, 116 } 117 118 for _, test := range tests { 119 hpa := &test.hpa 120 hpaBeforeMuatate := *hpa.DeepCopy() 121 obj := roundTrip(t, runtime.Object(hpa)) 122 final_obj, ok := obj.(*autoscalingv1.HorizontalPodAutoscaler) 123 if !ok { 124 t.Fatalf("unexpected object: %v", obj) 125 } 126 if !reflect.DeepEqual(*hpa, hpaBeforeMuatate) { 127 t.Errorf("diff: %v", diff.ObjectDiff(*hpa, hpaBeforeMuatate)) 128 t.Errorf("expected: %#v\n actual: %#v", *hpa, hpaBeforeMuatate) 129 } 130 131 if len(final_obj.ObjectMeta.Annotations) != 0 { 132 t.Fatalf("unexpected annotations: %v", final_obj.ObjectMeta.Annotations) 133 } 134 } 135} 136 137func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { 138 data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj) 139 if err != nil { 140 t.Errorf("%v\n %#v", err, obj) 141 return nil 142 } 143 obj2, err := runtime.Decode(legacyscheme.Codecs.UniversalDecoder(), data) 144 if err != nil { 145 t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) 146 return nil 147 } 148 obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) 149 err = legacyscheme.Scheme.Convert(obj2, obj3, nil) 150 if err != nil { 151 t.Errorf("%v\nSource: %#v", err, obj2) 152 return nil 153 } 154 return obj3 155} 156