github.com/kubewharf/katalyst-core@v0.5.3/pkg/controller/vpa/util/api_test.go (about) 1 /* 2 Copyright 2022 The Katalyst 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 util 18 19 import ( 20 "context" 21 "testing" 22 "time" 23 24 "github.com/stretchr/testify/assert" 25 core "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 28 apis "github.com/kubewharf/katalyst-api/pkg/apis/autoscaling/v1alpha1" 29 externalfake "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned/fake" 30 "github.com/kubewharf/katalyst-core/pkg/client/control" 31 ) 32 33 func TestUpdateVPAConditions(t *testing.T) { 34 t.Parallel() 35 36 oldvpa1 := &apis.KatalystVerticalPodAutoscaler{ 37 ObjectMeta: metav1.ObjectMeta{ 38 Name: "vpa1", 39 Namespace: "default", 40 }, 41 Status: apis.KatalystVerticalPodAutoscalerStatus{ 42 Conditions: []apis.VerticalPodAutoscalerCondition{ 43 { 44 Type: apis.RecommendationUpdated, 45 Status: core.ConditionTrue, 46 LastTransitionTime: metav1.NewTime(time.Now()), 47 }, 48 }, 49 }, 50 } 51 newvpa1 := &apis.KatalystVerticalPodAutoscaler{ 52 ObjectMeta: metav1.ObjectMeta{ 53 Name: "vpa1", 54 Namespace: "default", 55 }, 56 Status: apis.KatalystVerticalPodAutoscalerStatus{ 57 Conditions: []apis.VerticalPodAutoscalerCondition{ 58 { 59 Type: apis.RecommendationUpdated, 60 Status: core.ConditionTrue, 61 }, 62 }, 63 }, 64 } 65 newvpa2 := &apis.KatalystVerticalPodAutoscaler{ 66 ObjectMeta: metav1.ObjectMeta{ 67 Name: "vpa1", 68 Namespace: "default", 69 }, 70 Status: apis.KatalystVerticalPodAutoscalerStatus{ 71 Conditions: []apis.VerticalPodAutoscalerCondition{ 72 { 73 Type: apis.RecommendationUpdated, 74 Status: core.ConditionFalse, 75 }, 76 }, 77 }, 78 } 79 for _, tc := range []struct { 80 name string 81 oldvpa *apis.KatalystVerticalPodAutoscaler 82 conditionType apis.VerticalPodAutoscalerConditionType 83 conditionStatus core.ConditionStatus 84 updateTime bool 85 newvpa *apis.KatalystVerticalPodAutoscaler 86 }{ 87 { 88 name: "status not change", 89 oldvpa: oldvpa1, 90 conditionType: apis.RecommendationUpdated, 91 conditionStatus: core.ConditionTrue, 92 updateTime: false, 93 newvpa: newvpa1, 94 }, 95 { 96 name: "update time", 97 oldvpa: oldvpa1, 98 conditionType: apis.RecommendationUpdated, 99 conditionStatus: core.ConditionFalse, 100 updateTime: true, 101 newvpa: newvpa2, 102 }, 103 } { 104 tc := tc 105 t.Run(tc.name, func(t *testing.T) { 106 t.Parallel() 107 108 vpa := tc.oldvpa.DeepCopy() 109 err := SetVPAConditions(vpa, tc.conditionType, tc.conditionStatus, "", "") 110 assert.NoError(t, err) 111 tc.newvpa.Status.Conditions[0].LastTransitionTime = tc.oldvpa.Status.Conditions[0].LastTransitionTime 112 if tc.updateTime { 113 assert.NotEqual(t, tc.newvpa.Status.Conditions, vpa.Status.Conditions) 114 tc.newvpa.Status.Conditions[0].LastTransitionTime = vpa.Status.Conditions[0].LastTransitionTime 115 } 116 assert.Equal(t, vpa, tc.newvpa) 117 }) 118 } 119 } 120 121 func TestUpdateAPIVPAConditions(t *testing.T) { 122 t.Parallel() 123 124 oldvpa1 := &apis.KatalystVerticalPodAutoscaler{ 125 ObjectMeta: metav1.ObjectMeta{ 126 Name: "vpa1", 127 Namespace: "default", 128 }, 129 Status: apis.KatalystVerticalPodAutoscalerStatus{ 130 Conditions: []apis.VerticalPodAutoscalerCondition{ 131 { 132 Type: apis.RecommendationUpdated, 133 }, 134 }, 135 }, 136 } 137 newvpa1 := &apis.KatalystVerticalPodAutoscaler{ 138 ObjectMeta: metav1.ObjectMeta{ 139 Name: "vpa1", 140 Namespace: "default", 141 }, 142 Status: apis.KatalystVerticalPodAutoscalerStatus{ 143 Conditions: []apis.VerticalPodAutoscalerCondition{ 144 { 145 Type: apis.RecommendationUpdated, 146 }, 147 }, 148 }, 149 } 150 newvpa11 := &apis.KatalystVerticalPodAutoscaler{ 151 ObjectMeta: metav1.ObjectMeta{ 152 Name: "vpa1", 153 Namespace: "default", 154 }, 155 Status: apis.KatalystVerticalPodAutoscalerStatus{ 156 Conditions: []apis.VerticalPodAutoscalerCondition{ 157 { 158 Type: apis.RecommendationUpdated, 159 Reason: "test", 160 }, 161 }, 162 }, 163 } 164 for _, tc := range []struct { 165 name string 166 oldvpa *apis.KatalystVerticalPodAutoscaler 167 newvpa *apis.KatalystVerticalPodAutoscaler 168 }{ 169 { 170 name: "update different type condition type", 171 oldvpa: oldvpa1, 172 newvpa: newvpa1, 173 }, 174 { 175 name: "update same type condition type", 176 oldvpa: oldvpa1, 177 newvpa: newvpa11, 178 }, 179 } { 180 tc := tc 181 t.Run(tc.name, func(t *testing.T) { 182 t.Parallel() 183 184 InternalClient := externalfake.NewSimpleClientset() 185 vpaUpdater := control.NewRealVPAUpdater(InternalClient) 186 _, err := InternalClient.AutoscalingV1alpha1().KatalystVerticalPodAutoscalers(tc.oldvpa.Namespace).Create(context.TODO(), tc.oldvpa, metav1.CreateOptions{}) 187 assert.NoError(t, err) 188 189 _, err = vpaUpdater.PatchVPAStatus(context.TODO(), tc.oldvpa, tc.newvpa) 190 assert.NoError(t, err) 191 192 vpa, err := InternalClient.AutoscalingV1alpha1().KatalystVerticalPodAutoscalers(tc.newvpa.Namespace).Get(context.TODO(), tc.newvpa.Name, metav1.GetOptions{}) 193 assert.NoError(t, err) 194 assert.Equal(t, tc.newvpa, vpa) 195 }) 196 } 197 } 198 199 func TestUpdateVPARecConditions(t *testing.T) { 200 t.Parallel() 201 202 oldvparec1 := &apis.VerticalPodAutoscalerRecommendation{ 203 ObjectMeta: metav1.ObjectMeta{ 204 Name: "vpa1", 205 Namespace: "default", 206 }, 207 Status: apis.VerticalPodAutoscalerRecommendationStatus{ 208 Conditions: []apis.VerticalPodAutoscalerRecommendationCondition{ 209 { 210 Type: apis.RecommendationUpdatedToVPA, 211 LastTransitionTime: metav1.NewTime(time.Now()), 212 }, 213 }, 214 }, 215 } 216 newvparec1 := &apis.VerticalPodAutoscalerRecommendation{ 217 ObjectMeta: metav1.ObjectMeta{ 218 Name: "vpa1", 219 Namespace: "default", 220 }, 221 Status: apis.VerticalPodAutoscalerRecommendationStatus{ 222 Conditions: []apis.VerticalPodAutoscalerRecommendationCondition{ 223 { 224 Type: apis.RecommendationUpdatedToVPA, 225 }, 226 }, 227 }, 228 } 229 for _, tc := range []struct { 230 name string 231 oldvparec *apis.VerticalPodAutoscalerRecommendation 232 conditionType apis.VerticalPodAutoscalerRecommendationConditionType 233 forceUpdateTime bool 234 newvparec *apis.VerticalPodAutoscalerRecommendation 235 }{ 236 { 237 name: "force update time", 238 oldvparec: oldvparec1.DeepCopy(), 239 conditionType: apis.RecommendationUpdatedToVPA, 240 forceUpdateTime: true, 241 newvparec: newvparec1.DeepCopy(), 242 }, 243 { 244 name: "not force update time", 245 oldvparec: newvparec1.DeepCopy(), 246 conditionType: apis.RecommendationUpdatedToVPA, 247 forceUpdateTime: false, 248 newvparec: newvparec1.DeepCopy(), 249 }, 250 } { 251 tc := tc 252 t.Run(tc.name, func(t *testing.T) { 253 t.Parallel() 254 255 vparec := tc.oldvparec.DeepCopy() 256 err := SetVPARecConditions(vparec, tc.conditionType, "", "", "") 257 assert.NoError(t, err) 258 if tc.forceUpdateTime { 259 assert.NotEqual(t, tc.newvparec.Status.Conditions, vparec.Status.Conditions) 260 tc.newvparec.Status.Conditions[0].LastTransitionTime = vparec.Status.Conditions[0].LastTransitionTime 261 } 262 assert.Equal(t, vparec, tc.newvparec) 263 }) 264 } 265 }