e2e: add controller recovery test - #152
Conversation
| // Phase 3: Patch pool to update image while controller is down. | ||
| updateRef := env.NodeImageUpdateDigestedPullSpec() | ||
|
|
||
| poolModified := pool.DeepCopy() | ||
| poolModified.Spec.Image.Ref = updateRef | ||
| g.Expect(env.Client.Patch(ctx, poolModified, client.MergeFrom(pool))).To(Succeed()) | ||
| *pool = *poolModified | ||
|
|
||
| t.Logf("Patched pool to update image %s while controller is down", updateRef) | ||
|
|
||
| // Wait briefly to confirm nothing happens while controller is down. | ||
| g.Consistently(func() (bootcv1alpha1.BootcNodeStatus, error) { | ||
| var bn bootcv1alpha1.BootcNode | ||
| err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn) | ||
| return bn.Status, err | ||
| }).WithTimeout(10*time.Second).WithPolling(2*time.Second).Should( | ||
| HaveField("Booted.ImageDigest", Equal(env.NodeImageDigest())), | ||
| "node should not update while controller is down", | ||
| ) | ||
|
|
||
| // Phase 4: Scale controller back to one. | ||
| g.Expect(env.Client.Get(ctx, deployKey, controllerDeploy)).To(Succeed()) | ||
| modified = controllerDeploy.DeepCopy() | ||
| one := int32(1) | ||
| modified.Spec.Replicas = &one | ||
| g.Expect(env.Client.Patch(ctx, modified, client.MergeFrom(controllerDeploy))).To(Succeed()) |
There was a problem hiding this comment.
Test never interrupts an active rollout
The image changes while the controller is already stopped, so restart simply begins a new rollout.
HarshwardhanPatil07
left a comment
There was a problem hiding this comment.
You will need to sign DCO
e14d71b to
f5b290b
Compare
Signed-off-by: Prachiti Talgulkar <ptalgulk01@users.noreply.github.com>
f5b290b to
307a246
Compare
|
|
||
| t.Logf("Rollout in progress; interrupting the controller") | ||
|
|
||
| // Phase 4: Scale the controller to zero, interrupting the active rollout. |
There was a problem hiding this comment.
I'm wondering if we should pause the pool at this stage. I'm afraid that if the pulling is fast enough, the node might go in rebooting before scale down the controller, and it is a possible source for race conditions. Would it make sense to pause it when we detect the staging, scale down the operator and unpause it?
| deployKey := client.ObjectKey{ | ||
| Namespace: "bootc-operator", | ||
| Name: "bootc-operator-controller-manager", | ||
| } | ||
| // Restore replicas on cleanup in case the test fails while scaled down. | ||
| t.Cleanup(func() { | ||
| var d appsv1.Deployment | ||
| if err := env.Client.Get(ctx, deployKey, &d); err != nil { | ||
| return | ||
| } | ||
| if d.Spec.Replicas != nil && *d.Spec.Replicas == 0 { | ||
| restore := d.DeepCopy() | ||
| one := int32(1) | ||
| restore.Spec.Replicas = &one | ||
| _ = env.Client.Patch(ctx, restore, client.MergeFrom(&d)) | ||
| } | ||
| }) | ||
|
|
||
| controllerDeploy := &appsv1.Deployment{} | ||
| g.Expect(env.Client.Get(ctx, deployKey, controllerDeploy)).To(Succeed()) | ||
|
|
||
| down := controllerDeploy.DeepCopy() | ||
| zero := int32(0) | ||
| down.Spec.Replicas = &zero | ||
| g.Expect(env.Client.Patch(ctx, down, client.MergeFrom(controllerDeploy))).To(Succeed()) | ||
|
|
||
| g.Eventually(func() (int32, error) { | ||
| var d appsv1.Deployment | ||
| err := env.Client.Get(ctx, deployKey, &d) | ||
| return d.Status.AvailableReplicas, err | ||
| }).WithTimeout(1*time.Minute).Should(BeZero(), | ||
| "expected controller to scale to zero") | ||
|
|
||
| t.Logf("Controller scaled to zero mid-rollout") |
There was a problem hiding this comment.
Can you create an helper function for scaling up and down the controller? It could be reused by other tests and it makes the entire test more readable
| g.Expect(env.Client.Get(ctx, deployKey, controllerDeploy)).To(Succeed()) | ||
| up := controllerDeploy.DeepCopy() | ||
| one := int32(1) | ||
| up.Spec.Replicas = &one | ||
| g.Expect(env.Client.Patch(ctx, up, client.MergeFrom(controllerDeploy))).To(Succeed()) | ||
|
|
||
| g.Eventually(func() (int32, error) { | ||
| var d appsv1.Deployment | ||
| err := env.Client.Get(ctx, deployKey, &d) | ||
| return d.Status.AvailableReplicas, err | ||
| }).WithTimeout(2*time.Minute).Should(Equal(int32(1)), | ||
| "expected controller to scale back to one") | ||
|
|
||
| t.Logf("Controller restored; waiting for the interrupted rollout to finish") |
There was a problem hiding this comment.
This also could be replaced by the helper function
Summary
Context
Part of the e2e test planning in #69 (scenario 5: kill controller/daemon during rollout).
Manual testing also revealed that scenarios 4 (faulty node after reboot) and 8 (cross-distro bad image) both fail — the controller has no reboot timeout and doesn't correlate Node.Ready status, so nodes stuck after reboot are never marked degraded. Those need feature work before tests can be written.
Test plan