test: verify repair isolation without prolonged fixture waits
This commit is contained in:
parent
bbcf285514
commit
c73b8fe8fd
@ -1,7 +1,14 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"scm.bstein.dev/bstein/ananke/internal/cluster"
|
||||
"scm.bstein.dev/bstein/ananke/internal/execx"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -55,3 +62,28 @@ func TestDaemonMaybeRunPostStartAutoHeal(t *testing.T) {
|
||||
t.Fatalf("expected second allowed auto-heal call, got %d", calls)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDaemonRecoveryFailureDoesNotStopMonitoring exercises optional repair isolation.
|
||||
// Signature: TestDaemonRecoveryFailureDoesNotStopMonitoring(t *testing.T).
|
||||
// Why: a missing or failed repair helper must not terminate UPS monitoring.
|
||||
func TestDaemonRecoveryFailureDoesNotStopMonitoring(t *testing.T) {
|
||||
var messages bytes.Buffer
|
||||
d := &Daemon{cfg: config.Config{Startup: config.Startup{PostStartAutoHealSeconds: 60}}, log: log.New(&messages, "", 0)}
|
||||
var last time.Time
|
||||
d.maybeRunPostStartAutoHeal(context.Background(), &last, false)
|
||||
if !last.IsZero() {
|
||||
t.Fatal("missing helper must not consume an interval")
|
||||
}
|
||||
if err := d.runPostStartAutoHeal(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d.orch = cluster.New(config.Config{}, &execx.Runner{DryRun: true}, nil, d.log)
|
||||
if err := d.runPostStartAutoHeal(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d.postStartAutoHealOverride = func(context.Context) error { return errors.New("synthetic repair failure") }
|
||||
d.maybeRunPostStartAutoHeal(context.Background(), &last, false)
|
||||
if last.IsZero() || !strings.Contains(messages.String(), "synthetic repair failure") {
|
||||
t.Fatal("failed repair must be logged and rate limited")
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ func TestHookVaultLifecycleBranchMatrix(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("workload-ready-no-value-and-ensure-error", func(t *testing.T) {
|
||||
t.Run("workload-ready-no-value-and-ensure-cancel", func(t *testing.T) {
|
||||
cfg := lifecycleConfig(t)
|
||||
runNoValue := func(ctx context.Context, timeout time.Duration, name string, args ...string) (string, error) {
|
||||
command := name + " " + strings.Join(args, " ")
|
||||
@ -111,6 +111,8 @@ func TestHookVaultLifecycleBranchMatrix(t *testing.T) {
|
||||
t.Fatalf("expected no-value readiness branch, ready=%v err=%v", ready, err)
|
||||
}
|
||||
|
||||
waitCtx, cancelWait := context.WithCancel(context.Background())
|
||||
defer cancelWait()
|
||||
runEnsureErr := func(ctx context.Context, timeout time.Duration, name string, args ...string) (string, error) {
|
||||
command := name + " " + strings.Join(args, " ")
|
||||
switch {
|
||||
@ -119,14 +121,15 @@ func TestHookVaultLifecycleBranchMatrix(t *testing.T) {
|
||||
case name == "kubectl" && strings.Contains(command, "get pods -o custom-columns"):
|
||||
return "", nil
|
||||
case name == "kubectl" && strings.Contains(command, "rollout status statefulset/victoria-metrics-single-server"):
|
||||
cancelWait()
|
||||
return "", errors.New("rollout failed")
|
||||
default:
|
||||
return lifecycleDispatcher(&commandRecorder{})(ctx, timeout, name, args...)
|
||||
}
|
||||
}
|
||||
orchEnsureErr, _ := newHookOrchestratorWithRunnerMode(t, cfg, false, runEnsureErr, runEnsureErr)
|
||||
if err := orchEnsureErr.TestHookEnsureCriticalStartupWorkloads(context.Background()); err == nil || !strings.Contains(err.Error(), "rollout failed") {
|
||||
t.Fatalf("expected ensureCriticalStartupWorkloads wait error branch, got %v", err)
|
||||
if err := orchEnsureErr.TestHookEnsureCriticalStartupWorkloads(waitCtx); !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("expected ensureCriticalStartupWorkloads cancellation after failed rollout, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user