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 pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
A seat's verb names the shell commands it is the mesh's way to do, and a module says it for its own tools in its manifest; the tools verb and module list --json carry both, for the mesh MCP server's search, the agent's instructions and the guard on its shell.
120 lines
4.4 KiB
Go
120 lines
4.4 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The verbs an agent works around most say what they replace (novox/hq ADR 0245): the journal, a
|
|
// restart, a unit's status, the hosts file — each the command the agent would otherwise type over ssh.
|
|
func TestTheVerbsWorkedAroundSayWhatTheyReplace(t *testing.T) {
|
|
want := map[string]string{
|
|
ServiceManagerSeat + ".journal": "journalctl",
|
|
ServiceManagerSeat + ".restart": "systemctl restart",
|
|
ServiceManagerSeat + ".status": "systemctl status",
|
|
"node-hostname.add": "edit /etc/hosts",
|
|
ControllerSeatName + ".node": "hostnamectl",
|
|
}
|
|
for _, s := range DefaultSeats() {
|
|
for _, v := range s.Serves {
|
|
cmd, ok := want[s.Name+"."+v.Name]
|
|
if !ok {
|
|
continue
|
|
}
|
|
delete(want, s.Name+"."+v.Name)
|
|
found := false
|
|
for _, r := range v.Replaces {
|
|
found = found || r == cmd
|
|
}
|
|
if !found {
|
|
t.Errorf("%s.%s does not say it replaces %q: %v", s.Name, v.Name, cmd, v.Replaces)
|
|
}
|
|
}
|
|
}
|
|
for verb := range want {
|
|
t.Errorf("%s is not a verb of the compiled seats", verb)
|
|
}
|
|
}
|
|
|
|
// Every command a seat's verb replaces is one short line, said once — what the guard and the search match.
|
|
func TestEveryReplacedCommandIsOneShortLine(t *testing.T) {
|
|
for _, s := range DefaultSeats() {
|
|
for _, v := range s.Serves {
|
|
seen := map[string]bool{}
|
|
for _, r := range v.Replaces {
|
|
if strings.TrimSpace(r) == "" || strings.ContainsAny(r, "\n\r") || len(r) > MaxReplaced || seen[r] {
|
|
t.Errorf("%s.%s replaces %q, which is not one short line said once", s.Name, v.Name, r)
|
|
}
|
|
seen[r] = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// A verb's definition in a manifest may say what it replaces, like the mesh's own.
|
|
func TestAVerbDefinitionCarriesWhatItReplaces(t *testing.T) {
|
|
m, err := ParseManifest([]byte(`{"module":"till","version":"1","tools":["refund"],` +
|
|
`"seats":[{"name":"shop-till","serves":[{"name":"refund","replaces":["psql -c refund"]}]}],` +
|
|
`"claims":[{"name":"shop-till","scope":"mesh"}]}`))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := m.DefinesSeats[0].Serves[0].Replaces; len(got) != 1 || got[0] != "psql -c refund" {
|
|
t.Fatalf("replaces not read: %v", got)
|
|
}
|
|
}
|
|
|
|
// A module says what its own tools replace, and only for a tool it declares.
|
|
func TestAModuleSaysWhatItsOwnToolsReplace(t *testing.T) {
|
|
m, err := ParseManifest([]byte(`{"module":"docker","version":"1","tools":["docker_logs","docker_list"],` +
|
|
`"replaces":{"docker_logs":["docker logs"],"docker_list":["docker ps"]}}`))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if m.Replaces["docker_logs"][0] != "docker logs" || m.Replaces["docker_list"][0] != "docker ps" {
|
|
t.Fatalf("replaces not read: %v", m.Replaces)
|
|
}
|
|
for _, c := range []struct{ manifest, says string }{
|
|
{`{"module":"docker","version":"1","tools":["docker_logs"],"replaces":{"docker_lgos":["docker logs"]}}`,
|
|
"declares no such tool"},
|
|
{`{"module":"docker","version":"1","tools":["docker_logs"],"replaces":{"docker_logs":[]}}`, "replaces nothing"},
|
|
{`{"module":"docker","version":"1","tools":["docker_logs"],"replaces":{"docker_logs":[" "]}}`, "empty command"},
|
|
{`{"module":"docker","version":"1","tools":["docker_logs"],"replaces":{"docker_logs":["docker logs\nrm -rf /"]}}`,
|
|
"more than one line"},
|
|
{`{"module":"docker","version":"1","tools":["docker_logs"],"replaces":{"docker_logs":["docker logs","docker logs"]}}`,
|
|
"twice"},
|
|
{`{"module":"docker","version":"1","tools":["docker_logs"],"replaces":{"docker_logs":["` + strings.Repeat("x", MaxReplaced+1) + `"]}}`,
|
|
"longer than"},
|
|
} {
|
|
if _, err := ParseManifest([]byte(c.manifest)); err == nil || !strings.Contains(err.Error(), c.says) {
|
|
t.Errorf("%s: want a refusal saying %q, got %v", c.manifest, c.says, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A seat row the store seeded before `replaces` existed carries none; the working set takes the compiled
|
|
// one, so the `tools` answer says it on a mesh whose rows exist.
|
|
func TestASeededRowTakesWhatItsVerbsReplaceFromTheCompiledSeat(t *testing.T) {
|
|
was := Seats()
|
|
t.Cleanup(func() { UseSeats(was) })
|
|
var row Seat
|
|
for _, s := range DefaultSeats() {
|
|
if s.Name == ServiceManagerSeat {
|
|
row = s
|
|
}
|
|
}
|
|
stored := make([]Verb, len(row.Serves))
|
|
for i, v := range row.Serves {
|
|
v.Replaces = nil
|
|
stored[i] = v
|
|
}
|
|
row.Serves = stored
|
|
UseSeats([]Seat{row})
|
|
got, _ := SeatNamed(ServiceManagerSeat)
|
|
for _, v := range got.Serves {
|
|
if v.Name == "journal" && (len(v.Replaces) == 0 || v.Replaces[0] != "journalctl") {
|
|
t.Fatalf("the seeded journal verb says it replaces %v", v.Replaces)
|
|
}
|
|
}
|
|
}
|