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 covered: a later merge that contains it was delivered: novox/mesh-controller@4291fee68e95 (merged as a5a132ac into main, walk plan-17913907…
mesh/delivery-group group feat/health-the-field delivered: every member is delivered
A module could say nothing about what ready means for what it runs, so a web application with its port open and its requests hanging passed everything for eleven hours (issue 145). A long-running resource now carries `health` — the image's own check adopted by name, http, tcp, exec, unit or a module's own tool, with its timing — refused near its author when it names a port or an address, an endpoint the module does not declare, a tool it does not serve, a tool check alone, or a timing outside the record's bounds. It is composed with the endpoint as the port this machine published it on, and sent only to a node-engine whose statement says it reads it: an older one would refuse the whole declaration. The engine is granted its own machine's instance of each health tool. `module check` warns of every long-running resource without `health`, counts them for the catalogue, and refuses them from 2026-11-18. A check's findings stay out of a condition's summary. The node-engine's validator is vendored at its Phase B commit, so what is composed is judged by the words the engine takes.
66 lines
2.2 KiB
Go
66 lines
2.2 KiB
Go
package broker
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
)
|
|
|
|
// Every machine's node-engine may ask its own node tools PING; the one running the controller may read
|
|
// the lease's key, and nothing else of the bucket (novox/hq ADR 0236).
|
|
func TestTheWitnessIsGrantedWhatItReadsAndNoMore(t *testing.T) {
|
|
users, err := Users(Records{Nodes: []string{"control", "edge"},
|
|
Assigned: map[string][]Declared{"control": {{Module: "mesh-controller"}}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
lease := "$JS.API.DIRECT.GET.KV_mesh-controller_lease.$KV.mesh-controller_lease.holder"
|
|
for _, u := range users {
|
|
if u.Kind != KindNode {
|
|
continue
|
|
}
|
|
perms, err := PermissionsFor(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(perms.Publish, "$SRV.PING.node-tools."+u.Node) {
|
|
t.Errorf("%s may not ask its node tools: %v", u.Node, perms.Publish)
|
|
}
|
|
if got := slices.Contains(perms.Publish, lease); got != (u.Node == "control") {
|
|
t.Errorf("%s may read the lease: %v", u.Node, got)
|
|
}
|
|
for _, p := range perms.Publish {
|
|
if p == "$KV.mesh-controller_lease.>" || p == "$KV.mesh-controller_lease.holder" {
|
|
t.Errorf("%s may write the lease", u.Node)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// A module's health that asks one of its own tools is asked by the machine's node-engine, of the instance
|
|
// on its own machine and nowhere else (novox/hq ADR 0240, to-be 48 §3).
|
|
func TestTheEngineIsGrantedTheToolsItsModulesHealthAsks(t *testing.T) {
|
|
users, err := Users(Records{Nodes: []string{"control", "edge"},
|
|
Assigned: map[string][]Declared{"edge": {{Module: "keycloak", Checks: []string{"keycloak.keycloak_admin_health"}}}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, u := range users {
|
|
if u.Kind != KindNode {
|
|
continue
|
|
}
|
|
perms, err := PermissionsFor(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
mine := "mesh.mod.keycloak.tool.keycloak_admin_health.edge"
|
|
if got := slices.Contains(perms.Publish, mine); got != (u.Node == "edge") {
|
|
t.Errorf("%s may ask keycloak's health tool on edge: %v", u.Node, got)
|
|
}
|
|
for _, p := range perms.Publish {
|
|
if p == "mesh.mod.keycloak.tool.keycloak_admin_health" || p == "mesh.mod.keycloak.tool.>" {
|
|
t.Errorf("%s may ask the tool of any machine: %s", u.Node, p)
|
|
}
|
|
}
|
|
}
|
|
}
|