package inventory import ( "testing" "time" ) // A walk is said started on the save that finds it live, ended on the save that finds it ended after it started, // and neither on any other save (novox/hq ADR 0308 decision 1). func TestAWalkIsSaidStartedOnceAndEndedOnce(t *testing.T) { now := time.Date(2026, 10, 12, 11, 0, 0, 0, time.UTC) cut := now.Add(-time.Second) p := Plan{ID: "plan-1", State: PlanBuilding, Tiers: [][]string{{"messenger"}}, Modules: map[string]*PlanModule{"messenger": {}}, Times: &PlanTimes{Cut: &cut, Class: ClassLeaf}} p.markWalk(now) if p.WalkSaid != WalkStarted || p.Times.Started == nil || !p.Times.Started.Equal(now) { t.Fatalf("a live walk's first save starts it: %q %+v", p.WalkSaid, p.Times) } p.State = PlanRolling p.markWalk(now.Add(time.Minute)) if p.WalkSaid != "" || !p.Times.Started.Equal(now) { t.Fatalf("a later save says nothing and keeps the start: %q %+v", p.WalkSaid, p.Times) } p.State = PlanDone p.markWalk(now.Add(2 * time.Minute)) if p.WalkSaid != WalkEnded || p.Times.Ended == nil || p.Outcome() != WalkDelivered { t.Fatalf("the save that finds it done ends it, delivered: %q %+v %q", p.WalkSaid, p.Times, p.Outcome()) } p.markWalk(now.Add(3 * time.Minute)) if p.WalkSaid != "" { t.Fatalf("an ended walk saved again says nothing: %q", p.WalkSaid) } // Retried, it walks again: a new start. p.State = PlanBuilding p.markWalk(now.Add(4 * time.Minute)) if p.WalkSaid != WalkStarted || p.Times.Ended != nil || !p.Times.Started.Equal(now.Add(4*time.Minute)) { t.Fatalf("a retried walk starts again: %q %+v", p.WalkSaid, p.Times) } } // What is never said: a batch, a walk waiting for its word, a walk that ends without having started, and a walk // kept before its times were. A release plan is said. func TestWhatIsNotAWalkStartIsNotSaid(t *testing.T) { now := time.Now() for name, p := range map[string]Plan{ "a batch": {State: PlanAssembling, Times: &PlanTimes{}}, "waiting for a word": {State: PlanBuilding, Times: &PlanTimes{}, Delivery: &PlanDelivery{Awaits: "mesh-delivery"}}, "ended, never begun": {State: PlanDone, Times: &PlanTimes{}}, "kept before times": {State: PlanBuilding}, "stopped while waits": {State: PlanFailed, Times: &PlanTimes{}, Delivery: &PlanDelivery{Awaits: "mesh-delivery", Stopped: "x"}}, } { p.markWalk(now) if p.WalkSaid != "" { t.Errorf("%s: said %q", name, p.WalkSaid) } } r := Plan{State: PlanRolling, Release: &PlanRelease{Order: []string{"ace"}}} r.markWalk(now) if r.WalkSaid != WalkStarted || r.Times == nil || r.Times.Started == nil || r.Times.Class != "" { t.Fatalf("a release plan is said started, its times holding only that: %q %+v", r.WalkSaid, r.Times) } // Let go, the walk starts. go1 := now w := Plan{State: PlanBuilding, Times: &PlanTimes{}, Delivery: &PlanDelivery{Awaits: "mesh-delivery", Go: &go1}} w.markWalk(now) if w.WalkSaid != WalkStarted { t.Fatalf("a walk let go starts: %q", w.WalkSaid) } } // An ended walk's outcome: delivered, failed, or stopped by a person or the delivery's owner, or by a newer walk. func TestAWalksOutcome(t *testing.T) { for want, p := range map[string]Plan{ WalkDelivered: {State: PlanDone}, WalkFailed: {State: PlanFailed}, WalkStopped: {State: PlanFailed, Delivery: &PlanDelivery{Stopped: "mesh-delivery"}}, "": {State: PlanRolling}, } { if got := p.Outcome(); got != want { t.Errorf("%s: outcome %q, want %q", p.State, got, want) } } if (Plan{State: PlanSuperseded}).Outcome() != WalkStopped { t.Error("a superseded walk is stopped") } } // The marks are kept with the walk, so a controller replaced mid-walk neither says its start again nor misses // its end; and a save refused leaves the walk unmarked, so the save that is made says it.