1
16
17 package deployment
18
19 import (
20 "context"
21 "fmt"
22 "strings"
23 "testing"
24
25 apps "k8s.io/api/apps/v1"
26 v1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/util/intstr"
29 "k8s.io/apimachinery/pkg/util/uuid"
30 "k8s.io/apimachinery/pkg/util/wait"
31 "k8s.io/client-go/util/retry"
32 "k8s.io/klog/v2/ktesting"
33 deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
34 "k8s.io/kubernetes/test/integration/framework"
35 testutil "k8s.io/kubernetes/test/utils"
36 "k8s.io/utils/ptr"
37 )
38
39 func TestNewDeployment(t *testing.T) {
40 _, ctx := ktesting.NewTestContext(t)
41 ctx, cancel := context.WithCancel(ctx)
42 defer cancel()
43
44 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
45 defer closeFn()
46 name := "test-new-deployment"
47
48 ns := framework.CreateNamespaceOrDie(c, name, t)
49 defer framework.DeleteNamespaceOrDie(c, ns, t)
50
51 replicas := int32(20)
52 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
53 tester.deployment.Spec.MinReadySeconds = 4
54
55 tester.deployment.Annotations = map[string]string{"test": "should-copy-to-replica-set", v1.LastAppliedConfigAnnotation: "should-not-copy-to-replica-set"}
56 var err error
57 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
58 if err != nil {
59 t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
60 }
61
62
63 stopControllers := runControllersAndInformers(t, rm, dc, informers)
64 defer stopControllers()
65
66
67 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
68 t.Fatal(err)
69 }
70
71
72
73 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
74 t.Fatal(err)
75 }
76
77
78 newRS, err := tester.expectNewReplicaSet()
79 if err != nil {
80 t.Fatal(err)
81 }
82 if newRS.Annotations["test"] != "should-copy-to-replica-set" {
83 t.Errorf("expected new ReplicaSet annotations copied from Deployment %s, got: %v", tester.deployment.Name, newRS.Annotations)
84 }
85 if newRS.Annotations[v1.LastAppliedConfigAnnotation] != "" {
86 t.Errorf("expected new ReplicaSet last-applied annotation not copied from Deployment %s", tester.deployment.Name)
87 }
88
89
90 rsHash, err := checkRSHashLabels(newRS)
91 if err != nil {
92 t.Error(err)
93 }
94
95
96 selector, err := metav1.LabelSelectorAsSelector(tester.deployment.Spec.Selector)
97 if err != nil {
98 t.Fatalf("failed to parse deployment %s selector: %v", name, err)
99 }
100 pods, err := c.CoreV1().Pods(ns.Name).List(context.TODO(), metav1.ListOptions{LabelSelector: selector.String()})
101 if err != nil {
102 t.Fatalf("failed to list pods of deployment %s: %v", name, err)
103 }
104 if len(pods.Items) != int(replicas) {
105 t.Errorf("expected %d pods, got %d pods", replicas, len(pods.Items))
106 }
107 podHash, err := checkPodsHashLabel(pods)
108 if err != nil {
109 t.Error(err)
110 }
111 if rsHash != podHash {
112 t.Errorf("found mismatching pod-template-hash value: rs hash = %s whereas pod hash = %s", rsHash, podHash)
113 }
114 }
115
116
117
118
119 func TestDeploymentRollingUpdate(t *testing.T) {
120 _, ctx := ktesting.NewTestContext(t)
121 ctx, cancel := context.WithCancel(ctx)
122 defer cancel()
123
124 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
125 defer closeFn()
126
127 name := "test-rolling-update-deployment"
128 ns := framework.CreateNamespaceOrDie(c, name, t)
129 defer framework.DeleteNamespaceOrDie(c, ns, t)
130
131
132 stopControllers := runControllersAndInformers(t, rm, dc, informers)
133 defer stopControllers()
134
135 replicas := int32(20)
136 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
137 tester.deployment.Spec.MinReadySeconds = 4
138 quarter := intstr.FromString("25%")
139 tester.deployment.Spec.Strategy.RollingUpdate = &apps.RollingUpdateDeployment{
140 MaxUnavailable: &quarter,
141 MaxSurge: &quarter,
142 }
143
144
145 var err error
146 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
147 if err != nil {
148 t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
149 }
150 oriImage := tester.deployment.Spec.Template.Spec.Containers[0].Image
151 if err := tester.waitForDeploymentRevisionAndImage("1", oriImage); err != nil {
152 t.Fatal(err)
153 }
154 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
155 t.Fatal(err)
156 }
157
158
159 image := "new-image"
160 if oriImage == image {
161 t.Fatalf("bad test setup, deployment %s roll out with the same image", tester.deployment.Name)
162 }
163 imageFn := func(update *apps.Deployment) {
164 update.Spec.Template.Spec.Containers[0].Image = image
165 }
166 tester.deployment, err = tester.updateDeployment(imageFn)
167 if err != nil {
168 t.Fatalf("failed to update deployment %s: %v", tester.deployment.Name, err)
169 }
170 if err := tester.waitForDeploymentRevisionAndImage("2", image); err != nil {
171 t.Fatal(err)
172 }
173 if err := tester.waitForDeploymentCompleteAndCheckRollingAndMarkPodsReady(); err != nil {
174 t.Fatal(err)
175 }
176
177
178 image = "dont-finish"
179 imageFn = func(update *apps.Deployment) {
180 update.Spec.Template.Spec.Containers[0].Image = image
181 }
182 tester.deployment, err = tester.updateDeployment(imageFn)
183 if err != nil {
184 t.Fatalf("failed to update deployment %s: %v", tester.deployment.Name, err)
185 }
186 if err := tester.waitForDeploymentRevisionAndImage("3", image); err != nil {
187 t.Fatal(err)
188 }
189
190
191
192 image = "rollover"
193 imageFn = func(update *apps.Deployment) {
194 update.Spec.Template.Spec.Containers[0].Image = image
195 }
196 tester.deployment, err = tester.updateDeployment(imageFn)
197 if err != nil {
198 t.Fatalf("failed to update deployment %s: %v", tester.deployment.Name, err)
199 }
200 if err := tester.waitForDeploymentRevisionAndImage("4", image); err != nil {
201 t.Fatal(err)
202 }
203 if err := tester.waitForDeploymentCompleteAndCheckRollingAndMarkPodsReady(); err != nil {
204 t.Fatal(err)
205 }
206 _, allOldRSs, err := testutil.GetOldReplicaSets(tester.deployment, c)
207 if err != nil {
208 t.Fatalf("failed retrieving old replicasets of deployment %s: %v", tester.deployment.Name, err)
209 }
210 for _, oldRS := range allOldRSs {
211 if *oldRS.Spec.Replicas != 0 {
212 t.Errorf("expected old replicaset %s of deployment %s to have 0 replica, got %d", oldRS.Name, tester.deployment.Name, *oldRS.Spec.Replicas)
213 }
214 }
215 }
216
217
218 func TestDeploymentSelectorImmutability(t *testing.T) {
219 closeFn, c := dcSimpleSetup(t)
220 defer closeFn()
221
222 name := "test-deployment-selector-immutability"
223 ns := framework.CreateNamespaceOrDie(c, name, t)
224 defer framework.DeleteNamespaceOrDie(c, ns, t)
225
226 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, int32(20))}
227 var err error
228 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
229 if err != nil {
230 t.Fatalf("failed to create apps/v1 deployment %s: %v", tester.deployment.Name, err)
231 }
232
233
234 deploymentAppsV1, err := c.AppsV1().Deployments(ns.Name).Get(context.TODO(), name, metav1.GetOptions{})
235 if err != nil {
236 t.Fatalf("failed to get apps/v1 deployment %s: %v", name, err)
237 }
238 newSelectorLabels := map[string]string{"name_apps_v1": "test_apps_v1"}
239 deploymentAppsV1.Spec.Selector.MatchLabels = newSelectorLabels
240 deploymentAppsV1.Spec.Template.Labels = newSelectorLabels
241 _, err = c.AppsV1().Deployments(ns.Name).Update(context.TODO(), deploymentAppsV1, metav1.UpdateOptions{})
242 if err == nil {
243 t.Fatalf("failed to provide validation error when changing immutable selector when updating apps/v1 deployment %s", deploymentAppsV1.Name)
244 }
245 expectedErrType := "Invalid value"
246 expectedErrDetail := "field is immutable"
247 if !strings.Contains(err.Error(), expectedErrType) || !strings.Contains(err.Error(), expectedErrDetail) {
248 t.Errorf("error message does not match, expected type: %s, expected detail: %s, got: %s", expectedErrType, expectedErrDetail, err.Error())
249 }
250 }
251
252
253 func TestPausedDeployment(t *testing.T) {
254 _, ctx := ktesting.NewTestContext(t)
255 ctx, cancel := context.WithCancel(ctx)
256 defer cancel()
257
258 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
259 defer closeFn()
260
261 name := "test-paused-deployment"
262 ns := framework.CreateNamespaceOrDie(c, name, t)
263 defer framework.DeleteNamespaceOrDie(c, ns, t)
264
265 replicas := int32(1)
266 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
267 tester.deployment.Spec.Paused = true
268 tgps := int64(1)
269 tester.deployment.Spec.Template.Spec.TerminationGracePeriodSeconds = &tgps
270
271 var err error
272 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
273 if err != nil {
274 t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
275 }
276
277
278 stopControllers := runControllersAndInformers(t, rm, dc, informers)
279 defer stopControllers()
280
281
282 if err := tester.expectNoNewReplicaSet(); err != nil {
283 t.Fatal(err)
284 }
285
286
287 tester.deployment, err = tester.updateDeployment(resumeFn)
288 if err != nil {
289 t.Fatalf("failed to resume deployment %s: %v", tester.deployment.Name, err)
290 }
291
292
293 if err := tester.waitForObservedDeployment(tester.deployment.Generation); err != nil {
294 t.Fatal(err)
295 }
296
297
298 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
299 t.Fatal(err)
300 }
301
302
303
304 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
305 t.Fatal(err)
306 }
307
308
309 if _, err := tester.expectNewReplicaSet(); err != nil {
310 t.Fatal(err)
311 }
312
313
314
315 tester.deployment, err = tester.updateDeployment(pauseFn)
316 if err != nil {
317 t.Fatalf("failed to pause deployment %s: %v", tester.deployment.Name, err)
318 }
319
320
321 if err := tester.waitForObservedDeployment(tester.deployment.Generation); err != nil {
322 t.Fatal(err)
323 }
324
325
326 newTGPS := int64(0)
327 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
328 update.Spec.Template.Spec.TerminationGracePeriodSeconds = &newTGPS
329 })
330 if err != nil {
331 t.Fatalf("failed updating template of deployment %s: %v", tester.deployment.Name, err)
332 }
333
334
335 if err := tester.waitForObservedDeployment(tester.deployment.Generation); err != nil {
336 t.Fatal(err)
337 }
338
339
340 if err := tester.expectNoNewReplicaSet(); err != nil {
341 t.Fatal(err)
342 }
343
344 _, allOldRs, err := testutil.GetOldReplicaSets(tester.deployment, c)
345 if err != nil {
346 t.Fatalf("failed retrieving old replicasets of deployment %s: %v", tester.deployment.Name, err)
347 }
348 if len(allOldRs) != 1 {
349 t.Errorf("expected an old replica set, got %v", allOldRs)
350 }
351 if *allOldRs[0].Spec.Template.Spec.TerminationGracePeriodSeconds == newTGPS {
352 t.Errorf("TerminationGracePeriodSeconds on the replica set should be %d, got %d", tgps, newTGPS)
353 }
354 }
355
356
357 func TestScalePausedDeployment(t *testing.T) {
358 _, ctx := ktesting.NewTestContext(t)
359 ctx, cancel := context.WithCancel(ctx)
360 defer cancel()
361
362 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
363 defer closeFn()
364
365 name := "test-scale-paused-deployment"
366 ns := framework.CreateNamespaceOrDie(c, name, t)
367 defer framework.DeleteNamespaceOrDie(c, ns, t)
368
369 replicas := int32(1)
370 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
371 tgps := int64(1)
372 tester.deployment.Spec.Template.Spec.TerminationGracePeriodSeconds = &tgps
373
374 var err error
375 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
376 if err != nil {
377 t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
378 }
379
380
381 stopControllers := runControllersAndInformers(t, rm, dc, informers)
382 defer stopControllers()
383
384
385 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
386 t.Fatal(err)
387 }
388
389
390
391 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
392 t.Fatal(err)
393 }
394
395
396 if _, err := tester.expectNewReplicaSet(); err != nil {
397 t.Fatal(err)
398 }
399
400
401 tester.deployment, err = tester.updateDeployment(pauseFn)
402 if err != nil {
403 t.Fatalf("failed to pause deployment %s: %v", tester.deployment.Name, err)
404 }
405
406
407 if err := tester.waitForObservedDeployment(tester.deployment.Generation); err != nil {
408 t.Fatal(err)
409 }
410
411
412 newReplicas := int32(10)
413 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
414 update.Spec.Replicas = &newReplicas
415 })
416 if err != nil {
417 t.Fatalf("failed updating deployment %s: %v", tester.deployment.Name, err)
418 }
419
420
421 if err := tester.waitForObservedDeployment(tester.deployment.Generation); err != nil {
422 t.Fatal(err)
423 }
424
425
426 rs, err := tester.expectNewReplicaSet()
427 if err != nil {
428 t.Fatal(err)
429 }
430 if *rs.Spec.Replicas != newReplicas {
431 t.Errorf("expected new replicaset replicas = %d, got %d", newReplicas, *rs.Spec.Replicas)
432 }
433
434
435
436 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
437 t.Fatal(err)
438 }
439 }
440
441
442 func TestDeploymentHashCollision(t *testing.T) {
443 _, ctx := ktesting.NewTestContext(t)
444 ctx, cancel := context.WithCancel(ctx)
445 defer cancel()
446
447 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
448 defer closeFn()
449
450 name := "test-hash-collision-deployment"
451 ns := framework.CreateNamespaceOrDie(c, name, t)
452 defer framework.DeleteNamespaceOrDie(c, ns, t)
453
454 replicas := int32(1)
455 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
456
457 var err error
458 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
459 if err != nil {
460 t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
461 }
462
463
464 stopControllers := runControllersAndInformers(t, rm, dc, informers)
465 defer stopControllers()
466
467
468 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
469 t.Fatal(err)
470 }
471
472
473 newRS, err := testutil.GetNewReplicaSet(tester.deployment, c)
474 if err != nil {
475 t.Fatalf("failed getting new replicaset of deployment %s: %v", tester.deployment.Name, err)
476 }
477 if newRS == nil {
478 t.Fatalf("unable to find new replicaset of deployment %s", tester.deployment.Name)
479 }
480 _, err = tester.updateReplicaSet(newRS.Name, func(update *apps.ReplicaSet) {
481 *update.Spec.Template.Spec.TerminationGracePeriodSeconds = int64(5)
482 })
483 if err != nil {
484 t.Fatalf("failed updating replicaset %s template: %v", newRS.Name, err)
485 }
486
487
488 if err := wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
489 d, err := c.AppsV1().Deployments(ns.Name).Get(context.TODO(), tester.deployment.Name, metav1.GetOptions{})
490 if err != nil {
491 return false, nil
492 }
493 return d.Status.CollisionCount != nil && *d.Status.CollisionCount == int32(1), nil
494 }); err != nil {
495 t.Fatalf("Failed to increment collision counter for deployment %q: %v", tester.deployment.Name, err)
496 }
497
498
499 if err := tester.waitForDeploymentRevisionAndImage("2", fakeImage); err != nil {
500 t.Fatal(err)
501 }
502 }
503
504 func checkRSHashLabels(rs *apps.ReplicaSet) (string, error) {
505 hash := rs.Labels[apps.DefaultDeploymentUniqueLabelKey]
506 selectorHash := rs.Spec.Selector.MatchLabels[apps.DefaultDeploymentUniqueLabelKey]
507 templateLabelHash := rs.Spec.Template.Labels[apps.DefaultDeploymentUniqueLabelKey]
508
509 if hash != selectorHash || selectorHash != templateLabelHash {
510 return "", fmt.Errorf("mismatching hash value found in replicaset %s: %#v", rs.Name, rs)
511 }
512 if len(hash) == 0 {
513 return "", fmt.Errorf("unexpected replicaset %s missing required pod-template-hash labels", rs.Name)
514 }
515
516 if !strings.HasSuffix(rs.Name, hash) {
517 return "", fmt.Errorf("unexpected replicaset %s name suffix doesn't match hash %s", rs.Name, hash)
518 }
519
520 return hash, nil
521 }
522
523 func checkPodsHashLabel(pods *v1.PodList) (string, error) {
524 if len(pods.Items) == 0 {
525 return "", fmt.Errorf("no pods given")
526 }
527 var hash string
528 for _, pod := range pods.Items {
529 podHash := pod.Labels[apps.DefaultDeploymentUniqueLabelKey]
530 if len(podHash) == 0 {
531 return "", fmt.Errorf("found pod %s missing pod-template-hash label: %#v", pod.Name, pods)
532 }
533
534 if len(hash) == 0 {
535 hash = podHash
536 }
537 if podHash != hash {
538 return "", fmt.Errorf("found pod %s with mismatching pod-template-hash value %s: %#v", pod.Name, podHash, pods)
539 }
540 }
541 return hash, nil
542 }
543
544
545 func TestFailedDeployment(t *testing.T) {
546 _, ctx := ktesting.NewTestContext(t)
547 ctx, cancel := context.WithCancel(ctx)
548 defer cancel()
549
550 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
551 defer closeFn()
552
553 name := "test-failed-deployment"
554 ns := framework.CreateNamespaceOrDie(c, name, t)
555 defer framework.DeleteNamespaceOrDie(c, ns, t)
556
557 deploymentName := "progress-check"
558 replicas := int32(1)
559 three := int32(3)
560 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(deploymentName, ns.Name, replicas)}
561 tester.deployment.Spec.ProgressDeadlineSeconds = &three
562 var err error
563 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
564 if err != nil {
565 t.Fatalf("failed to create deployment %q: %v", deploymentName, err)
566 }
567
568
569 stopControllers := runControllersAndInformers(t, rm, dc, informers)
570 defer stopControllers()
571
572 if err = tester.waitForDeploymentUpdatedReplicasGTE(replicas); err != nil {
573 t.Fatal(err)
574 }
575
576
577
578 if err = tester.waitForDeploymentWithCondition(deploymentutil.TimedOutReason, apps.DeploymentProgressing); err != nil {
579 t.Fatal(err)
580 }
581
582
583 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
584 t.Fatalf("deployment %q fails to have its status becoming valid: %v", deploymentName, err)
585 }
586
587
588 if err = tester.waitForDeploymentWithCondition(deploymentutil.NewRSAvailableReason, apps.DeploymentProgressing); err != nil {
589 t.Fatal(err)
590 }
591 }
592
593 func TestOverlappingDeployments(t *testing.T) {
594 _, ctx := ktesting.NewTestContext(t)
595 ctx, cancel := context.WithCancel(ctx)
596 defer cancel()
597
598 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
599 defer closeFn()
600
601 name := "test-overlapping-deployments"
602 ns := framework.CreateNamespaceOrDie(c, name, t)
603 defer framework.DeleteNamespaceOrDie(c, ns, t)
604
605 replicas := int32(1)
606 firstDeploymentName := "first-deployment"
607 secondDeploymentName := "second-deployment"
608 testers := []*deploymentTester{
609 {t: t, c: c, deployment: newDeployment(firstDeploymentName, ns.Name, replicas)},
610 {t: t, c: c, deployment: newDeployment(secondDeploymentName, ns.Name, replicas)},
611 }
612
613
614 stopControllers := runControllersAndInformers(t, rm, dc, informers)
615 defer stopControllers()
616
617
618 var err error
619 var rss []*apps.ReplicaSet
620 for _, tester := range testers {
621 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
622 dname := tester.deployment.Name
623 if err != nil {
624 t.Fatalf("failed to create deployment %q: %v", dname, err)
625 }
626
627 if err = tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
628 t.Fatalf("failed to update deployment %q to revision 1: %v", dname, err)
629 }
630
631 if err = tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
632 t.Fatalf("deployment %q failed to complete: %v", dname, err)
633 }
634
635 newRS, err := tester.getNewReplicaSet()
636 if err != nil {
637 t.Fatalf("failed to get new replicaset of deployment %q: %v", dname, err)
638 }
639 if newRS == nil {
640 t.Fatalf("unable to find new replicaset of deployment %q", dname)
641 }
642
643 rss = append(rss, newRS)
644 }
645
646
647 if rss[0].UID == rss[1].UID {
648 t.Fatalf("overlapping deployments should not share the same replicaset")
649 }
650
651
652 newReplicas := replicas + 1
653 testers[0].deployment, err = testers[0].updateDeployment(func(update *apps.Deployment) {
654 update.Spec.Replicas = &newReplicas
655 })
656 if err != nil {
657 t.Fatalf("failed updating deployment %q: %v", firstDeploymentName, err)
658 }
659
660
661 if err := testers[0].waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
662 t.Fatalf("deployment %q failed to complete after scaling: %v", firstDeploymentName, err)
663 }
664
665
666 for i, tester := range testers {
667 rs, err := c.AppsV1().ReplicaSets(ns.Name).Get(context.TODO(), rss[i].Name, metav1.GetOptions{})
668 if err != nil {
669 t.Fatalf("failed to get replicaset %q: %v", rss[i].Name, err)
670 }
671 if *rs.Spec.Replicas != *tester.deployment.Spec.Replicas {
672 t.Errorf("expected replicaset %q of deployment %q has %d replicas, but found %d replicas", rs.Name, firstDeploymentName, *tester.deployment.Spec.Replicas, *rs.Spec.Replicas)
673 }
674 }
675 }
676
677
678 func TestScaledRolloutDeployment(t *testing.T) {
679 logger, ctx := ktesting.NewTestContext(t)
680 ctx, cancel := context.WithCancel(ctx)
681 defer cancel()
682
683 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
684 defer closeFn()
685
686 name := "test-scaled-rollout-deployment"
687 ns := framework.CreateNamespaceOrDie(c, name, t)
688 defer framework.DeleteNamespaceOrDie(c, ns, t)
689
690
691 stopControllers := runControllersAndInformers(t, rm, dc, informers)
692 defer stopControllers()
693
694
695 var err error
696 replicas := int32(10)
697 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
698 tester.deployment.Spec.Strategy.RollingUpdate.MaxSurge = ptr.To(intstr.FromInt32(3))
699 tester.deployment.Spec.Strategy.RollingUpdate.MaxUnavailable = ptr.To(intstr.FromInt32(2))
700 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
701 if err != nil {
702 t.Fatalf("failed to create deployment %q: %v", name, err)
703 }
704 if err = tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
705 t.Fatal(err)
706 }
707 if err = tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
708 t.Fatalf("deployment %q failed to complete: %v", name, err)
709 }
710
711
712 firstRS, err := tester.expectNewReplicaSet()
713 if err != nil {
714 t.Fatal(err)
715 }
716
717
718 fakeImage2 := "fakeimage2"
719 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
720 update.Spec.Template.Spec.Containers[0].Image = fakeImage2
721 })
722 if err != nil {
723 t.Fatalf("failed updating deployment %q: %v", name, err)
724 }
725 if err = tester.waitForDeploymentRevisionAndImage("2", fakeImage2); err != nil {
726 t.Fatal(err)
727 }
728
729
730 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Get(context.TODO(), name, metav1.GetOptions{})
731 if err != nil {
732 t.Fatalf("failed to get deployment %q: %v", name, err)
733 }
734 minAvailableReplicas := deploymentutil.MinAvailable(tester.deployment)
735 if tester.deployment.Status.AvailableReplicas < minAvailableReplicas {
736 t.Fatalf("deployment %q does not have minimum number of available replicas after 2nd rollout", name)
737 }
738
739
740 firstRS, err = c.AppsV1().ReplicaSets(ns.Name).Get(context.TODO(), firstRS.Name, metav1.GetOptions{})
741 if err != nil {
742 t.Fatalf("failed to get replicaset %q: %v", firstRS.Name, err)
743 }
744 if err = tester.waitRSStable(firstRS); err != nil {
745 t.Fatal(err)
746 }
747
748
749 secondRS, err := tester.expectNewReplicaSet()
750 if err != nil {
751 t.Fatal(err)
752 }
753 if err = tester.waitRSStable(secondRS); err != nil {
754 t.Fatal(err)
755 }
756
757
758 newReplicas := int32(20)
759 fakeImage3 := "fakeimage3"
760 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
761 update.Spec.Replicas = &newReplicas
762 update.Spec.Template.Spec.Containers[0].Image = fakeImage3
763 })
764 if err != nil {
765 t.Fatalf("failed updating deployment %q: %v", name, err)
766 }
767 if err = tester.waitForDeploymentRevisionAndImage("3", fakeImage3); err != nil {
768 t.Fatal(err)
769 }
770 if err = tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
771 t.Fatalf("deployment %q failed to complete: %v", name, err)
772 }
773
774
775 thirdRS, err := testutil.GetNewReplicaSet(tester.deployment, c)
776 if err != nil {
777 t.Fatalf("failed getting new revision 3 replicaset for deployment %q: %v", name, err)
778 }
779 rss := []*apps.ReplicaSet{firstRS, secondRS, thirdRS}
780 for _, curRS := range rss {
781 curRS, err = c.AppsV1().ReplicaSets(ns.Name).Get(context.TODO(), curRS.Name, metav1.GetOptions{})
782 if err != nil {
783 t.Fatalf("failed to get replicaset when checking desired replicas annotation: %v", err)
784 }
785 desired, ok := deploymentutil.GetDesiredReplicasAnnotation(logger, curRS)
786 if !ok {
787 t.Fatalf("failed to retrieve desiredReplicas annotation for replicaset %q", curRS.Name)
788 }
789 if desired != *(tester.deployment.Spec.Replicas) {
790 t.Fatalf("unexpected desiredReplicas annotation for replicaset %q: expected %d, got %d", curRS.Name, *(tester.deployment.Spec.Replicas), desired)
791 }
792 }
793
794
795 fakeImage4 := "fakeimage4"
796 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
797 update.Spec.Template.Spec.Containers[0].Image = fakeImage4
798 })
799 if err != nil {
800 t.Fatalf("failed updating deployment %q: %v", name, err)
801 }
802 if err = tester.waitForDeploymentRevisionAndImage("4", fakeImage4); err != nil {
803 t.Fatal(err)
804 }
805
806
807 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Get(context.TODO(), name, metav1.GetOptions{})
808 if err != nil {
809 t.Fatalf("failed to get deployment %q: %v", name, err)
810 }
811 minAvailableReplicas = deploymentutil.MinAvailable(tester.deployment)
812 if tester.deployment.Status.AvailableReplicas < minAvailableReplicas {
813 t.Fatalf("deployment %q does not have minimum number of available replicas after 4th rollout", name)
814 }
815
816
817 thirdRS, err = c.AppsV1().ReplicaSets(ns.Name).Get(context.TODO(), thirdRS.Name, metav1.GetOptions{})
818 if err != nil {
819 t.Fatalf("failed to get replicaset %q: %v", thirdRS.Name, err)
820 }
821 if err = tester.waitRSStable(thirdRS); err != nil {
822 t.Fatal(err)
823 }
824
825
826 fourthRS, err := tester.expectNewReplicaSet()
827 if err != nil {
828 t.Fatal(err)
829 }
830 if err = tester.waitRSStable(fourthRS); err != nil {
831 t.Fatal(err)
832 }
833
834
835 newReplicas = int32(5)
836 fakeImage5 := "fakeimage5"
837 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
838 update.Spec.Replicas = &newReplicas
839 update.Spec.Template.Spec.Containers[0].Image = fakeImage5
840 })
841 if err != nil {
842 t.Fatalf("failed updating deployment %q: %v", name, err)
843 }
844 if err = tester.waitForDeploymentRevisionAndImage("5", fakeImage5); err != nil {
845 t.Fatal(err)
846 }
847 if err = tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
848 t.Fatalf("deployment %q failed to complete: %v", name, err)
849 }
850
851
852 fifthRS, err := testutil.GetNewReplicaSet(tester.deployment, c)
853 if err != nil {
854 t.Fatalf("failed getting new revision 5 replicaset for deployment %q: %v", name, err)
855 }
856 rss = []*apps.ReplicaSet{thirdRS, fourthRS, fifthRS}
857 for _, curRS := range rss {
858 curRS, err = c.AppsV1().ReplicaSets(ns.Name).Get(context.TODO(), curRS.Name, metav1.GetOptions{})
859 if err != nil {
860 t.Fatalf("failed to get replicaset when checking desired replicas annotation: %v", err)
861 }
862 desired, ok := deploymentutil.GetDesiredReplicasAnnotation(logger, curRS)
863 if !ok {
864 t.Fatalf("failed to retrieve desiredReplicas annotation for replicaset %q", curRS.Name)
865 }
866 if desired != *(tester.deployment.Spec.Replicas) {
867 t.Fatalf("unexpected desiredReplicas annotation for replicaset %q: expected %d, got %d", curRS.Name, *(tester.deployment.Spec.Replicas), desired)
868 }
869 }
870 }
871
872 func TestSpecReplicasChange(t *testing.T) {
873 _, ctx := ktesting.NewTestContext(t)
874 ctx, cancel := context.WithCancel(ctx)
875 defer cancel()
876
877 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
878 defer closeFn()
879
880 name := "test-spec-replicas-change"
881 ns := framework.CreateNamespaceOrDie(c, name, t)
882 defer framework.DeleteNamespaceOrDie(c, ns, t)
883
884 deploymentName := "deployment"
885 replicas := int32(1)
886 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(deploymentName, ns.Name, replicas)}
887 tester.deployment.Spec.Strategy.Type = apps.RecreateDeploymentStrategyType
888 tester.deployment.Spec.Strategy.RollingUpdate = nil
889 var err error
890 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
891 if err != nil {
892 t.Fatalf("failed to create deployment %q: %v", deploymentName, err)
893 }
894
895
896 stopControllers := runControllersAndInformers(t, rm, dc, informers)
897 defer stopControllers()
898
899
900 if err = tester.scaleDeployment(2); err != nil {
901 t.Fatal(err)
902 }
903 if err = tester.scaleDeployment(0); err != nil {
904 t.Fatal(err)
905 }
906 if err = tester.scaleDeployment(1); err != nil {
907 t.Fatal(err)
908 }
909
910
911
912 var oldGeneration int64
913 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
914 oldGeneration = update.Generation
915 update.Spec.RevisionHistoryLimit = ptr.To[int32](4)
916 })
917 if err != nil {
918 t.Fatalf("failed updating deployment %q: %v", tester.deployment.Name, err)
919 }
920
921 savedGeneration := tester.deployment.Generation
922 if savedGeneration == oldGeneration {
923 t.Fatalf("Failed to verify .Generation has incremented for deployment %q", deploymentName)
924 }
925 if err = tester.waitForObservedDeployment(savedGeneration); err != nil {
926 t.Fatal(err)
927 }
928 }
929
930 func TestDeploymentAvailableCondition(t *testing.T) {
931 _, ctx := ktesting.NewTestContext(t)
932 ctx, cancel := context.WithCancel(ctx)
933 defer cancel()
934
935 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
936 defer closeFn()
937
938 name := "test-deployment-available-condition"
939 ns := framework.CreateNamespaceOrDie(c, name, t)
940 defer framework.DeleteNamespaceOrDie(c, ns, t)
941
942 deploymentName := "deployment"
943 replicas := int32(10)
944 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(deploymentName, ns.Name, replicas)}
945
946 tester.deployment.Spec.MinReadySeconds = 3600
947
948 tester.deployment.Spec.ProgressDeadlineSeconds = ptr.To[int32](7200)
949 var err error
950 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
951 if err != nil {
952 t.Fatalf("failed to create deployment %q: %v", deploymentName, err)
953 }
954
955
956 stopControllers := runControllersAndInformers(t, rm, dc, informers)
957 defer stopControllers()
958
959
960 if err = tester.waitForDeploymentUpdatedReplicasGTE(replicas); err != nil {
961 t.Fatal(err)
962 }
963
964
965 if err = tester.waitForDeploymentWithCondition(deploymentutil.MinimumReplicasUnavailable, apps.DeploymentAvailable); err != nil {
966 t.Fatal(err)
967 }
968
969
970 if err = tester.checkDeploymentStatusReplicasFields(10, 10, 0, 0, 10); err != nil {
971 t.Fatal(err)
972 }
973
974
975 if err = tester.markUpdatedPodsReadyWithoutComplete(); err != nil {
976 t.Fatal(err)
977 }
978
979
980 if err = tester.waitForReadyReplicas(); err != nil {
981 t.Fatal(err)
982 }
983
984
985 if err = tester.waitForDeploymentWithCondition(deploymentutil.MinimumReplicasUnavailable, apps.DeploymentAvailable); err != nil {
986 t.Fatal(err)
987 }
988
989
990 if err = tester.checkDeploymentStatusReplicasFields(10, 10, 10, 0, 10); err != nil {
991 t.Fatal(err)
992 }
993
994
995 tester.deployment, err = tester.updateDeployment(func(update *apps.Deployment) {
996 update.Spec.MinReadySeconds = 1
997 })
998 if err != nil {
999 t.Fatalf("failed updating deployment %q: %v", deploymentName, err)
1000 }
1001
1002
1003 if err := tester.waitForObservedDeployment(tester.deployment.Generation); err != nil {
1004 t.Fatal(err)
1005 }
1006
1007
1008 if err = tester.waitForDeploymentWithCondition(deploymentutil.MinimumReplicasAvailable, apps.DeploymentAvailable); err != nil {
1009 t.Fatal(err)
1010 }
1011
1012
1013 if err = tester.checkDeploymentStatusReplicasFields(10, 10, 10, 10, 0); err != nil {
1014 t.Fatal(err)
1015 }
1016 }
1017
1018
1019 func testRSControllerRefPatch(t *testing.T, tester *deploymentTester, rs *apps.ReplicaSet, ownerReference *metav1.OwnerReference, expectedOwnerReferenceNum int) {
1020 ns := rs.Namespace
1021 rsClient := tester.c.AppsV1().ReplicaSets(ns)
1022 rs, err := tester.updateReplicaSet(rs.Name, func(update *apps.ReplicaSet) {
1023 update.OwnerReferences = []metav1.OwnerReference{*ownerReference}
1024 })
1025 if err != nil {
1026 t.Fatalf("failed to update replicaset %q: %v", rs.Name, err)
1027 }
1028
1029 if err := wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
1030 newRS, err := rsClient.Get(context.TODO(), rs.Name, metav1.GetOptions{})
1031 if err != nil {
1032 return false, err
1033 }
1034 return metav1.GetControllerOf(newRS) != nil, nil
1035 }); err != nil {
1036 t.Fatalf("failed to wait for controllerRef of the replicaset %q to become nil: %v", rs.Name, err)
1037 }
1038
1039 newRS, err := rsClient.Get(context.TODO(), rs.Name, metav1.GetOptions{})
1040 if err != nil {
1041 t.Fatalf("failed to obtain replicaset %q: %v", rs.Name, err)
1042 }
1043 controllerRef := metav1.GetControllerOf(newRS)
1044 if controllerRef.UID != tester.deployment.UID {
1045 t.Fatalf("controllerRef of replicaset %q has a different UID: Expected %v, got %v", newRS.Name, tester.deployment.UID, controllerRef.UID)
1046 }
1047 ownerReferenceNum := len(newRS.GetOwnerReferences())
1048 if ownerReferenceNum != expectedOwnerReferenceNum {
1049 t.Fatalf("unexpected number of owner references for replicaset %q: Expected %d, got %d", newRS.Name, expectedOwnerReferenceNum, ownerReferenceNum)
1050 }
1051 }
1052
1053 func TestGeneralReplicaSetAdoption(t *testing.T) {
1054 _, ctx := ktesting.NewTestContext(t)
1055 ctx, cancel := context.WithCancel(ctx)
1056 defer cancel()
1057
1058 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
1059 defer closeFn()
1060
1061 name := "test-general-replicaset-adoption"
1062 ns := framework.CreateNamespaceOrDie(c, name, t)
1063 defer framework.DeleteNamespaceOrDie(c, ns, t)
1064
1065 deploymentName := "deployment"
1066 replicas := int32(1)
1067 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(deploymentName, ns.Name, replicas)}
1068 var err error
1069 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
1070 if err != nil {
1071 t.Fatalf("failed to create deployment %q: %v", deploymentName, err)
1072 }
1073
1074
1075 stopControllers := runControllersAndInformers(t, rm, dc, informers)
1076 defer stopControllers()
1077
1078
1079 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
1080 t.Fatal(err)
1081 }
1082
1083
1084 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
1085 t.Fatal(err)
1086 }
1087
1088
1089 rs, err := testutil.GetNewReplicaSet(tester.deployment, c)
1090 if err != nil {
1091 t.Fatalf("failed to get replicaset of deployment %q: %v", deploymentName, err)
1092 }
1093 if rs == nil {
1094 t.Fatalf("unable to find replicaset of deployment %q", deploymentName)
1095 }
1096
1097
1098
1099
1100 var falseVar = false
1101 ownerReference := metav1.OwnerReference{UID: uuid.NewUUID(), APIVersion: "apps/v1", Kind: "StatefulSet", Name: deploymentName, Controller: &falseVar}
1102 testRSControllerRefPatch(t, tester, rs, &ownerReference, 2)
1103
1104
1105
1106 ownerReference = metav1.OwnerReference{UID: tester.deployment.UID, APIVersion: "apps/v1", Kind: "Deployment", Name: deploymentName, Controller: &falseVar}
1107 testRSControllerRefPatch(t, tester, rs, &ownerReference, 1)
1108 }
1109
1110 func testScalingUsingScaleSubresource(t *testing.T, tester *deploymentTester, replicas int32) {
1111 ns := tester.deployment.Namespace
1112 deploymentName := tester.deployment.Name
1113 deploymentClient := tester.c.AppsV1().Deployments(ns)
1114 deployment, err := deploymentClient.Get(context.TODO(), deploymentName, metav1.GetOptions{})
1115 if err != nil {
1116 t.Fatalf("Failed to obtain deployment %q: %v", deploymentName, err)
1117 }
1118 scale, err := tester.c.AppsV1().Deployments(ns).GetScale(context.TODO(), deploymentName, metav1.GetOptions{})
1119 if err != nil {
1120 t.Fatalf("Failed to obtain scale subresource for deployment %q: %v", deploymentName, err)
1121 }
1122 if scale.Spec.Replicas != *deployment.Spec.Replicas {
1123 t.Fatalf("Scale subresource for deployment %q does not match .Spec.Replicas: expected %d, got %d", deploymentName, *deployment.Spec.Replicas, scale.Spec.Replicas)
1124 }
1125
1126 if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
1127 scale, err := tester.c.AppsV1().Deployments(ns).GetScale(context.TODO(), deploymentName, metav1.GetOptions{})
1128 if err != nil {
1129 return err
1130 }
1131 scale.Spec.Replicas = replicas
1132 _, err = tester.c.AppsV1().Deployments(ns).UpdateScale(context.TODO(), deploymentName, scale, metav1.UpdateOptions{})
1133 return err
1134 }); err != nil {
1135 t.Fatalf("Failed to set .Spec.Replicas of scale subresource for deployment %q: %v", deploymentName, err)
1136 }
1137
1138 deployment, err = deploymentClient.Get(context.TODO(), deploymentName, metav1.GetOptions{})
1139 if err != nil {
1140 t.Fatalf("Failed to obtain deployment %q: %v", deploymentName, err)
1141 }
1142 if *deployment.Spec.Replicas != replicas {
1143 t.Fatalf(".Spec.Replicas of deployment %q does not match its scale subresource: expected %d, got %d", deploymentName, replicas, *deployment.Spec.Replicas)
1144 }
1145 }
1146
1147 func TestDeploymentScaleSubresource(t *testing.T) {
1148 _, ctx := ktesting.NewTestContext(t)
1149 ctx, cancel := context.WithCancel(ctx)
1150 defer cancel()
1151
1152 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
1153 defer closeFn()
1154
1155 name := "test-deployment-scale-subresource"
1156 ns := framework.CreateNamespaceOrDie(c, name, t)
1157 defer framework.DeleteNamespaceOrDie(c, ns, t)
1158
1159 deploymentName := "deployment"
1160 replicas := int32(2)
1161 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(deploymentName, ns.Name, replicas)}
1162 var err error
1163 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
1164 if err != nil {
1165 t.Fatalf("failed to create deployment %q: %v", deploymentName, err)
1166 }
1167
1168
1169 stopControllers := runControllersAndInformers(t, rm, dc, informers)
1170 defer stopControllers()
1171
1172
1173 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
1174 t.Fatal(err)
1175 }
1176
1177
1178 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
1179 t.Fatal(err)
1180 }
1181
1182
1183 testScalingUsingScaleSubresource(t, tester, 3)
1184
1185 testScalingUsingScaleSubresource(t, tester, 0)
1186 }
1187
1188
1189
1190
1191
1192
1193 func TestReplicaSetOrphaningAndAdoptionWhenLabelsChange(t *testing.T) {
1194 _, ctx := ktesting.NewTestContext(t)
1195 ctx, cancel := context.WithCancel(ctx)
1196 defer cancel()
1197
1198 closeFn, rm, dc, informers, c := dcSetup(ctx, t)
1199 defer closeFn()
1200
1201 name := "test-replicaset-orphaning-and-adoption-when-labels-change"
1202 ns := framework.CreateNamespaceOrDie(c, name, t)
1203 defer framework.DeleteNamespaceOrDie(c, ns, t)
1204
1205 deploymentName := "deployment"
1206 replicas := int32(1)
1207 tester := &deploymentTester{t: t, c: c, deployment: newDeployment(deploymentName, ns.Name, replicas)}
1208 var err error
1209 tester.deployment, err = c.AppsV1().Deployments(ns.Name).Create(context.TODO(), tester.deployment, metav1.CreateOptions{})
1210 if err != nil {
1211 t.Fatalf("failed to create deployment %q: %v", deploymentName, err)
1212 }
1213
1214
1215 stopControllers := runControllersAndInformers(t, rm, dc, informers)
1216 defer stopControllers()
1217
1218
1219 if err := tester.waitForDeploymentRevisionAndImage("1", fakeImage); err != nil {
1220 t.Fatal(err)
1221 }
1222
1223
1224 if err := tester.waitForDeploymentCompleteAndMarkPodsReady(); err != nil {
1225 t.Fatal(err)
1226 }
1227
1228
1229
1230
1231 rs, err := testutil.GetNewReplicaSet(tester.deployment, c)
1232 if err != nil {
1233 t.Fatalf("failed to get replicaset of deployment %q: %v", deploymentName, err)
1234 }
1235 if rs == nil {
1236 t.Fatalf("unable to find replicaset of deployment %q", deploymentName)
1237 }
1238
1239
1240 controllerRef := metav1.GetControllerOf(rs)
1241 if controllerRef == nil {
1242 t.Fatalf("controllerRef of replicaset %q is nil", rs.Name)
1243 }
1244 if controllerRef.UID != tester.deployment.UID {
1245 t.Fatalf("controllerRef of replicaset %q has a different UID: Expected %v, got %v", rs.Name, tester.deployment.UID, controllerRef.UID)
1246 }
1247
1248
1249 labelMap := map[string]string{"new-name": "new-test"}
1250 rs, err = tester.updateReplicaSet(rs.Name, func(update *apps.ReplicaSet) {
1251 update.Labels = labelMap
1252 })
1253 if err != nil {
1254 t.Fatalf("failed to update replicaset %q: %v", rs.Name, err)
1255 }
1256
1257
1258 rsClient := tester.c.AppsV1().ReplicaSets(ns.Name)
1259 if err = wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
1260 rs, err = rsClient.Get(context.TODO(), rs.Name, metav1.GetOptions{})
1261 if err != nil {
1262 return false, err
1263 }
1264 return metav1.GetControllerOf(rs) == nil, nil
1265 }); err != nil {
1266 t.Fatalf("failed to wait for controllerRef of replicaset %q to become nil: %v", rs.Name, err)
1267 }
1268
1269
1270
1271
1272 var newRS *apps.ReplicaSet
1273 if err = wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
1274 newRS, err = testutil.GetNewReplicaSet(tester.deployment, c)
1275 if err != nil {
1276 return false, fmt.Errorf("failed to get new replicaset of deployment %q after orphaning: %v", deploymentName, err)
1277 }
1278 return newRS != nil, nil
1279 }); err != nil {
1280 t.Fatalf("failed to wait for deployment %q to create a new replicaset after orphaning: %v", deploymentName, err)
1281 }
1282 if newRS.UID == rs.UID {
1283 t.Fatalf("expect deployment %q to create a new replicaset different from the orphaned one, but it isn't", deploymentName)
1284 }
1285
1286
1287
1288
1289 rs, err = tester.updateReplicaSet(rs.Name, func(update *apps.ReplicaSet) {
1290 update.Labels = testLabels()
1291 })
1292 if err != nil {
1293 t.Fatalf("failed to update replicaset %q: %v", rs.Name, err)
1294 }
1295
1296
1297 if err = wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
1298 rs, err := rsClient.Get(context.TODO(), rs.Name, metav1.GetOptions{})
1299 if err != nil {
1300 return false, err
1301 }
1302 controllerRef = metav1.GetControllerOf(rs)
1303 return controllerRef != nil && controllerRef.UID == tester.deployment.UID, nil
1304 }); err != nil {
1305 t.Fatalf("failed waiting for replicaset adoption by deployment %q to complete: %v", deploymentName, err)
1306 }
1307 }
1308
View as plain text