Skip to content

Commit 5e6d98a

Browse files
committed
e2e: extract WaitForNodeIdle into testutil
Move the idle-wait polling pattern into a shared testutil.WaitForNodeIdle helper and replace all 14 occurrences across both test files. Assisted-by: AI Signed-off-by: Alice Frosi <afrosi@redhat.com>
1 parent 62a877e commit 5e6d98a

3 files changed

Lines changed: 83 additions & 218 deletions

File tree

‎test/e2e/bootcnode_test.go‎

Lines changed: 35 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,12 @@ func TestControllerMembership(t *testing.T) {
8686
HaveField("Status.Phase", corev1.PodRunning),
8787
)), "expected exactly one running daemon pod on %s", nodeName)
8888

89-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
90-
var bn bootcv1alpha1.BootcNode
91-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
92-
return bn.Status, err
93-
}).WithTimeout(3 * time.Minute).Should(And(
89+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute,
9490
HaveField("Booted", And(
95-
Not(BeNil()),
9691
HaveField("Image", env.NodeImageDigestedPullSpec()),
9792
HaveField("ImageDigest", env.NodeImageDigest()),
9893
)),
99-
HaveField("Conditions", ContainElement(And(
100-
HaveField("Type", bootcv1alpha1.NodeIdle),
101-
HaveField("Status", metav1.ConditionTrue),
102-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
103-
))),
104-
))
94+
)
10595

10696
// Verify pool status reflects steady state.
10797
g.Eventually(fetchPoolStatus(ctx, env.Client, pool)).
@@ -126,18 +116,7 @@ func TestUpdateReboot(t *testing.T) {
126116
pool := env.NewPool("workers", env.NodeImageDigestedPullSpec())
127117
g.Expect(env.Client.Create(ctx, pool)).To(Succeed())
128118

129-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
130-
var bn bootcv1alpha1.BootcNode
131-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
132-
return bn.Status, err
133-
}).WithTimeout(3 * time.Minute).Should(And(
134-
HaveField("Booted", Not(BeNil())),
135-
HaveField("Conditions", ContainElement(And(
136-
HaveField("Type", bootcv1alpha1.NodeIdle),
137-
HaveField("Status", metav1.ConditionTrue),
138-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
139-
))),
140-
))
119+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute)
141120

142121
t.Logf("Node %q is Idle with original image", nodeName)
143122

@@ -224,21 +203,9 @@ func TestUpdateReboot(t *testing.T) {
224203

225204
// Phase 4: Wait for Idle with the update digest — proves the full
226205
// update lifecycle completed (staging, reboot, boot into new image).
227-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
228-
var bn bootcv1alpha1.BootcNode
229-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
230-
return bn.Status, err
231-
}).WithTimeout(5*time.Minute).Should(And(
232-
HaveField("Booted", And(
233-
Not(BeNil()),
234-
HaveField("ImageDigest", env.NodeImageUpdateDigest()),
235-
)),
236-
HaveField("Conditions", ContainElement(And(
237-
HaveField("Type", bootcv1alpha1.NodeIdle),
238-
HaveField("Status", metav1.ConditionTrue),
239-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
240-
))),
241-
), "expected node to reach Idle with update image after reboot")
206+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 5*time.Minute,
207+
HaveField("Booted", HaveField("ImageDigest", env.NodeImageUpdateDigest())),
208+
)
242209

243210
t.Logf("Node %q is Idle with update image", nodeName)
244211

@@ -280,21 +247,9 @@ func TestUpdateReboot(t *testing.T) {
280247
t.Logf("Patched pool to rollback to original image %s", originalRef)
281248

282249
// Phase 8: Wait for Idle with the original digest — proves rollback succeeded.
283-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
284-
var bn2 bootcv1alpha1.BootcNode
285-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn2)
286-
return bn2.Status, err
287-
}).WithTimeout(5*time.Minute).Should(And(
288-
HaveField("Booted", And(
289-
Not(BeNil()),
290-
HaveField("ImageDigest", Equal(env.NodeImageDigest())),
291-
)),
292-
HaveField("Conditions", ContainElement(And(
293-
HaveField("Type", bootcv1alpha1.NodeIdle),
294-
HaveField("Status", metav1.ConditionTrue),
295-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
296-
))),
297-
), "expected node to reach Idle with original image after rollback")
250+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 5*time.Minute,
251+
HaveField("Booted", HaveField("ImageDigest", Equal(env.NodeImageDigest()))),
252+
)
298253

299254
t.Logf("Node %q successfully rolled back to original image", nodeName)
300255

@@ -333,20 +288,9 @@ func TestTagResolution(t *testing.T) {
333288
t.Logf("Tag resolved to original digest %s", env.NodeImageDigest())
334289

335290
// Wait for node to reach Idle with the original image.
336-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
337-
var bn bootcv1alpha1.BootcNode
338-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
339-
return bn.Status, err
340-
}).WithTimeout(3 * time.Minute).Should(And(
341-
HaveField("Booted", And(
342-
Not(BeNil()),
343-
HaveField("ImageDigest", Equal(env.NodeImageDigest())),
344-
)),
345-
HaveField("Conditions", ContainElement(And(
346-
HaveField("Type", bootcv1alpha1.NodeIdle),
347-
HaveField("Status", metav1.ConditionTrue),
348-
))),
349-
))
291+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute,
292+
HaveField("Booted", HaveField("ImageDigest", Equal(env.NodeImageDigest()))),
293+
)
350294

