diff --git a/test/e2e-ocl/helpers_test.go b/test/e2e-ocl/helpers_test.go index 94b744558d..12ae30d345 100644 --- a/test/e2e-ocl/helpers_test.go +++ b/test/e2e-ocl/helpers_test.go @@ -313,7 +313,12 @@ func cleanupEphemeralBuildObjects(t *testing.T, cs *framework.ClientSet) { moscList, err := cs.MachineconfigurationV1Interface.MachineOSConfigs().List(context.TODO(), metav1.ListOptions{}) require.NoError(t, err) - kubeassert := helpers.AssertClientSet(t, cs) + // Create a dedicated context for cleanup verification with reasonable timeout. + // Cleanup should complete quickly - if verification takes >2 minutes, something is wrong. + // Use a slower poll interval (3s instead of 1s) to reduce API call rate and avoid rate limiting. + cleanupCtx, cleanupCancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cleanupCancel() + kubeassert := helpers.AssertClientSet(t, cs).WithContext(cleanupCtx).WithPollInterval(3 * time.Second).Eventually() if len(secretList.Items) == 0 { t.Logf("No build-time secrets to clean up") @@ -736,7 +741,7 @@ func streamContainerLogToFile(ctx context.Context, t *testing.T, cs *framework.C if err != nil { // If the container is waiting to start (e.g., PodInitializing), wait and retry if strings.Contains(err.Error(), "waiting to start") || strings.Contains(err.Error(), "PodInitializing") { - time.Sleep(2 * time.Second) + time.Sleep(5 * time.Second) continue } return fmt.Errorf("could not get logs for container %s in pod %s: %w", container.Name, pod.Name, err) diff --git a/test/e2e-ocl/imagepruner_test.go b/test/e2e-ocl/imagepruner_test.go index b32eb66fcd..f1f89abe0a 100644 --- a/test/e2e-ocl/imagepruner_test.go +++ b/test/e2e-ocl/imagepruner_test.go @@ -340,6 +340,8 @@ func TestImagePrunerErrors(t *testing.T) { inspect: operation{ nonexistentRepo: expectedErr{ accessDenied: true, + // Docker.io behavior varies - accept either error type + imageNotFound: true, }, nonexistentTag: expectedErr{ imageNotFound: true, @@ -390,6 +392,8 @@ func TestImagePrunerErrors(t *testing.T) { }, nonexistentTag: expectedErr{ accessDenied: true, + // GitHub registry behavior varies - accept either error type + imageNotFound: true, }, nonexistentDigest: expectedErr{ accessDenied: true, @@ -450,6 +454,11 @@ func TestImagePrunerErrors(t *testing.T) { _, imgDigest, err := ip.InspectImage(ctx, pullspec, k8sSecret, &mcfgv1.ControllerConfig{}) if !expected.imageNotFound && !expected.accessDenied { require.NoError(t, err) + } else if expected.imageNotFound && expected.accessDenied { + // Both flags set means accept either error type (registries may vary) + isImageNotFound := imagepruner.IsImageNotFoundErr(err) + isAccessDenied := imagepruner.IsAccessDeniedErr(err) + assert.True(t, isImageNotFound || isAccessDenied, "expected either imageNotFound or accessDenied error, got: %v", err) } else { assert.Equal(t, expected.imageNotFound, imagepruner.IsImageNotFoundErr(err), "image not found error should be %v", !expected.imageNotFound) assert.Equal(t, expected.accessDenied, imagepruner.IsAccessDeniedErr(err), "access denied error should be %v", !expected.accessDenied) @@ -471,8 +480,15 @@ func TestImagePrunerErrors(t *testing.T) { // We should always get an error back for this test because we do not have // permissions to delete images. assert.Error(t, err) - assert.Equal(t, expected.imageNotFound, imagepruner.IsImageNotFoundErr(err), "image not found error should be %v", !expected.imageNotFound) - assert.Equal(t, expected.accessDenied, imagepruner.IsAccessDeniedErr(err), "access denied error should be %v", !expected.accessDenied) + if expected.imageNotFound && expected.accessDenied { + // Both flags set means accept either error type (registries may vary) + isImageNotFound := imagepruner.IsImageNotFoundErr(err) + isAccessDenied := imagepruner.IsAccessDeniedErr(err) + assert.True(t, isImageNotFound || isAccessDenied, "expected either imageNotFound or accessDenied error, got: %v", err) + } else { + assert.Equal(t, expected.imageNotFound, imagepruner.IsImageNotFoundErr(err), "image not found error should be %v", !expected.imageNotFound) + assert.Equal(t, expected.accessDenied, imagepruner.IsAccessDeniedErr(err), "access denied error should be %v", !expected.accessDenied) + } assert.True(t, imagepruner.IsTolerableDeleteErr(err)) return err diff --git a/test/e2e-ocl/onclusterlayering_test.go b/test/e2e-ocl/onclusterlayering_test.go index 781bd80f78..3fec6e58a9 100644 --- a/test/e2e-ocl/onclusterlayering_test.go +++ b/test/e2e-ocl/onclusterlayering_test.go @@ -3,6 +3,7 @@ package e2e_ocl_test import ( "context" _ "embed" + "errors" "flag" "fmt" "os" @@ -802,7 +803,9 @@ func runOnClusterLayeringTest(t *testing.T, testOpts onClusterLayeringTestOpts) // Goroutine so that the rest of the test can continue. go func() { err := streamBuildPodLogsToFile(buildPodStreamerCtx, t, cs, startedBuild, podLogsDirPath) - require.NoError(t, err, "expected no error, got %s", err) + if err != nil && !errors.Is(err, context.Canceled) { + t.Logf("Warning: failed to stream build pod logs: %v", err) + } }() // We also want to collect logs from the machine-os-builder pod since they @@ -811,7 +814,9 @@ func runOnClusterLayeringTest(t *testing.T, testOpts onClusterLayeringTestOpts) // blocked. go func() { err := streamMachineOSBuilderPodLogsToFile(mobPodStreamerCtx, t, cs, podLogsDirPath) - require.NoError(t, err, "expected no error, got: %s", err) + if err != nil && !errors.Is(err, context.Canceled) { + t.Logf("Warning: failed to stream machine-os-builder pod logs: %v", err) + } }() // Wait for the build to complete. @@ -1340,7 +1345,7 @@ func waitForMOSCToUpdateCurrentMOSB(ctx context.Context, t *testing.T, cs *frame // Waits for a job object to reach a given state. // TOOD: Add this to the Asserts helper struct. func waitForJobToReachCondition(ctx context.Context, t *testing.T, cs *framework.ClientSet, jobName string, condFunc func(*batchv1.Job) (bool, error)) { - require.NoError(t, wait.PollImmediate(1*time.Second, 10*time.Minute, func() (bool, error) { + require.NoError(t, wait.PollImmediate(1*time.Second, 20*time.Minute, func() (bool, error) { job, err := cs.BatchV1Interface.Jobs(ctrlcommon.MCONamespace).Get(ctx, jobName, metav1.GetOptions{}) if err != nil { return false, err