package supervisor_test import ( "git.cin.su/m/Assistant/runtime/supervisor" "path/filepath" "testing" ) func TestLifeboatRollsBackCandidateToLastKnownGood(t *testing.T) { l := supervisor.Lifeboat{} l.Start(supervisor.Release{ID: "good", Version: "1"}) l.Record(supervisor.Observation{ReleaseID: "good", Ready: true}) l.Start(supervisor.Release{ID: "candidate", Version: "2"}) l.Record(supervisor.Observation{ReleaseID: "candidate", Ready: false}) if !l.Rollback() || l.Current.ID != "good" || l.Current.State != supervisor.ReleaseRolledBack { t.Fatalf("%#v", l) } } func TestPersistentLifeboatRestoresLastKnownGoodAfterCandidateFailure(t *testing.T) { store, err := supervisor.NewDurableStore(filepath.Join(t.TempDir(), "control", "lifeboat.json")) if err != nil { t.Fatal(err) } first := supervisor.NewPersistentLifeboat(store) if ok, err := first.Start(supervisor.Release{ID: "good", Version: "1"}); err != nil || !ok { t.Fatalf("start good: %v %v", ok, err) } if ok, err := first.Record(supervisor.Observation{ReleaseID: "good", Ready: true, ObservedAtUnixMillis: 1}); err != nil || !ok { t.Fatalf("record good: %v %v", ok, err) } if ok, err := first.Start(supervisor.Release{ID: "candidate", Version: "2"}); err != nil || !ok { t.Fatalf("start candidate: %v %v", ok, err) } if ok, err := first.Record(supervisor.Observation{ReleaseID: "candidate", Ready: false, Reason: "candidate crashed", ObservedAtUnixMillis: 2}); err != nil || !ok { t.Fatalf("record failure: %v %v", ok, err) } second := supervisor.NewPersistentLifeboat(store) if ok, err := second.Rollback(); err != nil || !ok { t.Fatalf("rollback after restart: %v %v", ok, err) } state, err := second.Snapshot() if err != nil { t.Fatal(err) } if state.Current.ID != "good" || state.Current.State != supervisor.ReleaseRolledBack || state.LastKnownGood.ID != "good" { t.Fatalf("state=%+v", state) } }