From 6264b559c9d974de6fbb9abe5189c025840d13c7 Mon Sep 17 00:00:00 2001 From: aviralgarg05 Date: Wed, 14 Jan 2026 00:38:50 +0530 Subject: [PATCH] Fix flaky TestApplyCRDuringCRDFinalization test This PR fixes the flaky TestApplyCRDuringCRDFinalization test that was failing intermittently on slower systems (s390x architecture, race detector builds). The root cause was a race condition where the test would attempt to apply a CR immediately after requesting CRD deletion, without waiting for the CRD to actually enter the terminating state. The fix explicitly waits for the CRD to have the Terminating condition set to True before attempting the apply. --- .../test/integration/finalization_test.go | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/staging/src/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go b/staging/src/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go index 11435f45c22..a440b33284f 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apiextensions-apiserver/test/integration/fixtures" "k8s.io/apimachinery/pkg/api/errors" @@ -30,6 +31,11 @@ import ( "k8s.io/apimachinery/pkg/util/wait" ) +const ( + testNamespace = "not-the-default" + testFinalizer = "noxu.example.com/finalizer" +) + func TestFinalization(t *testing.T) { tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) require.NoError(t, err) @@ -39,12 +45,12 @@ func TestFinalization(t *testing.T) { noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) require.NoError(t, err) - ns := "not-the-default" + ns := testNamespace name := "foo123" noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) instance := fixtures.NewNoxuInstance(ns, name) - instance.SetFinalizers([]string{"noxu.example.com/finalizer"}) + instance.SetFinalizers([]string{testFinalizer}) createdNoxuInstance, err := instantiateCustomResource(t, instance, noxuResourceClient, noxuDefinition) require.NoError(t, err) @@ -104,12 +110,12 @@ func TestFinalizationAndDeletion(t *testing.T) { require.NoError(t, err) // Create a CR with a finalizer. - ns := "not-the-default" + ns := testNamespace name := "foo123" noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) instance := fixtures.NewNoxuInstance(ns, name) - instance.SetFinalizers([]string{"noxu.example.com/finalizer"}) + instance.SetFinalizers([]string{testFinalizer}) createdNoxuInstance, err := instantiateCustomResource(t, instance, noxuResourceClient, noxuDefinition) require.NoError(t, err) @@ -171,7 +177,7 @@ func TestApplyCRDuringCRDFinalization(t *testing.T) { // Create a CRD with a finalizer which will stall deletion noxuDefinition := fixtures.NewNoxuV1CustomResourceDefinition(apiextensionsv1.ClusterScoped) - noxuDefinition.SetFinalizers([]string{"noxu.example.com/finalizer"}) + noxuDefinition.SetFinalizers([]string{testFinalizer}) noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient) require.NoError(t, err) @@ -179,20 +185,27 @@ func TestApplyCRDuringCRDFinalization(t *testing.T) { err = apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Delete(t.Context(), noxuDefinition.Name, metav1.DeleteOptions{}) require.NoError(t, err) + // Wait for the CRD to have the Terminating condition set to True. + // The handler checks IsCRDConditionTrue(crd, apiextensionsv1.Terminating) to block + // CR creation, and this condition is set asynchronously by the CRD finalizer controller + // after it observes the DeletionTimestamp. Without this wait, the Apply could succeed + // if it races ahead of the controller setting the condition. + err = wait.PollUntilContextTimeout(t.Context(), 100*time.Millisecond, wait.ForeverTestTimeout, true, func(ctx context.Context) (bool, error) { + crd, err := apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, noxuDefinition.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + return apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Terminating), nil + }) + require.NoError(t, err, "timed out waiting for CRD Terminating condition to be set") + // Try to create a CR using SSA. This should fail due to the CRD validation - ns := "not-the-default" + ns := testNamespace name := "foo123" noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition) - err = wait.PollUntilContextTimeout(t.Context(), 100*time.Millisecond, wait.ForeverTestTimeout, true, func(ctx context.Context) (bool, error) { - instance := fixtures.NewNoxuInstance(ns, name) - _, err := noxuResourceClient.Apply(ctx, name, instance, metav1.ApplyOptions{DryRun: []string{"All"}, FieldManager: "manager"}) - if err == nil { - t.Log("apply was not blocked, retrying...") - return false, nil - } - return true, err - }) + instance := fixtures.NewNoxuInstance(ns, name) + _, err = noxuResourceClient.Apply(t.Context(), name, instance, metav1.ApplyOptions{DryRun: []string{"All"}, FieldManager: "manager"}) wantErr := `create not allowed while custom resource definition is terminating` require.ErrorContains(t, err, wantErr) }