351295
t.Logf("Node %q is Idle with original image", nodeName)
352296

@@ -391,20 +335,9 @@ func TestTagResolution(t *testing.T) {
391335
)))
392336

393337
// Wait for node to reach Idle with the update image.
394-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
395-
var bn bootcv1alpha1.BootcNode
396-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
397-
return bn.Status, err
398-
}).WithTimeout(5 * time.Minute).Should(And(
399-
HaveField("Booted", And(
400-
Not(BeNil()),
401-
HaveField("ImageDigest", Equal(env.NodeImageUpdateDigest())),
402-
)),
403-
HaveField("Conditions", ContainElement(And(
404-
HaveField("Type", bootcv1alpha1.NodeIdle),
405-
HaveField("Status", metav1.ConditionTrue),
406-
))),
407-
))
338+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 5*time.Minute,
339+
HaveField("Booted", HaveField("ImageDigest", Equal(env.NodeImageUpdateDigest()))),
340+
)
408341

409342
t.Logf("Node %q is Idle with update image", nodeName)
410343
}
@@ -431,18 +364,7 @@ func TestMidRolloutImageChange(t *testing.T) {
431364
g.Expect(env.Client.Create(ctx, pool)).To(Succeed())
432365

433366
for _, nodeName := range []string{nodeA, nodeB} {
434-
g.Eventually(func() (bootcv1alpha1.BootcNode, error) {
435-
var bn bootcv1alpha1.BootcNode
436-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
437-
return bn, err
438-
}).WithTimeout(3 * time.Minute).Should(SatisfyAll(
439-
HaveField("Status.Booted", Not(BeNil())),
440-
HaveField("Status.Conditions", ContainElement(And(
441-
HaveField("Type", bootcv1alpha1.NodeIdle),
442-
HaveField("Status", metav1.ConditionTrue),
443-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
444-
))),
445-
))
367+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute)
446368
}
447369

448370
t.Logf("Both nodes are Idle with original image")
@@ -503,19 +425,9 @@ func TestMidRolloutImageChange(t *testing.T) {
503425

504426
// Phase 6: Wait for both nodes to be Idle with the second update image.
505427
for _, nodeName := range []string{nodeA, nodeB} {
506-
g.Eventually(func() (bootcv1alpha1.BootcNode, error) {
507-
var bn bootcv1alpha1.BootcNode
508-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
509-
return bn, err
510-
}).WithTimeout(8*time.Minute).Should(SatisfyAll(
511-
HaveField("Status.Booted", Not(BeNil())),
512-
HaveField("Status.Booted.ImageDigest", Equal(env.NodeImageUpdate2Digest())),
513-
HaveField("Status.Conditions", ContainElement(And(
514-
HaveField("Type", bootcv1alpha1.NodeIdle),
515-
HaveField("Status", metav1.ConditionTrue),
516-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
517-
))),
518-
), "expected node %s to reach Idle with second update image", nodeName)
428+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 8*time.Minute,
429+
HaveField("Booted", HaveField("ImageDigest", Equal(env.NodeImageUpdate2Digest()))),
430+
)
519431
}
520432

521433
t.Logf("Both nodes are Idle with second update image")
@@ -627,21 +539,12 @@ func TestPauseResume(t *testing.T) {
627539
pool := env.NewPool("bnp-pause", env.NodeImageDigestedPullSpec())
628540
g.Expect(env.Client.Create(ctx, pool)).To(Succeed())
629541

630-
var bn bootcv1alpha1.BootcNode
631-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
632-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
633-
return bn.Status, err
634-
}).WithTimeout(3 * time.Minute).Should(And(
635-
HaveField("Booted", Not(BeNil())),
636-
HaveField("Conditions", ContainElement(And(
637-
HaveField("Type", bootcv1alpha1.NodeIdle),
638-
HaveField("Status", metav1.ConditionTrue),
639-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
640-
))),
641-
))
542+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute)
642543

643544
t.Logf("Node %q is Idle with original image", nodeName)
644545

546+
var bn bootcv1alpha1.BootcNode
547+
645548
// Phase 2: Patch pool to update image with paused=true.
646549
updateRef := env.NodeImageUpdateDigestedPullSpec()
647550

