mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check fail: its merge-check.sh failed: --- FAIL: TestReplay336 (1.12s)
mesh/delivery superseded: a newer head of the same pull request
The condition and the plan named the verb in command-line form; the operator reaches it through the mesh MCP server, so it is written as that call. A rebuild of the same source moves nothing (issue 280), which the plan cannot know before the build, so its line says so.
79 lines
3.4 KiB
Go
79 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
// **One commit, one change plan** (novox/hq ADR 0238): the planner's reach, laid out machine by machine in
|
|
// the build plan's order, with what is not an ordinary send said — the bus step, a module that waits for a
|
|
// person, a provider whose consumers follow it.
|
|
func TestAChangePlanSaysWhatEachMachineReceives(t *testing.T) {
|
|
const catalogue_ = "http://forge.internal:20000/novox/mesh-catalog.git"
|
|
entry := func(name, path string, on ...string) inventory.Entry {
|
|
e := fromRepo(name, catalogue_, path)
|
|
e.Source.BuiltFrom = "old"
|
|
e.On = on
|
|
return e
|
|
}
|
|
nats := entry("nats", "modules/nats", "anchor")
|
|
nats.Manifest.Provides = []catalogue.Offer{{Name: "mesh-bus"}}
|
|
gitea := entry("gitea", "modules/gitea", "anchor")
|
|
held := entry("photos", "modules/photos", "anchor", "laptop")
|
|
tools := fromRepo("node-tools", "http://forge.internal:20000/novox/mesh-tools.git", "node-tools")
|
|
tools.On = []string{"anchor", "laptop"}
|
|
entries := []inventory.Entry{nats, gitea, held, tools}
|
|
edges := []inventory.Edge{{From: "node-tools", To: "nats", Kind: inventory.EdgeStandsOn}}
|
|
policy := func(module string) (inventory.Upgrade, bool) {
|
|
if module == "photos" {
|
|
return inventory.Upgrade{RollOut: false, From: "a person"}, true
|
|
}
|
|
return inventory.Upgrade{RollOut: true}, true
|
|
}
|
|
plan := func(paths ...string) link.ChangePlan {
|
|
m := link.SourceMoved{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "head", Paths: paths}
|
|
return changePlanOf("novox/mesh-catalog", "main", "head", reachOfMerge(m, entries, nil, edges), entries, policy)
|
|
}
|
|
|
|
p := plan("modules/gitea/index.ts")
|
|
if p.Summary != "builds gitea → anchor; no bus step" {
|
|
t.Errorf("one module's change reads %q", p.Summary)
|
|
}
|
|
|
|
p = plan("modules/nats/Dockerfile", "modules/photos/x.js")
|
|
if !strings.Contains(p.Summary, "needs a person's bus upgrade") || !strings.Contains(p.Summary, "2 wait(s) for a person") ||
|
|
!strings.Contains(p.Summary, "(+1 dependent(s))") {
|
|
t.Errorf("the bus and a held module read %q", p.Summary)
|
|
}
|
|
got := map[string]string{}
|
|
for _, m := range p.Machines {
|
|
got[m.Machine] = strings.Join(m.Receives, ",") + "|" + strings.Join(m.Waits, ",")
|
|
}
|
|
// The bus first, what stands on it after: the build plan's order, per machine.
|
|
if got["anchor"] != "nats,node-tools|photos" || got["laptop"] != "node-tools|photos" {
|
|
t.Errorf("the deploy plan reads %v", got)
|
|
}
|
|
text := strings.Join(p.Steps, "\n")
|
|
// Said before the merge (novox/hq issue 336): merging it holds every send to the bus's machine until a
|
|
// person runs the bus's step, and the verb that does.
|
|
for _, want := range []string{"merging this needs a person's bus upgrade", "nothing else is sent to anchor",
|
|
"mesh_call mesh-controller.bus", "the same as the one running there", "photos waits for a person",
|
|
"nats provides mesh-bus"} {
|
|
if !strings.Contains(text, want) {
|
|
t.Errorf("the steps do not say %q:\n%s", want, text)
|
|
}
|
|
}
|
|
|
|
p = plan("merge-check.sh")
|
|
if !strings.HasPrefix(p.Summary, "builds nothing") || len(p.Machines) != 0 || strings.Join(p.Unread, ",") != "merge-check.sh" {
|
|
t.Errorf("a root file's plan reads %+v", p)
|
|
}
|
|
if !strings.Contains(planText(p), "read by no module's build: merge-check.sh") {
|
|
t.Errorf("the plan's text does not say why nothing is built:\n%s", planText(p))
|
|
}
|
|
}
|