Files
felhom-controller/controller/internal/backup/d28_unhealthy_hold_test.go
T

51 lines
1.9 KiB
Go

package backup
import (
"io"
"log"
"strings"
"testing"
"time"
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
)
// Decision 28: the stop is a hold (same store — no start path revives it), Start lifts ONLY that kind,
// and a second stop within 24 h says support is informed.
func TestD28_HoldTripsAndLift(t *testing.T) {
sett := slice4Settings(t)
m := &Manager{logger: log.New(io.Discard, "", 0), settings: sett}
t0 := time.Date(2026, 9, 24, 22, 0, 0, 0, time.UTC)
trip, err := m.HoldUnhealthy("gokapi", "crash_loop", t0)
if err != nil || trip != 1 {
t.Fatalf("trip=%d err=%v", trip, err)
}
held, why := m.RestoreHoldForLang("gokapi", "hu")
if !held || !strings.Contains(why, "Indítás gombbal") || strings.Contains(why, "gyfélszolgálat") {
t.Fatalf("first stop: held=%v %q", held, why)
}
if !m.UpdateHeldStacks()["gokapi"] {
t.Fatal("an unhealthy stop is a product stop — it must be in the app-down suppression set")
}
if m.HoldKind("gokapi") != settings.HoldReasonUnhealthyStop || !m.LiftUnhealthyStop("gokapi") {
t.Fatal("Start could not lift the unhealthy stop")
}
if held, _ := m.RestoreHoldFor("gokapi"); held {
t.Fatal("still held after Start")
}
trip, _ = m.HoldUnhealthy("gokapi", "oom_storm", t0.Add(3*time.Hour))
_, why = m.RestoreHoldForLang("gokapi", "en")
if trip != 2 || !strings.Contains(why, "support has been told") {
t.Fatalf("second stop within 24 h: trip=%d %q", trip, why)
}
m.LiftUnhealthyStop("gokapi")
if trip, _ = m.HoldUnhealthy("gokapi", "crash_loop", t0.Add(30*time.Hour)); trip != 1 {
t.Fatalf("a stop 27 h after the last is a first stop again, got trip %d", trip)
}
// Start never lifts another kind.
_ = sett.SetRestoreHold(settings.RestoreHold{Stack: "nextcloud", At: t0.Format(time.RFC3339), Reason: settings.HoldReasonUpdateFailed})
if m.LiftUnhealthyStop("nextcloud") {
t.Fatal("Start lifted an UPDATE hold")
}
}