76 lines
2.8 KiB
Go
76 lines
2.8 KiB
Go
package backup
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
|
)
|
|
|
|
// R-1348: the restore_mixed hold written at START-UP after an interrupted put-back fails must reach the operator as the
|
|
// R-1340 mail. Recover runs long before the notifier exists (main.go), so the guard keeps the name and hands it over when
|
|
// SetHeldNotify is wired; a failure after that (a drive that returned at run time) goes out at once.
|
|
//
|
|
// RED-PROOF (2026-11-02): seen failing before the seam existed (build: SetHeldNotify); with the call dropped from
|
|
// holdPutBackFailed these fail on „no mail for a held app".
|
|
func TestR1348_AFailedPutBackAtStartupMailsOnceTheNotifierIsWired(t *testing.T) {
|
|
r := newR1251Rig(t)
|
|
r.putErr = errors.New("compose down: timeout")
|
|
g := r.guard()
|
|
if res := g.Recover(); res == nil || len(res.Held) != 1 {
|
|
t.Fatalf("recovery must hold the app: %+v", res)
|
|
}
|
|
var mailed []string
|
|
g.SetHeldNotify(func(stack string) { mailed = append(mailed, stack) })
|
|
if len(mailed) != 1 || mailed[0] != "immich" {
|
|
t.Fatalf("no mail for a held app: the hold from Recover must be handed over when the notifier is wired, got %v", mailed)
|
|
}
|
|
h, ok := r.sett.GetRestoreHold("immich")
|
|
if !ok || h.Reason != settings.HoldReasonRestoreMixed || h.MixedCause != settings.MixedCauseInterruptedPutBack ||
|
|
!strings.Contains(h.FailedStep, "compose down: timeout") {
|
|
t.Fatalf("the mail reads this record, and it is wrong: %+v", h)
|
|
}
|
|
g.SetHeldNotify(func(stack string) { mailed = append(mailed, "again:"+stack) })
|
|
if len(mailed) != 1 {
|
|
t.Fatalf("a held app is mailed once, not at every wiring: %v", mailed)
|
|
}
|
|
}
|
|
|
|
// A clean put-back, or one still waiting for its drive, is no failure: no mail.
|
|
func TestR1348_NoMailWithoutAFailedPutBack(t *testing.T) {
|
|
r := newR1251Rig(t)
|
|
g := r.guard()
|
|
g.Recover()
|
|
var mailed []string
|
|
g.SetHeldNotify(func(stack string) { mailed = append(mailed, stack) })
|
|
if len(mailed) != 0 {
|
|
t.Fatalf("a put-back that worked mailed: %v", mailed)
|
|
}
|
|
|
|
w := newR1251Rig(t)
|
|
w.unbind(t)
|
|
gw := w.guard()
|
|
gw.Recover()
|
|
gw.SetHeldNotify(func(stack string) { mailed = append(mailed, stack) })
|
|
if len(mailed) != 0 {
|
|
t.Fatalf("a put-back that waits for its drive has its own hold and reminder, not this mail: %v", mailed)
|
|
}
|
|
}
|
|
|
|
// After the wiring a failed put-back (the drive returned at run time: ResumePutBack) mails at once.
|
|
func TestR1348_AFailedResumeMailsAtOnce(t *testing.T) {
|
|
r := newR1251Rig(t)
|
|
r.unbind(t)
|
|
g := r.guard()
|
|
g.Recover() // waiting for its drive
|
|
var mailed []string
|
|
g.SetHeldNotify(func(stack string) { mailed = append(mailed, stack) })
|
|
r.bind(t)
|
|
r.putErr = errors.New("tar xf failed")
|
|
g.ResumePutBack("immich")
|
|
if len(mailed) != 1 || mailed[0] != "immich" {
|
|
t.Fatalf("a put-back that failed on resume must mail: %v", mailed)
|
|
}
|
|
}
|