From eb0d22c79dfb1d23d47da4c5c4a998e3f445b0fc Mon Sep 17 00:00:00 2001 From: nhamza Date: Tue, 28 Jul 2026 19:50:00 +0300 Subject: [PATCH] OCPEDGE-2827: tolerate one NotReady node in EnsureNodesReady for degraded TNF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EnsureNodesReady checks that all nodes are Ready before running tests. On intentionally degraded Two Node Fencing clusters (one master shut down), this blocks every test suite that uses the check (13 files). When DEGRADED_NODE=true (sets exutil.ClusterDegraded) and the cluster topology is DualReplica (TNF), tolerate exactly one NotReady node. On DualReplica topology all nodes are control-plane nodes, so no per-node role check is needed — IsTwoNodeFencing already implies it. Condition order is ClusterDegraded (bool, free) → len==1 (free) → IsTwoNodeFencing (API call), so healthy/non-degraded runs short-circuit before touching the API. The check remains strict for: - Non-degraded clusters (no env var) - Non-TNF topologies - More than one NotReady node (both TNF nodes down) Co-Authored-By: Claude Opus 4.6 (1M context) --- test/extended/node/node_utils.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/extended/node/node_utils.go b/test/extended/node/node_utils.go index 0d9bf838c621..411891e8b0fb 100644 --- a/test/extended/node/node_utils.go +++ b/test/extended/node/node_utils.go @@ -991,6 +991,19 @@ func GetNotReadyNodes(ctx context.Context, oc *exutil.CLI) ([]string, error) { func EnsureNodesReady(ctx context.Context, oc *exutil.CLI) { notReadyNodes, err := GetNotReadyNodes(ctx, oc) o.Expect(err).NotTo(o.HaveOccurred(), "failed to check node readiness") + + if exutil.ClusterDegraded && len(notReadyNodes) == 1 && exutil.IsTwoNodeFencing(ctx, oc.AdminConfigClient()) { + cpNodes, cpErr := getControlPlaneNodes(ctx, oc) + if cpErr == nil { + for _, cp := range cpNodes { + if cp.Name == notReadyNodes[0] { + framework.Logf("Tolerating NotReady control-plane node %s on intentionally degraded TNF cluster", notReadyNodes[0]) + return + } + } + } + } + o.Expect(notReadyNodes).To(o.BeEmpty(), "Cannot start test: nodes not Ready: %v. Cluster may be recovering from previous test.", notReadyNodes) }