From 5097073ccfa540a332b05484a809ecdf91f436ca Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Wed, 7 Jan 2026 14:26:28 +0000 Subject: [PATCH 1/5] UPSTREAM: : add service account to curl job --- .../tests-extension/test/olmv1-catalog.go | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/openshift/tests-extension/test/olmv1-catalog.go b/openshift/tests-extension/test/olmv1-catalog.go index cba96594b..66e616e37 100644 --- a/openshift/tests-extension/test/olmv1-catalog.go +++ b/openshift/tests-extension/test/olmv1-catalog.go @@ -11,6 +11,7 @@ import ( batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -77,7 +78,7 @@ func verifyCatalogEndpoint(ctx SpecContext, catalog, endpoint, query string) { strings.ReplaceAll(endpoint, "?", ""), strings.ReplaceAll(catalog, "-", "")) - job := buildCurlJob(jobNamePrefix, "default", serviceURL) + job := buildCurlJob(ctx, jobNamePrefix, "default", serviceURL) err = k8sClient.Create(ctx, job) Expect(err).NotTo(HaveOccurred(), "failed to create Job") @@ -228,7 +229,29 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 }) }) -func buildCurlJob(prefix, namespace, url string) *batchv1.Job { +func buildCurlJob(ctx SpecContext, prefix, namespace, url string) *batchv1.Job { + // create service account object + serviceAccount := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: prefix, + Namespace: namespace, + }, + } + + serviceAccount.SetName(prefix) + serviceAccount.SetNamespace(namespace) + + k8sClient := env.Get().K8sClient + + err := k8sClient.Create(ctx, serviceAccount) + if err != nil && !apierrors.IsAlreadyExists(err) { + Fail(fmt.Sprintf("Failed to ensure ServiceAccount %s: %v", prefix, err)) + } + + DeferCleanup(func(ctx SpecContext) { + _ = k8sClient.Delete(ctx, serviceAccount) + }) + backoff := int32(1) // This means the k8s garbage collector will automatically delete the job 5 minutes // after it has completed or failed. @@ -257,7 +280,8 @@ func buildCurlJob(prefix, namespace, url string) *batchv1.Job { BackoffLimit: &backoff, Template: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: serviceAccount.Name, + RestartPolicy: corev1.RestartPolicyNever, Containers: []corev1.Container{{ Name: "api-tester", Image: "registry.redhat.io/rhel8/httpd-24:latest", From b297ef77d9932b351923fa3c027f7be6775cdea1 Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Thu, 8 Jan 2026 12:41:41 +0000 Subject: [PATCH 2/5] UPSTREAM: : move sa creation out of buildCurlJob() --- .../tests-extension/test/olmv1-catalog.go | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/openshift/tests-extension/test/olmv1-catalog.go b/openshift/tests-extension/test/olmv1-catalog.go index 66e616e37..b0cd7d526 100644 --- a/openshift/tests-extension/test/olmv1-catalog.go +++ b/openshift/tests-extension/test/olmv1-catalog.go @@ -78,12 +78,30 @@ func verifyCatalogEndpoint(ctx SpecContext, catalog, endpoint, query string) { strings.ReplaceAll(endpoint, "?", ""), strings.ReplaceAll(catalog, "-", "")) - job := buildCurlJob(ctx, jobNamePrefix, "default", serviceURL) + // create service account object + serviceAccount := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: jobNamePrefix, + Namespace: "default", + }, + } + + serviceAccount.SetName(jobNamePrefix) + serviceAccount.SetNamespace("default") + + err = k8sClient.Create(ctx, serviceAccount) + + if err != nil && !apierrors.IsAlreadyExists(err) { + Fail(fmt.Sprintf("Failed to ensure ServiceAccount %s: %v", jobNamePrefix, err)) + } + + job := buildCurlJob(jobNamePrefix, "default", serviceURL, serviceAccount) err = k8sClient.Create(ctx, job) Expect(err).NotTo(HaveOccurred(), "failed to create Job") DeferCleanup(func(ctx SpecContext) { _ = k8sClient.Delete(ctx, job) + _ = k8sClient.Delete(ctx, serviceAccount) }) By("Waiting for Job to succeed") @@ -229,29 +247,7 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 }) }) -func buildCurlJob(ctx SpecContext, prefix, namespace, url string) *batchv1.Job { - // create service account object - serviceAccount := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: prefix, - Namespace: namespace, - }, - } - - serviceAccount.SetName(prefix) - serviceAccount.SetNamespace(namespace) - - k8sClient := env.Get().K8sClient - - err := k8sClient.Create(ctx, serviceAccount) - if err != nil && !apierrors.IsAlreadyExists(err) { - Fail(fmt.Sprintf("Failed to ensure ServiceAccount %s: %v", prefix, err)) - } - - DeferCleanup(func(ctx SpecContext) { - _ = k8sClient.Delete(ctx, serviceAccount) - }) - +func buildCurlJob(prefix, namespace, url string, serviceAccount *corev1.ServiceAccount) *batchv1.Job { backoff := int32(1) // This means the k8s garbage collector will automatically delete the job 5 minutes // after it has completed or failed. From e596858f1321c694c64a788b5b85e68675b4fa3a Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Fri, 9 Jan 2026 09:51:37 +0000 Subject: [PATCH 3/5] UPSTREAM: : comment out delete service account --- openshift/tests-extension/test/olmv1-catalog.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openshift/tests-extension/test/olmv1-catalog.go b/openshift/tests-extension/test/olmv1-catalog.go index b0cd7d526..be10b3b67 100644 --- a/openshift/tests-extension/test/olmv1-catalog.go +++ b/openshift/tests-extension/test/olmv1-catalog.go @@ -101,7 +101,7 @@ func verifyCatalogEndpoint(ctx SpecContext, catalog, endpoint, query string) { DeferCleanup(func(ctx SpecContext) { _ = k8sClient.Delete(ctx, job) - _ = k8sClient.Delete(ctx, serviceAccount) + // _ = k8sClient.Delete(ctx, serviceAccount) }) By("Waiting for Job to succeed") From 5d0731f431a6399a94819ad28bd3c6344cb4b6aa Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Fri, 9 Jan 2026 14:44:02 +0000 Subject: [PATCH 4/5] UPSTREAM: : move defercleanup for sa for LIFO --- openshift/tests-extension/test/olmv1-catalog.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openshift/tests-extension/test/olmv1-catalog.go b/openshift/tests-extension/test/olmv1-catalog.go index be10b3b67..0f7c124b2 100644 --- a/openshift/tests-extension/test/olmv1-catalog.go +++ b/openshift/tests-extension/test/olmv1-catalog.go @@ -90,6 +90,11 @@ func verifyCatalogEndpoint(ctx SpecContext, catalog, endpoint, query string) { serviceAccount.SetNamespace("default") err = k8sClient.Create(ctx, serviceAccount) + Expect(err).NotTo(HaveOccurred(), "failed to create Service Account") + + DeferCleanup(func(ctx SpecContext) { + _ = k8sClient.Delete(ctx, serviceAccount) + }) if err != nil && !apierrors.IsAlreadyExists(err) { Fail(fmt.Sprintf("Failed to ensure ServiceAccount %s: %v", jobNamePrefix, err)) @@ -101,7 +106,6 @@ func verifyCatalogEndpoint(ctx SpecContext, catalog, endpoint, query string) { DeferCleanup(func(ctx SpecContext) { _ = k8sClient.Delete(ctx, job) - // _ = k8sClient.Delete(ctx, serviceAccount) }) By("Waiting for Job to succeed") From 47e70722b5e702e31b987b434231a5c07fb8b39b Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Mon, 12 Jan 2026 13:19:43 +0000 Subject: [PATCH 5/5] UPSTREAM: : add polling so job fully deleted before proceed --- openshift/tests-extension/test/olmv1-catalog.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openshift/tests-extension/test/olmv1-catalog.go b/openshift/tests-extension/test/olmv1-catalog.go index 0f7c124b2..ee1a0cb46 100644 --- a/openshift/tests-extension/test/olmv1-catalog.go +++ b/openshift/tests-extension/test/olmv1-catalog.go @@ -105,7 +105,15 @@ func verifyCatalogEndpoint(ctx SpecContext, catalog, endpoint, query string) { Expect(err).NotTo(HaveOccurred(), "failed to create Job") DeferCleanup(func(ctx SpecContext) { + By("Deleting Job and waiting for pods to terminate") _ = k8sClient.Delete(ctx, job) + + // Wait for Job to be fully deleted. + Eventually(func() bool { + checkJob := &batchv1.Job{} + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(job), checkJob) + return apierrors.IsNotFound(err) + }).WithTimeout(helpers.DefaultTimeout).WithPolling(helpers.DefaultPolling).Should(BeTrue()) }) By("Waiting for Job to succeed")