39 lines
1.8 KiB
Go
39 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
|
)
|
|
|
|
// R-1286: demo-hp's Kimai was held by the crash-loop guard (reason unhealthy_stop, 2026-10-14) and the boot sweep, the
|
|
// start gate and `--restore-holds` all said „held after a failed restore whose rollback also failed" for 11 days.
|
|
// Each reason now says what it is and what lifts it.
|
|
// RED-PROOF: holdWhy back to the old two-way branch → the unhealthy_stop, restore_mixed and putback_pending cases fail.
|
|
func TestR1286_EveryHoldReasonSaysWhatItIs(t *testing.T) {
|
|
sett := holdTestSettings(t)
|
|
g := driveStartGate{sett: sett}
|
|
for _, tc := range []struct {
|
|
hold settings.RestoreHold
|
|
want string
|
|
}{
|
|
{settings.RestoreHold{Stack: "kimai", At: "2026-10-14T09:06:31Z", Reason: settings.HoldReasonUnhealthyStop, UnhealthyKind: "crash_loop"}, "stopped by the box for a crash loop"},
|
|
{settings.RestoreHold{Stack: "a", At: "t", Reason: settings.HoldReasonUpdateFailed}, "failed update"},
|
|
{settings.RestoreHold{Stack: "b", At: "t", Reason: settings.HoldReasonRestoreMixed}, "off-site restore failed its database replay"},
|
|
{settings.RestoreHold{Stack: "c", At: "t", Reason: settings.HoldReasonPutBackPending}, "pre-restore copy is poured back"},
|
|
{settings.RestoreHold{Stack: "d", At: "t"}, "failed restore whose rollback also failed"},
|
|
} {
|
|
if err := sett.SetRestoreHold(tc.hold); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ok, why := g.MayStart(tc.hold.Stack)
|
|
if ok || !strings.Contains(why, tc.want) {
|
|
t.Fatalf("%s (reason %q): the gate says %q, want it to contain %q", tc.hold.Stack, tc.hold.Reason, why, tc.want)
|
|
}
|
|
if tc.hold.Reason != "" && strings.Contains(why, "failed restore whose rollback also failed") {
|
|
t.Fatalf("%s: a %q hold must not read as a failed restore: %q", tc.hold.Stack, tc.hold.Reason, why)
|
|
}
|
|
}
|
|
}
|