carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package provision
2
3import (
4 "errors"
5 "testing"
6 "time"
7)
8
9func TestMoveRollbackLossRebind(t *testing.T) {
10 g := MoveGuard{ID: "mv_abcdefghijklmnopqrstuvwxyz", Incarnation: "inc"}
11 now := time.Date(2026, 9, 1, 0, 0, 0, 0, time.UTC)
12 lost := func(phase, ref string, dirty bool) *Record {
13 at := now.Add(-time.Minute)
14 return &Record{Move: &MoveState{ID: g.ID, Incarnation: g.Incarnation, State: MoveRollingBack,
15 Rollback: &MoveRollback{ID: "rb_bbbbbbbbbbbbbbbbbbbbbbbbbb", TargetPhase: phase, Dirty: dirty, LossRef: ref, LostAt: &at, SourcePhase: RbSourceWaiting}}}
16 }
17 rec := lost(RbTargetLost, "old", true)
18 if err := MoveRollbackLossRebind(g, "old", "new", now)(rec); err != nil {
19 t.Fatal(err)
20 }
21 rb := rec.Move.Rollback
22 if rb.LossRef != "new" || !rb.LostAt.Equal(now) || rb.TargetPhase != RbTargetLost || !rb.Dirty || rb.ID != "rb_bbbbbbbbbbbbbbbbbbbbbbbbbb" {
23 t.Fatalf("rollback = %+v", rb)
24 }
25 // A replay changes nothing.
26 if err := MoveRollbackLossRebind(g, "old", "new", now.Add(time.Hour))(rec); err != nil || !rb.LostAt.Equal(now) {
27 t.Fatalf("replay = %v %v", err, rb.LostAt)
28 }
29 for name, tc := range map[string]struct {
30 rec *Record
31 g MoveGuard
32 oldRef, newRef string
33 }{
34 "other old ref": {lost(RbTargetLost, "other", false), g, "old", "new"},
35 "not lost": {lost(RbTargetReleasing, "", false), g, "old", "new"},
36 "released": {lost(RbTargetReleased, "old", false), g, "old", "new"},
37 "same ref": {lost(RbTargetLost, "old", false), g, "old", "old"},
38 "empty old": {lost(RbTargetLost, "", false), g, "", "new"},
39 "other move": {lost(RbTargetLost, "old", false), MoveGuard{ID: "mv_cccccccccccccccccccccccccc", Incarnation: "inc"}, "old", "new"},
40 "other incarnate": {lost(RbTargetLost, "old", false), MoveGuard{ID: g.ID, Incarnation: "other"}, "old", "new"},
41 } {
42 before := *tc.rec.Move.Rollback
43 err := MoveRollbackLossRebind(tc.g, tc.oldRef, tc.newRef, now)(tc.rec)
44 if err == nil {
45 t.Errorf("%s accepted", name)
46 }
47 if name != "same ref" && name != "empty old" && !errors.Is(err, ErrMoveConflict) {
48 t.Errorf("%s = %v", name, err)
49 }
50 if after := *tc.rec.Move.Rollback; after.LossRef != before.LossRef || after.TargetPhase != before.TargetPhase {
51 t.Errorf("%s changed the rollback", name)
52 }
53 }
54}
55