issue 974: review 1: a verb's end, a provisioner client's word and a failed key read each ask or retry a look; the silent bucket ages; the acceptance test starts the rollout through the serving wiring
This commit is contained in:
@@ -56,10 +56,11 @@ func TestARolloutAdvancesOnEventsAndAReplacedControllerResumesIt(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(func() { _ = sub.Unsubscribe() })
|
||||
|
||||
// Every save of a plan is said and asks the look, as the serving controller's hook does.
|
||||
// Every save of a plan is kept, said and looked at by the serving controller's own hook.
|
||||
saved := &movesSaid{revs: map[string][]int64{}}
|
||||
wasSaved := inventory.PlanSaved
|
||||
inventory.PlanSaved = func(i *inventory.Inventory, p inventory.Plan) { saved.hear(i, p); planKept(p) }
|
||||
serving := servingPlanSaved(ctx, checkEvents, open)
|
||||
inventory.PlanSaved = func(i *inventory.Inventory, p inventory.Plan) { saved.hear(i, p); serving(i, p) }
|
||||
t.Cleanup(func() { inventory.PlanSaved = wasSaved })
|
||||
|
||||
// The build machine and the machines, as far as the plan meets them: an ask is counted, a send is recorded and kept.
|
||||
@@ -176,10 +177,7 @@ func TestARolloutAdvancesOnEventsAndAReplacedControllerResumesIt(t *testing.T) {
|
||||
// The first controller. Its plan has tier 0 built and tier 1 not asked: nothing but the save asks anything.
|
||||
first, stopFirst := context.WithCancel(ctx)
|
||||
defer stopFirst()
|
||||
if err := startRolloutSilent(first, js); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
startPlanLooks(first, open)
|
||||
startRolloutEvents(first, open, js)
|
||||
built := time.Now().UTC()
|
||||
p := inventory.Plan{ID: "plan-974", Repository: "novox/mesh-catalog", Branch: "main", Commit: "c2", Created: built,
|
||||
State: inventory.PlanBuilding, Tiers: [][]string{{"a"}, {"b"}},
|
||||
@@ -204,10 +202,7 @@ func TestARolloutAdvancesOnEventsAndAReplacedControllerResumesIt(t *testing.T) {
|
||||
|
||||
second, stopSecond := context.WithCancel(ctx)
|
||||
defer stopSecond()
|
||||
if err := startRolloutSilent(second, js); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
startPlanLooks(second, open)
|
||||
startRolloutEvents(second, open, js)
|
||||
// Its first look finds anchor reported, so its key goes; laptop's stays, and is the new controller's to hear expire.
|
||||
eventually(t, "the new controller's first look deletes the key of the machine that reported", func() bool {
|
||||
h := heldKeys()
|
||||
@@ -279,3 +274,72 @@ func TestARolloutAdvancesOnEventsAndAReplacedControllerResumesIt(t *testing.T) {
|
||||
// And every move of the plan was said as plan-moved.
|
||||
saved.noUnsaid(t, open)
|
||||
}
|
||||
|
||||
// Acceptance of the verb path (issue 974, review 1), live, with the store and a bus: a walk the delivery's owner lets
|
||||
// go by the verb `deliver` after the operator's approval is asked its first tier with no other event. The verb runs as a
|
||||
// child process, whose saves the serving controller does not hear; the handler asks the look as the verb ends.
|
||||
func TestAWalkLetGoByTheDeliverVerbIsAskedWithNoOtherEvent(t *testing.T) {
|
||||
open := aMesh(t)
|
||||
ctx := t.Context()
|
||||
js, err := broker.Dial(testbus.URL(t))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(js.Close)
|
||||
if err := broker.AssertMeshStreams(js); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := js.EnsureControllerBuckets(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
legacy, err := js.Conn().JetStream()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkEvents = link.OverNATS{Conn: js.Conn(), JS: legacy}
|
||||
t.Cleanup(func() { checkEvents = nil })
|
||||
asked := asksRecorded(t)
|
||||
register(t, open, catalogue.Manifest{Module: "app", Version: "1"})
|
||||
if _, err := assign(ctx, open, "anchor", "app"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cut := time.Now().UTC()
|
||||
waiting := inventory.Plan{ID: "plan-974-deliver", Repository: "novox/mesh-catalog", Branch: "main", Commit: "c8c8c8c8",
|
||||
Created: cut, State: inventory.PlanBuilding, Tiers: [][]string{{"app"}},
|
||||
Modules: map[string]*inventory.PlanModule{"app": {}},
|
||||
Delivery: &inventory.PlanDelivery{Awaits: catalogue.DeliverySeat},
|
||||
Times: &inventory.PlanTimes{Cut: &cut, Class: inventory.ClassLeaf}}
|
||||
if err := open.inventory.SavePlan(ctx, &waiting); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// The serving controller, as serve starts it.
|
||||
wasSaved := inventory.PlanSaved
|
||||
inventory.PlanSaved = servingPlanSaved(ctx, checkEvents, open)
|
||||
t.Cleanup(func() { inventory.PlanSaved = wasSaved })
|
||||
started, stop := context.WithCancel(ctx)
|
||||
defer stop()
|
||||
startRolloutEvents(started, open, js)
|
||||
time.Sleep(500 * time.Millisecond) // the first look: the walk waits, and is asked nothing
|
||||
|
||||
// The verb as its child process runs it: the delivery command, whose saves are not the serving controller's.
|
||||
wasRun := runTheVerb
|
||||
runTheVerb = func(ctx context.Context, argv []string) (verbAnswer, error) {
|
||||
was := inventory.PlanSaved
|
||||
inventory.PlanSaved = func(*inventory.Inventory, inventory.Plan) {}
|
||||
defer func() { inventory.PlanSaved = was }()
|
||||
return verbAnswer{}, deliveryCommand(ctx, []string{"go", waiting.ID, "--why", "its turn"})
|
||||
}
|
||||
t.Cleanup(func() { runTheVerb = wasRun })
|
||||
handlers, _, err := seatToolHandlers()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := handlers["deliver"](ctx, []byte(`{"plan":"`+waiting.ID+`","why":"its turn"}`)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
eventually(t, "the walk's first tier asked, with no event but the verb's end", func() bool {
|
||||
p, err := open.inventory.PlanByID(ctx, waiting.ID)
|
||||
return err == nil && p.Modules["app"] != nil && p.Modules["app"].Build != "" && len(*asked) == 1
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user