From 47c9b61cc8b13a84d5a6dc5bceb74ff620ef7f8b Mon Sep 17 00:00:00 2001 From: Mateusz Kowalski Date: Mon, 20 Jul 2026 13:41:28 +0200 Subject: [PATCH] Fix NetworkDiagnosticsConfig serial test race condition The AfterEach handler resets network diagnostics config but does not wait for the openshift-network-diagnostics namespace to be fully recreated. After the "Should remove all network diagnostics pods when disabled" test, the namespace enters Terminating state. The next test starts immediately and cannot find diagnostics pods, polling indefinitely until the 5h job timeout is hit. Add a wait in AfterEach that ensures: 1. The namespace is Active (not Terminating) 2. network-check-source pods exist 3. network-check-target pods exist 4. NetworkDiagnosticsAvailable condition is True This prevents the race between namespace deletion/recreation and the subsequent test that depends on diagnostics pods being available. Fixes: https://issues.redhat.com/browse/OCPBUGS-99183 Signed-off-by: Mateusz Kowalski Generated-by: AI --- .../networking/network_diagnostics.go | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/test/extended/networking/network_diagnostics.go b/test/extended/networking/network_diagnostics.go index c0432feb050d..71421fe5d898 100644 --- a/test/extended/networking/network_diagnostics.go +++ b/test/extended/networking/network_diagnostics.go @@ -53,6 +53,55 @@ var _ = g.Describe("[sig-network][OCPFeatureGate:NetworkDiagnosticsConfig][Seria _, err := oc.AdminConfigClient().ConfigV1().Networks().Apply(ctx, netConfigApply, metav1.ApplyOptions{FieldManager: fieldManager, Force: true}) o.Expect(err).NotTo(o.HaveOccurred()) + + // Wait for the network diagnostics namespace to be Active and pods to be running. + // This prevents a race where the next test starts before CNO has fully recreated + // the namespace after it was deleted by a "disable diagnostics" test. + o.Eventually(func() bool { + ns, err := oc.AdminKubeClient().CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) + if err != nil { + framework.Logf("Waiting for namespace %s: %v", namespace, err) + return false + } + if ns.Status.Phase != corev1.NamespaceActive { + framework.Logf("Namespace %s is %s, waiting for Active", namespace, ns.Status.Phase) + return false + } + + srcPods, err := oc.AdminKubeClient().CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: "app=network-check-source"}) + if err != nil { + framework.Logf("Error listing source pods: %v", err) + return false + } + if len(srcPods.Items) == 0 { + framework.Logf("No network-check-source pods found yet") + return false + } + + targetPods, err := oc.AdminKubeClient().CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: "app=network-check-target"}) + if err != nil { + framework.Logf("Error listing target pods: %v", err) + return false + } + if len(targetPods.Items) == 0 { + framework.Logf("No network-check-target pods found yet") + return false + } + + cfg, err := oc.AdminConfigClient().ConfigV1().Networks().Get(ctx, clusterConfig, metav1.GetOptions{}) + if err != nil { + framework.Logf("Error getting cluster config: %v", err) + return false + } + if !meta.IsStatusConditionTrue(cfg.Status.Conditions, condition) { + framework.Logf("NetworkDiagnosticsAvailable condition is not True yet") + return false + } + + return true + }, 5*time.Minute, 5*time.Second).Should(o.BeTrue()) }) g.It("Should be enabled by default", func(ctx context.Context) {