v0.285.0 — a box keeps two controller versions (decision 56, R-745); the update clean-up's nil-stack crash (R-751)
gates / gates (push) Successful in 25s
gates / gates (push) Successful in 25s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -71,3 +71,14 @@ func ClearState(dataDir string, logger *log.Logger) {
|
||||
}
|
||||
logger.Printf("[INFO] [selfupdate] Update state cleared")
|
||||
}
|
||||
|
||||
// RecordedPrevious is the controller image the box ran before `running`, by the swap's own record (decision 56,
|
||||
// R-745): the previous_image of an update that ended on the running version. "" when the record names none — the
|
||||
// last swap failed, was to another version, or there is no record (a box set up by hand). Pinned by
|
||||
// TestRecordedPrevious in state_test.go.
|
||||
func (s *UpdateState) RecordedPrevious(running string) string {
|
||||
if s == nil || s.Status != "success" || s.TargetVersion != running || s.PreviousVersion == running {
|
||||
return ""
|
||||
}
|
||||
return s.PreviousImage
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package selfupdate
|
||||
|
||||
import "testing"
|
||||
|
||||
// decision 56 (R-745): the controller's previous image comes from the swap record only when that record is a
|
||||
// SUCCESS that ended on the running version. COMPANION RED-PROOF: drop the Status check → the failed-swap row fails.
|
||||
func TestRecordedPrevious(t *testing.T) {
|
||||
ok := &UpdateState{Status: "success", PreviousVersion: "0.284.2", PreviousImage: "r:0.284.2", TargetVersion: "0.285.0"}
|
||||
cases := []struct {
|
||||
name string
|
||||
st *UpdateState
|
||||
running string
|
||||
want string
|
||||
}{
|
||||
{"success onto the running version", ok, "0.285.0", "r:0.284.2"},
|
||||
{"no record", nil, "0.285.0", ""},
|
||||
{"the record is about another version", ok, "0.286.0", ""},
|
||||
{"a failed swap (rolled back: the box runs the 'previous')", &UpdateState{Status: "failed", PreviousVersion: "0.284.2", PreviousImage: "r:0.284.2", TargetVersion: "0.285.0"}, "0.285.0", ""},
|
||||
{"pending", &UpdateState{Status: "pending", PreviousImage: "r:0.284.2", TargetVersion: "0.285.0"}, "0.285.0", ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := c.st.RecordedPrevious(c.running); got != c.want {
|
||||
t.Errorf("%s: got %q, want %q", c.name, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user