@@ -712,20 +615,9 @@ func TestPauseResume(t *testing.T) {
712615

713616
// Phase 5: Wait for node to complete the update — proves the full
714617
// update lifecycle completed after resume (reboot, boot into new image).
715-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
716-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
717-
return bn.Status, err
718-
}).WithTimeout(5*time.Minute).Should(And(
719-
HaveField("Booted", And(
720-
Not(BeNil()),
721-
HaveField("ImageDigest", Equal(env.NodeImageUpdateDigest())),
722-
)),
723-
HaveField("Conditions", ContainElement(And(
724-
HaveField("Type", bootcv1alpha1.NodeIdle),
725-
HaveField("Status", metav1.ConditionTrue),
726-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
727-
))),
728-
), "expected node to reach Idle with update image after resume")
618+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 5*time.Minute,
619+
HaveField("Booted", HaveField("ImageDigest", Equal(env.NodeImageUpdateDigest()))),
620+
)
729621

730622
t.Logf("Node %q completed update after resume", nodeName)
731623

@@ -752,21 +644,12 @@ func TestNonExistingImage(t *testing.T) {
752644
pool := env.NewPool("bnp-noimg", env.NodeImageDigestedPullSpec())
753645
g.Expect(env.Client.Create(ctx, pool)).To(Succeed())
754646

755-
var bn bootcv1alpha1.BootcNode
756-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
757-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
758-
return bn.Status, err
759-
}).WithTimeout(3 * time.Minute).Should(And(
760-
HaveField("Booted", Not(BeNil())),
761-
HaveField("Conditions", ContainElement(And(
762-
HaveField("Type", bootcv1alpha1.NodeIdle),
763-
HaveField("Status", metav1.ConditionTrue),
764-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
765-
))),
766-
))
647+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute)
767648

768649
t.Logf("Node %q is Idle with original image", nodeName)
769650

651+
var bn bootcv1alpha1.BootcNode
652+
770653
// Phase 2: Patch pool to update to a non-existing image.
771654
nonExistingRef := "localhost:5000/node@sha256:0000000000000000000000000000000000000000000000000000000000000000"
772655

@@ -886,21 +769,9 @@ func TestPullSecretAuth(t *testing.T) {
886769
// Check Booted.Image (the full ref with manifest digest) rather
887770
// than Booted.ImageDigest (the content digest) because they can
888771
// differ with remote registries.
889-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
890-
var bn bootcv1alpha1.BootcNode
891-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
892-
return bn.Status, err
893-
}).WithTimeout(5 * time.Minute).Should(And(
894-
HaveField("Booted", And(
895-
Not(BeNil()),
896-
HaveField("Image", Equal(authImageRef)),
897-
)),
898-
HaveField("Conditions", ContainElement(And(
899-
HaveField("Type", bootcv1alpha1.NodeIdle),
900-
HaveField("Status", metav1.ConditionTrue),
901-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
902-
))),
903-
))
772+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 5*time.Minute,
773+
HaveField("Booted", HaveField("Image", Equal(authImageRef))),
774+
)
904775

905776
t.Logf("Node %q booted into auth-registry image", nodeName)
906777

@@ -930,18 +801,7 @@ func TestControllerRecovery(t *testing.T) {
930801
pool := env.NewPool("bnp-recovery", env.NodeImageDigestedPullSpec())
931802
g.Expect(env.Client.Create(ctx, pool)).To(Succeed())
932803

933-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
934-
var bn bootcv1alpha1.BootcNode
935-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
936-
return bn.Status, err
937-
}).WithTimeout(3 * time.Minute).Should(And(
938-
HaveField("Booted", Not(BeNil())),
939-
HaveField("Conditions", ContainElement(And(
940-
HaveField("Type", bootcv1alpha1.NodeIdle),
941-
HaveField("Status", metav1.ConditionTrue),
942-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
943-
))),
944-
))
804+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 3*time.Minute)
945805

946806
t.Logf("Node %q is Idle with original image", nodeName)
947807

@@ -1024,21 +884,9 @@ func TestControllerRecovery(t *testing.T) {
1024884
scaleController(t, env, ctx, 1)
1025885
t.Logf("Controller restored; waiting for the interrupted rollout to finish")
1026886

1027-
g.Eventually(func() (bootcv1alpha1.BootcNodeStatus, error) {
1028-
var bn bootcv1alpha1.BootcNode
1029-
err := env.Client.Get(ctx, client.ObjectKey{Name: nodeName}, &bn)
1030-
return bn.Status, err
1031-
}).WithTimeout(5*time.Minute).Should(And(
1032-
HaveField("Booted", And(
1033-
Not(BeNil()),
1034-
HaveField("ImageDigest", Equal(env.NodeImageUpdateDigest())),
1035-
)),
1036-
HaveField("Conditions", ContainElement(And(
1037-
HaveField("Type", bootcv1alpha1.NodeIdle),
1038-
HaveField("Status", metav1.ConditionTrue),
1039-
HaveField("Reason", bootcv1alpha1.NodeReasonIdle),
1040-
))),
1041-
), "expected node to reach Idle with update image after controller recovery")
887+
testutil.WaitForNodeIdle(t, g, ctx, env.Client, nodeName, 5*time.Minute,
888+
HaveField("Booted", HaveField("ImageDigest", Equal(env.NodeImageUpdateDigest()))),
889+
)
1042890

1043891
t.Logf("Node %q completed the interrupted rollout after controller recovery", nodeName)
1044892

0 commit comments

Comments
 (0)