From 2e4705ebf20ee0a5ecaf6320753db81dc52c7f85 Mon Sep 17 00:00:00 2001 From: "Nelo-T. Wallus" Date: Fri, 20 Mar 2026 21:22:09 +0100 Subject: [PATCH] Prevent spurious failures due to APIBindings not being ready In CI errors related to kcp resources sometimes come up, e.g.: workspace_test.go:556: Error Trace: /home/prow/go/src/github.com/kcp-dev/kcp/test/e2e/authentication/workspace_test.go:556 Error: "the server could not find the requested resource (post workspaceauthenticationconfigurations.tenancy.kcp.io)" does not contain "claim and expression cannot both be specified" Test: TestAcceptableWorkspaceAuthenticationConfigurations/claim-and-expression The reason for this is that the fixture only waits for the workspace and underlying logical cluster to be ready. Instead the fixture now waits until all APIBindings (which are usually just the kcp APIs) are bound. Signed-off-by: Nelo-T. Wallus Signed-off-by: Nelo-T. Wallus --- .../github.com/kcp-dev/sdk/testing/workspaces.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/staging/src/github.com/kcp-dev/sdk/testing/workspaces.go b/staging/src/github.com/kcp-dev/sdk/testing/workspaces.go index 79a5d841c50..5ef799bfc79 100644 --- a/staging/src/github.com/kcp-dev/sdk/testing/workspaces.go +++ b/staging/src/github.com/kcp-dev/sdk/testing/workspaces.go @@ -34,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "github.com/kcp-dev/logicalcluster/v3" + apisv1alpha2 "github.com/kcp-dev/sdk/apis/apis/v1alpha2" "github.com/kcp-dev/sdk/apis/core" corev1alpha1 "github.com/kcp-dev/sdk/apis/core/v1alpha1" tenancyv1alpha1 "github.com/kcp-dev/sdk/apis/tenancy/v1alpha1" @@ -219,6 +220,20 @@ func NewLowLevelWorkspaceFixture[O WorkspaceOption](t TestingT, createClusterCli return true, "" }, wait.ForeverTestTimeout, time.Millisecond*100, "failed to wait for %s workspace %s to become accessible", ws.Spec.Type, parent.Join(ws.Name)) + kcptestinghelpers.Eventually(t, func() (bool, string) { + apibindings, err := clusterClient.Cluster(logicalcluster.NewPath(ws.Spec.Cluster)).ApisV1alpha2().APIBindings().List(t.Context(), metav1.ListOptions{}) + if err != nil { + return false, fmt.Sprintf("error getting APIBindings from workspace %s", parent.Join(ws.Name)) + } + + for _, apibinding := range apibindings.Items { + if apibinding.Status.Phase != apisv1alpha2.APIBindingPhaseBound { + return false, fmt.Sprintf("APIBinding %s is in phase %s", apibinding.Name, apibinding.Status.Phase) + } + } + return true, "" + }, workspaceInitTimeout, time.Millisecond*100, "failed to wait for %s workspace %s APIBindings to become ready", ws.Spec.Type, parent.Join(ws.Name)) + t.Logf("Created %s workspace %s as /clusters/%s on shard %q", ws.Spec.Type, parent.Join(ws.Name), ws.Spec.Cluster, WorkspaceShardOrDie(t, clusterClient, ws).Name) return ws }