From db8587f7d103bebe5ccab4176f6fd359c4218f9d Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 07:39:58 +0100 Subject: [PATCH] Align the cached fallback fixture with observed recovery Replace the old optimistic-health expectation with cached selection, failed-request and later-success controls. Advance no production clock or safety fence and avoid an irrelevant constructor attempt in the in-memory fixture. Contract-Neutral: Test-only correction to the recovery contract established in 4147f48db3; runtime and browser inputs are unchanged. Change-source: pulse-maintainer --- pkg/proxmox/cluster_client_failover_test.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/proxmox/cluster_client_failover_test.go b/pkg/proxmox/cluster_client_failover_test.go index 960e5dd9ca..51c170f6ef 100644 --- a/pkg/proxmox/cluster_client_failover_test.go +++ b/pkg/proxmox/cluster_client_failover_test.go @@ -7,15 +7,15 @@ import ( "time" ) -func TestGetHealthyClientSingleEndpointFallback(t *testing.T) { +func TestGetHealthyClientSingleEndpointFallbackKeepsObservedFailure(t *testing.T) { endpoint := "http://example.invalid" cc := &ClusterClient{ name: "single", endpoints: []string{endpoint}, clients: map[string]*Client{endpoint: {}}, nodeHealth: map[string]bool{endpoint: false}, - lastError: make(map[string]string), - lastHealthCheck: make(map[string]time.Time), + lastError: map[string]string{endpoint: "previous failed observation"}, + lastHealthCheck: map[string]time.Time{endpoint: time.Now()}, rateLimitUntil: make(map[string]time.Time), } @@ -26,8 +26,19 @@ func TestGetHealthyClientSingleEndpointFallback(t *testing.T) { if client == nil { t.Fatal("expected client, got nil") } - if !cc.nodeHealth[endpoint] { - t.Fatal("expected endpoint to be marked healthy after fallback") + if cc.nodeHealth[endpoint] || cc.lastError[endpoint] != "previous failed observation" { + t.Fatal("cached fallback selection must not erase an observed failure") + } + if err := cc.executeWithFailover(context.Background(), func(*Client) error { + return fmt.Errorf("API error 500: fixture unavailable") + }); err == nil || cc.nodeHealth[endpoint] { + t.Fatal("failed last-resort request must not establish recovery") + } + if err := cc.executeWithFailover(context.Background(), func(*Client) error { return nil }); err != nil { + t.Fatal(err) + } + if !cc.nodeHealth[endpoint] || cc.lastError[endpoint] != "" { + t.Fatal("accepted ordinary request must clear its own recorded failure") } }