1
16
17 package scale
18
19 import (
20 "encoding/json"
21 "fmt"
22 "testing"
23 "time"
24
25 autoscalingv1 "k8s.io/api/autoscaling/v1"
26 apierrors "k8s.io/apimachinery/pkg/api/errors"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 api "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
29 "k8s.io/apimachinery/pkg/runtime"
30 "k8s.io/apimachinery/pkg/runtime/schema"
31 "k8s.io/apimachinery/pkg/types"
32 "k8s.io/client-go/scale"
33 fakescale "k8s.io/client-go/scale/fake"
34 testcore "k8s.io/client-go/testing"
35 )
36
37 var (
38 rcgvr = schema.GroupVersionResource{
39 Group: "",
40 Version: "v1",
41 Resource: "replicationcontrollers",
42 }
43 rsgvr = schema.GroupVersionResource{
44 Group: "extensions",
45 Version: "v1beta1",
46 Resource: "replicasets",
47 }
48 deploygvr = schema.GroupVersionResource{
49 Group: "apps",
50 Version: "v1",
51 Resource: "deployments",
52 }
53 stsgvr = schema.GroupVersionResource{
54 Group: "apps",
55 Version: "v1",
56 Resource: "statefulsets",
57 }
58 )
59
60 func TestReplicationControllerScaleRetry(t *testing.T) {
61 verbsOnError := map[string]*apierrors.StatusError{
62 "patch": apierrors.NewConflict(api.Resource("Status"), "foo", nil),
63 }
64 scaleClientExpectedAction := []string{"patch", "get"}
65 scaleClient := createFakeScaleClient("replicationcontrollers", "foo-v1", 2, verbsOnError)
66 scaler := NewScaler(scaleClient)
67 count := uint(3)
68 name := "foo-v1"
69 namespace := metav1.NamespaceDefault
70
71 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rcgvr, false)
72 pass, err := scaleFunc()
73 if pass {
74 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
75 }
76 if err != nil {
77 t.Errorf("Did not expect an error on update conflict failure, got %v", err)
78 }
79 preconditions := ScalePrecondition{3, ""}
80 scaleFunc = ScaleCondition(scaler, &preconditions, namespace, name, count, nil, rcgvr, false)
81 _, err = scaleFunc()
82 if err == nil {
83 t.Errorf("Expected error on precondition failure")
84 }
85 actions := scaleClient.Actions()
86 if len(actions) != len(scaleClientExpectedAction) {
87 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
88 }
89 for i, verb := range scaleClientExpectedAction {
90 if actions[i].GetVerb() != verb {
91 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
92 }
93 }
94 }
95
96 func TestReplicationControllerScaleInvalid(t *testing.T) {
97 verbsOnError := map[string]*apierrors.StatusError{
98 "patch": apierrors.NewInvalid(api.Kind("Status"), "foo", nil),
99 }
100 scaleClientExpectedAction := []string{"patch"}
101 scaleClient := createFakeScaleClient("replicationcontrollers", "foo-v1", 1, verbsOnError)
102 scaler := NewScaler(scaleClient)
103 count := uint(3)
104 name := "foo-v1"
105 namespace := "default"
106
107 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rcgvr, false)
108 pass, err := scaleFunc()
109 if pass {
110 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
111 }
112 if err == nil {
113 t.Errorf("Expected error on invalid update failure, got %v", err)
114 }
115 actions := scaleClient.Actions()
116 if len(actions) != len(scaleClientExpectedAction) {
117 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
118 }
119 for i, verb := range scaleClientExpectedAction {
120 if actions[i].GetVerb() != verb {
121 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
122 }
123 }
124 }
125
126 func TestReplicationControllerScale(t *testing.T) {
127 scaleClientExpectedAction := []string{"patch"}
128 scaleClient := createFakeScaleClient("replicationcontrollers", "foo-v1", 2, nil)
129 scaler := NewScaler(scaleClient)
130 count := uint(3)
131 name := "foo-v1"
132 err := scaler.Scale("default", name, count, nil, nil, nil, rcgvr, false)
133
134 if err != nil {
135 t.Fatalf("unexpected error occurred = %v while scaling the resource", err)
136 }
137 actions := scaleClient.Actions()
138 if len(actions) != len(scaleClientExpectedAction) {
139 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
140 }
141 for i, verb := range scaleClientExpectedAction {
142 if actions[i].GetVerb() != verb {
143 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
144 }
145 }
146 }
147
148 func TestReplicationControllerScaleFailsPreconditions(t *testing.T) {
149 scaleClientExpectedAction := []string{"get"}
150 scaleClient := createFakeScaleClient("replicationcontrollers", "foo", 10, nil)
151 scaler := NewScaler(scaleClient)
152 preconditions := ScalePrecondition{2, ""}
153 count := uint(3)
154 name := "foo"
155 err := scaler.Scale("default", name, count, &preconditions, nil, nil, rcgvr, false)
156 if err == nil {
157 t.Fatal("expected to get an error but none was returned")
158 }
159 actions := scaleClient.Actions()
160 if len(actions) != len(scaleClientExpectedAction) {
161 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
162 }
163 for i, verb := range scaleClientExpectedAction {
164 if actions[i].GetVerb() != verb {
165 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
166 }
167 }
168 }
169
170 func TestDeploymentScaleRetry(t *testing.T) {
171 verbsOnError := map[string]*apierrors.StatusError{
172 "patch": apierrors.NewConflict(api.Resource("Status"), "foo", nil),
173 }
174 scaleClientExpectedAction := []string{"patch", "get"}
175 scaleClient := createFakeScaleClient("deployments", "foo", 2, verbsOnError)
176 scaler := NewScaler(scaleClient)
177 count := uint(3)
178 name := "foo"
179 namespace := "default"
180
181 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, deploygvr, false)
182 pass, err := scaleFunc()
183 if pass != false {
184 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
185 }
186 if err != nil {
187 t.Errorf("Did not expect an error on update failure, got %v", err)
188 }
189 preconditions := &ScalePrecondition{3, ""}
190 scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, deploygvr, false)
191 _, err = scaleFunc()
192 if err == nil {
193 t.Error("Expected error on precondition failure")
194 }
195 actions := scaleClient.Actions()
196 if len(actions) != len(scaleClientExpectedAction) {
197 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
198 }
199 for i, verb := range scaleClientExpectedAction {
200 if actions[i].GetVerb() != verb {
201 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
202 }
203 }
204 }
205
206 func TestDeploymentScale(t *testing.T) {
207 scaleClientExpectedAction := []string{"patch"}
208 scaleClient := createFakeScaleClient("deployments", "foo", 2, nil)
209 scaler := NewScaler(scaleClient)
210 count := uint(3)
211 name := "foo"
212 err := scaler.Scale("default", name, count, nil, nil, nil, deploygvr, false)
213 if err != nil {
214 t.Fatal(err)
215 }
216 actions := scaleClient.Actions()
217 if len(actions) != len(scaleClientExpectedAction) {
218 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
219 }
220 for i, verb := range scaleClientExpectedAction {
221 if actions[i].GetVerb() != verb {
222 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
223 }
224 }
225 }
226
227 func TestDeploymentScaleInvalid(t *testing.T) {
228 scaleClientExpectedAction := []string{"patch"}
229 verbsOnError := map[string]*apierrors.StatusError{
230 "patch": apierrors.NewInvalid(api.Kind("Status"), "foo", nil),
231 }
232 scaleClient := createFakeScaleClient("deployments", "foo", 2, verbsOnError)
233 scaler := NewScaler(scaleClient)
234 count := uint(3)
235 name := "foo"
236 namespace := "default"
237
238 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, deploygvr, false)
239 pass, err := scaleFunc()
240 if pass {
241 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
242 }
243 if err == nil {
244 t.Errorf("Expected error on invalid update failure, got %v", err)
245 }
246 actions := scaleClient.Actions()
247 if len(actions) != len(scaleClientExpectedAction) {
248 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
249 }
250 for i, verb := range scaleClientExpectedAction {
251 if actions[i].GetVerb() != verb {
252 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
253 }
254 }
255 }
256
257 func TestDeploymentScaleFailsPreconditions(t *testing.T) {
258 scaleClientExpectedAction := []string{"get"}
259 scaleClient := createFakeScaleClient("deployments", "foo", 10, nil)
260 scaler := NewScaler(scaleClient)
261 preconditions := ScalePrecondition{2, ""}
262 count := uint(3)
263 name := "foo"
264 err := scaler.Scale("default", name, count, &preconditions, nil, nil, deploygvr, false)
265 if err == nil {
266 t.Fatal("exptected to get an error but none was returned")
267 }
268 actions := scaleClient.Actions()
269 if len(actions) != len(scaleClientExpectedAction) {
270 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
271 }
272 for i, verb := range scaleClientExpectedAction {
273 if actions[i].GetVerb() != verb {
274 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
275 }
276 }
277 }
278
279 func TestStatefulSetScale(t *testing.T) {
280 scaleClientExpectedAction := []string{"patch"}
281 scaleClient := createFakeScaleClient("statefulsets", "foo", 2, nil)
282 scaler := NewScaler(scaleClient)
283 count := uint(3)
284 name := "foo"
285 err := scaler.Scale("default", name, count, nil, nil, nil, stsgvr, false)
286 if err != nil {
287 t.Fatal(err)
288 }
289 actions := scaleClient.Actions()
290 if len(actions) != len(scaleClientExpectedAction) {
291 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
292 }
293 for i, verb := range scaleClientExpectedAction {
294 if actions[i].GetVerb() != verb {
295 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
296 }
297 }
298 }
299
300 func TestStatefulSetScaleRetry(t *testing.T) {
301 scaleClientExpectedAction := []string{"patch", "get"}
302 verbsOnError := map[string]*apierrors.StatusError{
303 "patch": apierrors.NewConflict(api.Resource("Status"), "foo", nil),
304 }
305 scaleClient := createFakeScaleClient("statefulsets", "foo", 2, verbsOnError)
306 scaler := NewScaler(scaleClient)
307 count := uint(3)
308 name := "foo"
309 namespace := "default"
310
311 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, stsgvr, false)
312 pass, err := scaleFunc()
313 if pass != false {
314 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
315 }
316 if err != nil {
317 t.Errorf("Did not expect an error on update failure, got %v", err)
318 }
319 preconditions := &ScalePrecondition{3, ""}
320 scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, stsgvr, false)
321 _, err = scaleFunc()
322 if err == nil {
323 t.Error("Expected error on precondition failure")
324 }
325 actions := scaleClient.Actions()
326 if len(actions) != len(scaleClientExpectedAction) {
327 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
328 }
329 for i, verb := range scaleClientExpectedAction {
330 if actions[i].GetVerb() != verb {
331 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
332 }
333 }
334 }
335
336 func TestStatefulSetScaleInvalid(t *testing.T) {
337 scaleClientExpectedAction := []string{"patch"}
338 verbsOnError := map[string]*apierrors.StatusError{
339 "patch": apierrors.NewInvalid(api.Kind("Status"), "foo", nil),
340 }
341 scaleClient := createFakeScaleClient("statefulsets", "foo", 2, verbsOnError)
342 scaler := NewScaler(scaleClient)
343 count := uint(3)
344 name := "foo"
345 namespace := "default"
346
347 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, stsgvr, false)
348 pass, err := scaleFunc()
349 if pass {
350 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
351 }
352 if err == nil {
353 t.Errorf("Expected error on invalid update failure, got %v", err)
354 }
355 actions := scaleClient.Actions()
356 if len(actions) != len(scaleClientExpectedAction) {
357 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
358 }
359 for i, verb := range scaleClientExpectedAction {
360 if actions[i].GetVerb() != verb {
361 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
362 }
363 }
364 }
365
366 func TestStatefulSetScaleFailsPreconditions(t *testing.T) {
367 scaleClientExpectedAction := []string{"get"}
368 scaleClient := createFakeScaleClient("statefulsets", "foo", 10, nil)
369 scaler := NewScaler(scaleClient)
370 preconditions := ScalePrecondition{2, ""}
371 count := uint(3)
372 name := "foo"
373 err := scaler.Scale("default", name, count, &preconditions, nil, nil, stsgvr, false)
374 if err == nil {
375 t.Fatal("expected to get an error but none was returned")
376 }
377 actions := scaleClient.Actions()
378 if len(actions) != len(scaleClientExpectedAction) {
379 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
380 }
381 for i, verb := range scaleClientExpectedAction {
382 if actions[i].GetVerb() != verb {
383 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
384 }
385 }
386 }
387
388 func TestReplicaSetScale(t *testing.T) {
389 scaleClientExpectedAction := []string{"patch"}
390 scaleClient := createFakeScaleClient("replicasets", "foo", 10, nil)
391 scaler := NewScaler(scaleClient)
392 count := uint(3)
393 name := "foo"
394 err := scaler.Scale("default", name, count, nil, nil, nil, rsgvr, false)
395 if err != nil {
396 t.Fatal(err)
397 }
398 actions := scaleClient.Actions()
399 if len(actions) != len(scaleClientExpectedAction) {
400 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
401 }
402 for i, verb := range scaleClientExpectedAction {
403 if actions[i].GetVerb() != verb {
404 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
405 }
406 }
407 }
408
409 func TestReplicaSetScaleRetry(t *testing.T) {
410 verbsOnError := map[string]*apierrors.StatusError{
411 "patch": apierrors.NewConflict(api.Resource("Status"), "foo", nil),
412 }
413 scaleClientExpectedAction := []string{"patch", "get"}
414 scaleClient := createFakeScaleClient("replicasets", "foo", 2, verbsOnError)
415 scaler := NewScaler(scaleClient)
416 count := uint(3)
417 name := "foo"
418 namespace := "default"
419
420 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rsgvr, false)
421 pass, err := scaleFunc()
422 if pass != false {
423 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
424 }
425 if err != nil {
426 t.Errorf("Did not expect an error on update failure, got %v", err)
427 }
428 preconditions := &ScalePrecondition{3, ""}
429 scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, rsgvr, false)
430 _, err = scaleFunc()
431 if err == nil {
432 t.Error("Expected error on precondition failure")
433 }
434 actions := scaleClient.Actions()
435 if len(actions) != len(scaleClientExpectedAction) {
436 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
437 }
438 for i, verb := range scaleClientExpectedAction {
439 if actions[i].GetVerb() != verb {
440 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
441 }
442 }
443 }
444
445 func TestReplicaSetScaleInvalid(t *testing.T) {
446 verbsOnError := map[string]*apierrors.StatusError{
447 "patch": apierrors.NewInvalid(api.Kind("Status"), "foo", nil),
448 }
449 scaleClientExpectedAction := []string{"patch"}
450 scaleClient := createFakeScaleClient("replicasets", "foo", 2, verbsOnError)
451 scaler := NewScaler(scaleClient)
452 count := uint(3)
453 name := "foo"
454 namespace := "default"
455
456 scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rsgvr, false)
457 pass, err := scaleFunc()
458 if pass {
459 t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
460 }
461 if err == nil {
462 t.Errorf("Expected error on invalid update failure, got %v", err)
463 }
464 actions := scaleClient.Actions()
465 if len(actions) != len(scaleClientExpectedAction) {
466 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
467 }
468 for i, verb := range scaleClientExpectedAction {
469 if actions[i].GetVerb() != verb {
470 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
471 }
472 }
473 }
474
475 func TestReplicaSetsGetterFailsPreconditions(t *testing.T) {
476 scaleClientExpectedAction := []string{"get"}
477 scaleClient := createFakeScaleClient("replicasets", "foo", 10, nil)
478 scaler := NewScaler(scaleClient)
479 preconditions := ScalePrecondition{2, ""}
480 count := uint(3)
481 name := "foo"
482 err := scaler.Scale("default", name, count, &preconditions, nil, nil, rsgvr, false)
483 if err == nil {
484 t.Fatal("expected to get an error but non was returned")
485 }
486 actions := scaleClient.Actions()
487 if len(actions) != len(scaleClientExpectedAction) {
488 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
489 }
490 for i, verb := range scaleClientExpectedAction {
491 if actions[i].GetVerb() != verb {
492 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
493 }
494 }
495 }
496
497
498 func TestGenericScaleSimple(t *testing.T) {
499
500 scaleClient := createFakeScaleClient("deployments", "abc", 5, nil)
501
502 scaleClientExpectedAction := []string{"patch", "get", "update", "get", "update", "get", "get", "update", "get"}
503
504
505 scenarios := []struct {
506 name string
507 precondition *ScalePrecondition
508 newSize int
509 targetGVR schema.GroupVersionResource
510 resName string
511 scaleGetter scale.ScalesGetter
512 expectError bool
513 }{
514
515 {
516 name: "scale up the \"abc\" deployment without precondition",
517 precondition: nil,
518 newSize: 10,
519 targetGVR: deploygvr,
520 resName: "abc",
521 scaleGetter: scaleClient,
522 },
523
524 {
525 name: "scale up the \"abc\" deployment",
526 precondition: &ScalePrecondition{10, ""},
527 newSize: 20,
528 targetGVR: deploygvr,
529 resName: "abc",
530 scaleGetter: scaleClient,
531 },
532
533 {
534 name: "scale down the \"abs\" deployment",
535 precondition: &ScalePrecondition{20, ""},
536 newSize: 5,
537 targetGVR: deploygvr,
538 resName: "abc",
539 scaleGetter: scaleClient,
540 },
541
542
543 {
544 name: "precondition error, expected size is 1",
545 precondition: &ScalePrecondition{1, ""},
546 newSize: 5,
547 targetGVR: deploygvr,
548 resName: "abc",
549 scaleGetter: scaleClient,
550 expectError: true,
551 },
552
553 {
554 name: "precondition is not validated when the size is set to -1",
555 precondition: &ScalePrecondition{-1, ""},
556 newSize: 5,
557 targetGVR: deploygvr,
558 resName: "abc",
559 scaleGetter: scaleClient,
560 },
561
562 {
563 name: "precondition error, resource version mismatch",
564 precondition: &ScalePrecondition{5, "v1"},
565 newSize: 5,
566 targetGVR: deploygvr,
567 resName: "abc",
568 scaleGetter: scaleClient,
569 expectError: true,
570 },
571 }
572
573
574 for index, scenario := range scenarios {
575 t.Run(fmt.Sprintf("running scenario %d: %s", index+1, scenario.name), func(t *testing.T) {
576 target := NewScaler(scenario.scaleGetter)
577
578 resVersion, err := target.ScaleSimple("default", scenario.resName, scenario.precondition, uint(scenario.newSize), scenario.targetGVR, false)
579
580 if scenario.expectError && err == nil {
581 t.Fatal("expected an error but was not returned")
582 }
583 if !scenario.expectError && err != nil {
584 t.Fatalf("unexpected error: %v", err)
585 }
586 if resVersion != "" {
587 t.Fatalf("unexpected resource version returned = %s, wanted = %s", resVersion, "")
588 }
589 })
590 }
591
592
593 actions := scaleClient.Actions()
594 if len(actions) != len(scaleClientExpectedAction) {
595 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
596 }
597 for i, verb := range scaleClientExpectedAction {
598 if actions[i].GetVerb() != verb {
599 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
600 }
601 }
602 }
603
604
605 func TestGenericScale(t *testing.T) {
606
607 scaleClient := createFakeScaleClient("deployments", "abc", 5, nil)
608
609 scaleClientExpectedAction := []string{"patch", "get", "update", "get", "get"}
610
611
612 scenarios := []struct {
613 name string
614 precondition *ScalePrecondition
615 newSize int
616 targetGVR schema.GroupVersionResource
617 resName string
618 scaleGetter scale.ScalesGetter
619 waitForReplicas *RetryParams
620 expectError bool
621 }{
622
623 {
624 name: "scale up the \"abc\" deployment without precondition",
625 precondition: nil,
626 newSize: 10,
627 targetGVR: deploygvr,
628 resName: "abc",
629 scaleGetter: scaleClient,
630 },
631
632 {
633 name: "scale up the \"abc\" deployment",
634 precondition: &ScalePrecondition{10, ""},
635 newSize: 20,
636 targetGVR: deploygvr,
637 resName: "abc",
638 scaleGetter: scaleClient,
639 },
640
641 {
642 name: "a resource name cannot be empty",
643 precondition: &ScalePrecondition{10, ""},
644 newSize: 20,
645 targetGVR: deploygvr,
646 resName: "",
647 scaleGetter: scaleClient,
648 expectError: true,
649 },
650
651 {
652 name: "wait for replicas error due to status.Replicas != spec.Replicas",
653 precondition: &ScalePrecondition{10, ""},
654 newSize: 20,
655 targetGVR: deploygvr,
656 resName: "abc",
657 scaleGetter: scaleClient,
658 waitForReplicas: &RetryParams{time.Duration(5 * time.Second), time.Duration(5 * time.Second)},
659 expectError: true,
660 },
661 }
662
663
664 for _, scenario := range scenarios {
665 t.Run(scenario.name, func(t *testing.T) {
666 target := NewScaler(scenario.scaleGetter)
667
668 err := target.Scale("default", scenario.resName, uint(scenario.newSize), scenario.precondition, nil, scenario.waitForReplicas, scenario.targetGVR, false)
669
670 if scenario.expectError && err == nil {
671 t.Fatal("expected an error but was not returned")
672 }
673 if !scenario.expectError && err != nil {
674 t.Fatalf("unexpected error: %v", err)
675 }
676 })
677 }
678
679
680 actions := scaleClient.Actions()
681 if len(actions) != len(scaleClientExpectedAction) {
682 t.Errorf("unexpected actions: %v, expected %d actions got %d", actions, len(scaleClientExpectedAction), len(actions))
683 }
684 for i, verb := range scaleClientExpectedAction {
685 if actions[i].GetVerb() != verb {
686 t.Errorf("unexpected action: %+v, expected %s", actions[i].GetVerb(), verb)
687 }
688 }
689 }
690
691 func createFakeScaleClient(resource string, resourceName string, replicas int, errorsOnVerb map[string]*apierrors.StatusError) *fakescale.FakeScaleClient {
692 shouldReturnAnError := func(verb string) (*apierrors.StatusError, bool) {
693 if anError, anErrorExists := errorsOnVerb[verb]; anErrorExists {
694 return anError, true
695 }
696 return &apierrors.StatusError{}, false
697 }
698 newReplicas := int32(replicas)
699 scaleClient := &fakescale.FakeScaleClient{}
700 scaleClient.AddReactor("get", resource, func(rawAction testcore.Action) (handled bool, ret runtime.Object, err error) {
701 action := rawAction.(testcore.GetAction)
702 if action.GetName() != resourceName {
703 return true, nil, fmt.Errorf("expected = %s, got = %s", resourceName, action.GetName())
704 }
705 if anError, should := shouldReturnAnError("get"); should {
706 return true, nil, anError
707 }
708 obj := &autoscalingv1.Scale{
709 ObjectMeta: metav1.ObjectMeta{
710 Name: action.GetName(),
711 Namespace: action.GetNamespace(),
712 },
713 Spec: autoscalingv1.ScaleSpec{
714 Replicas: newReplicas,
715 },
716 }
717 return true, obj, nil
718 })
719
720 scaleClient.AddReactor("update", resource, func(rawAction testcore.Action) (handled bool, ret runtime.Object, err error) {
721 action := rawAction.(testcore.UpdateAction)
722 obj := action.GetObject().(*autoscalingv1.Scale)
723 if obj.Name != resourceName {
724 return true, nil, fmt.Errorf("expected = %s, got = %s", resourceName, obj.Name)
725 }
726 if anError, should := shouldReturnAnError("update"); should {
727 return true, nil, anError
728 }
729 newReplicas = obj.Spec.Replicas
730 return true, &autoscalingv1.Scale{
731 ObjectMeta: metav1.ObjectMeta{
732 Name: obj.Name,
733 Namespace: action.GetNamespace(),
734 },
735 Spec: autoscalingv1.ScaleSpec{
736 Replicas: newReplicas,
737 },
738 }, nil
739 })
740
741 scaleClient.AddReactor("patch", resource, func(rawAction testcore.Action) (handled bool, ret runtime.Object, err error) {
742 action := rawAction.(testcore.PatchAction)
743 pt := action.GetPatchType()
744 if pt != types.MergePatchType {
745 return true, nil, fmt.Errorf("unexpected patch type: expected = %s, got = %s", types.MergePatchType, pt)
746 }
747 var scale autoscalingv1.Scale
748 err = json.Unmarshal(action.GetPatch(), &scale)
749 if err != nil {
750 return true, nil, fmt.Errorf("invalid patch: %s", err)
751 }
752 name := action.GetName()
753 if name != resourceName {
754 return true, nil, fmt.Errorf("expected = %s, got = %s", resourceName, name)
755 }
756 if anError, should := shouldReturnAnError("patch"); should {
757 return true, nil, anError
758 }
759 newReplicas = scale.Spec.Replicas
760 return true, &autoscalingv1.Scale{
761 ObjectMeta: metav1.ObjectMeta{
762 Name: name,
763 Namespace: action.GetNamespace(),
764 },
765 Spec: autoscalingv1.ScaleSpec{
766 Replicas: newReplicas,
767 },
768 }, nil
769 })
770 return scaleClient
771 }
772
View as plain text