Hold what a walk's merges change on a machine it sends nothing to, and name only where it sent (ADR 0505 §2)
This commit is contained in:
@@ -89,3 +89,33 @@ func TestTheControllersOwnConditionsAreNotHeldByAWalkOfAnotherModule(t *testing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shanksDeclared is a touch as the controller says a machine whose declaration the walk's merges change and to which
|
||||
// it sends nothing (mesh-controller walk_said.go walkTouch, `declared`, ADR 0505 §2b).
|
||||
var shanksDeclared = Touch{Machine: "shanks", Modules: []string{"mesh-build-image"}, Declared: true}
|
||||
|
||||
// ADR 0505 §2b: a machine whose declaration a walk's merges change is held like a machine it sends to, and is not
|
||||
// named among the machines the walk reached.
|
||||
func TestAMachineWhoseDeclarationTheWalkChangesIsHeldAndNotNamedAsReached(t *testing.T) {
|
||||
ev, ok, err := DecodeWalk([]byte(`{"id":"plan-d","walk":"plan-d","phase":"started","budget_class":"leaf",` +
|
||||
`"bound_seconds":600,"touches":[{"machine":"novox","modules":["gitea"]},` +
|
||||
`{"machine":"shanks","modules":["mesh-build-image"],"declared":true}]}`))
|
||||
if err != nil || !ok || len(ev.Touches) != 2 || !ev.Touches[1].Declared || ev.Touches[0].Declared {
|
||||
t.Fatalf("a declared touch was not read: %+v %v %v", ev.Touches, ok, err)
|
||||
}
|
||||
h, tg, dt, c, _ := newHolder(t)
|
||||
walk(t, h, "plan-d", WalkStarted, "", c.now(), 600, novox("gitea"), shanksDeclared)
|
||||
k := cond("machine.shanks.uncomposable", Urgent, "shanks cannot get new instructions")
|
||||
k.Machine, k.Raised = "shanks", c.now()
|
||||
h.Condition(EventRaised, k)
|
||||
runFor(h, c, time.Minute)
|
||||
if !has(outcomes(h, k.Key), "held") || heard(headlineOf(k.Key), tg, dt) {
|
||||
t.Fatalf("a condition on the declared machine was not held: %v", outcomes(h, k.Key))
|
||||
}
|
||||
if got := touchWords(mergeTouches([]Touch{novox("gitea"), shanksDeclared}, nil)); got != "gitea on novox" {
|
||||
t.Fatalf("what the walk reached reads %q, want only novox", got)
|
||||
}
|
||||
if got := mergeTouches([]Touch{shanksDeclared}, []Touch{{Machine: "shanks", Modules: []string{"buildah"}}}); got[0].Declared {
|
||||
t.Fatalf("a machine the walk also sends to stayed declared: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,10 @@ func (h *Holder) settle() time.Duration {
|
||||
type Touch struct {
|
||||
Machine string `json:"machine"`
|
||||
Modules []string `json:"modules"`
|
||||
// Declared: the walk sends nothing to this machine, but its merges change the machine's declaration (an
|
||||
// assignment, a provision or a requirement added or removed, ADR 0505 §2b). Held like any touch; never named
|
||||
// among the machines the walk reached.
|
||||
Declared bool `json:"declared,omitempty"`
|
||||
}
|
||||
|
||||
// WalkEvent is a walk's start or end as the controller says it.
|
||||
@@ -229,9 +233,10 @@ func DecodeWalk(body []byte) (WalkEvent, bool, error) {
|
||||
}
|
||||
if v, ok := raw["touches"]; ok && string(v) != "null" {
|
||||
var list []struct {
|
||||
Machine string `json:"machine"`
|
||||
Node string `json:"node"`
|
||||
Modules []string `json:"modules"`
|
||||
Machine string `json:"machine"`
|
||||
Node string `json:"node"`
|
||||
Modules []string `json:"modules"`
|
||||
Declared bool `json:"declared"`
|
||||
}
|
||||
if json.Unmarshal(v, &list) != nil {
|
||||
return WalkEvent{}, false, fmt.Errorf("walk %s: touches is not a list of {machine, modules}", ev.Walk)
|
||||
@@ -242,7 +247,7 @@ func DecodeWalk(body []byte) (WalkEvent, bool, error) {
|
||||
m = t.Node
|
||||
}
|
||||
if m != "" {
|
||||
ev.Touches = append(ev.Touches, Touch{Machine: m, Modules: t.Modules})
|
||||
ev.Touches = append(ev.Touches, Touch{Machine: m, Modules: t.Modules, Declared: t.Declared})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,9 +271,11 @@ func DecodeWalk(body []byte) (WalkEvent, bool, error) {
|
||||
return ev, true, nil
|
||||
}
|
||||
|
||||
// mergeTouches is what two sayings of a walk's touches name together.
|
||||
// mergeTouches is what two sayings of a walk's touches name together. A machine is declared only while no saying
|
||||
// sends to it (ADR 0505 §2b).
|
||||
func mergeTouches(a, b []Touch) []Touch {
|
||||
by := map[string]map[string]bool{}
|
||||
sent := map[string]bool{}
|
||||
var order []string
|
||||
for _, list := range [][]Touch{a, b} {
|
||||
for _, t := range list {
|
||||
@@ -279,6 +286,9 @@ func mergeTouches(a, b []Touch) []Touch {
|
||||
for _, m := range t.Modules {
|
||||
by[t.Machine][m] = true
|
||||
}
|
||||
if !t.Declared {
|
||||
sent[t.Machine] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(order)
|
||||
@@ -289,7 +299,7 @@ func mergeTouches(a, b []Touch) []Touch {
|
||||
mods = append(mods, m)
|
||||
}
|
||||
sort.Strings(mods)
|
||||
out = append(out, Touch{Machine: machine, Modules: mods})
|
||||
out = append(out, Touch{Machine: machine, Modules: mods, Declared: !sent[machine]})
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -684,6 +694,9 @@ func touchWords(touches []Touch) string {
|
||||
mods := map[string]bool{}
|
||||
var machines []string
|
||||
for _, t := range touches {
|
||||
if t.Declared {
|
||||
continue // its declaration changed; nothing was sent to it (ADR 0505 §2b)
|
||||
}
|
||||
machines = append(machines, t.Machine)
|
||||
for _, m := range t.Modules {
|
||||
mods[m] = true
|
||||
|
||||
Reference in New Issue
Block a user