7cba0bfca7
gates / gates (push) Successful in 26s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
39 lines
1.3 KiB
Go
39 lines
1.3 KiB
Go
package settings
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// R-704 (v0.278.0) — ClearUpdateHold clears the holds that belong to an INSTALL (update, crash-loop stop) and
|
|
// never a restore hold (R-379), which stays operator-cleared.
|
|
// COMPANION RED-PROOF: the pre-fix predicate (`h.Reason != HoldReasonUpdateFailed`) → the crash-loop case fails.
|
|
func TestR704_ClearUpdateHoldClearsTheInstallsHoldsOnly(t *testing.T) {
|
|
s, err := Load(filepath.Join(t.TempDir(), "settings.json"), log.New(io.Discard, "", 0))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, c := range []struct {
|
|
reason string
|
|
want bool
|
|
}{{HoldReasonUpdateFailed, true}, {HoldReasonUnhealthyStop, true}, {HoldReasonRestoreFailed, false}} {
|
|
if err := s.SetRestoreHold(RestoreHold{Stack: "app", At: "2026-09-13T19:56:32Z", Reason: c.reason}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cleared, err := s.ClearUpdateHold("app")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, still := s.GetRestoreHold("app")
|
|
if cleared != c.want || still == c.want {
|
|
t.Fatalf("reason %q: cleared=%v still-held=%v, want cleared=%v", c.reason, cleared, still, c.want)
|
|
}
|
|
_, _ = s.ClearRestoreHold("app")
|
|
}
|
|
if cleared, _ := s.ClearUpdateHold("none"); cleared {
|
|
t.Fatal("clearing an app with no hold reported a clear")
|
|
}
|
|
}
|