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 delivered
mesh/delivery-group group withhold-login-shell-execute delivered: every member is delivered
execute runs any command as the operator account, which can become root without a person. The operator withholds it on the control-node until a call needs a person's approval (hq ADR 0268); the holder withholds it per machine through its own setting. With execute required, that holder could not hold the seat there and would be judged silent. ADR 0246's optional mark lets it hold the seat without serving the verb.
118 lines
5.0 KiB
Go
118 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
)
|
|
|
|
// The live case of 2026-10-07 (novox/hq issue 299), replayed: the node-uplink seat gained its first
|
|
// verbs, `resolvers` and `links`, both optional while its holders catch up, and the holders serve
|
|
// neither. The working set is read from the store, whose rows carry no optional mark, so the seat comes
|
|
// back through UseSeats as it does live. Its holder on every machine answers nothing for it on the bus,
|
|
// and must not be judged silent: a seat whose verbs are all optional asks no holder to answer.
|
|
func TestAHolderOfASeatWhoseVerbsAreAllOptionalIsNotSilent(t *testing.T) {
|
|
defer catalogue.UseSeats(catalogue.DefaultSeats())
|
|
var rows []catalogue.Seat
|
|
for _, s := range catalogue.DefaultSeats() {
|
|
stored := s
|
|
stored.Serves = nil
|
|
for _, v := range s.Serves {
|
|
v.Optional = false // the store never keeps the mark
|
|
stored.Serves = append(stored.Serves, v)
|
|
}
|
|
rows = append(rows, stored)
|
|
}
|
|
catalogue.UseSeats(rows)
|
|
|
|
uplink, ok := catalogue.SeatNamed("node-uplink")
|
|
if !ok || len(uplink.Serves) == 0 {
|
|
t.Fatalf("node-uplink must serve verbs for this replay: %+v", uplink)
|
|
}
|
|
for _, v := range uplink.Serves {
|
|
if !v.Optional {
|
|
t.Fatalf("node-uplink's %s is required; this replay is of a seat whose verbs are all optional", v.Name)
|
|
}
|
|
}
|
|
|
|
nodes := []string{"anchor", "home-server", "workstation", "laptop"}
|
|
heard := map[string]bool{}
|
|
var recorded []catalogue.Held
|
|
for _, n := range nodes {
|
|
heard[n] = true
|
|
recorded = append(recorded, catalogue.Held{Claim: "node-uplink", Scope: catalogue.ScopeNode, Node: n,
|
|
Module: "networkmanager"})
|
|
}
|
|
expected := holdersToHear(catalogue.SeatsWithAProtocol(), recorded, nil, heard, nil, time.Now())
|
|
if _, asked := expected["node-uplink"]; asked {
|
|
t.Fatalf("node-uplink's holders are expected to answer though every verb of the seat is optional: %v",
|
|
expected["node-uplink"])
|
|
}
|
|
// Nothing answers for the seat, as live: no silence is said about it.
|
|
for _, o := range silentHolders(expected, map[string]map[string]bool{}) {
|
|
if o.ID == "node-uplink."+o.Machine {
|
|
t.Errorf("a holder serving none of a seat's optional verbs was judged silent: %s", o.Summary)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Silence is still judged on a required verb: a seat with one required and one optional verb, held on a
|
|
// machine that is heard from, whose holder answers nothing — silent.
|
|
func TestAHolderServingNoRequiredVerbIsStillSilent(t *testing.T) {
|
|
seat := catalogue.Seat{Name: "example-seat", Scope: catalogue.ScopeNode, Serves: []catalogue.Verb{
|
|
{Name: "state"}, {Name: "later", Optional: true}}}
|
|
recorded := []catalogue.Held{{Claim: "example-seat", Scope: catalogue.ScopeNode, Node: "laptop", Module: "m"}}
|
|
expected := holdersToHear([]catalogue.Seat{seat}, recorded, nil, map[string]bool{"laptop": true}, nil, time.Now())
|
|
if !expected["example-seat"]["laptop"] {
|
|
t.Fatalf("a holder of a seat with a required verb is not expected to answer: %v", expected)
|
|
}
|
|
out := silentHolders(expected, map[string]map[string]bool{})
|
|
if len(out) != 1 || out[0].ID != "example-seat.laptop" || out[0].Token != "silent" {
|
|
t.Fatalf("a holder serving no required verb is not said to be silent: %+v", out)
|
|
}
|
|
if got := silentHolders(expected, map[string]map[string]bool{"example-seat": {"laptop": true}}); len(got) != 0 {
|
|
t.Fatalf("a holder that answers is said to be silent: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestHoldingNeedsAnAnswer(t *testing.T) {
|
|
for _, c := range []struct {
|
|
name string
|
|
serves []catalogue.Verb
|
|
want bool
|
|
}{
|
|
{"no verb", nil, false},
|
|
{"only optional verbs", []catalogue.Verb{{Name: "a", Optional: true}, {Name: "b", Optional: true}}, false},
|
|
{"a required verb among optional ones", []catalogue.Verb{{Name: "a", Optional: true}, {Name: "b"}}, true},
|
|
{"only required verbs", []catalogue.Verb{{Name: "a"}}, true},
|
|
} {
|
|
if got := holdingNeedsAnAnswer(catalogue.Seat{Name: "s", Serves: c.serves}); got != c.want {
|
|
t.Errorf("%s: holdingNeedsAnAnswer = %v, want %v", c.name, got, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The control-node withholds the login shell's `execute` (novox/hq ADR 0268): its holder there serves
|
|
// nothing on the seat, and must not be judged silent for it, as the store's rows read it back.
|
|
func TestALoginShellWithholdingExecuteIsNotSilent(t *testing.T) {
|
|
defer catalogue.UseSeats(catalogue.DefaultSeats())
|
|
var rows []catalogue.Seat
|
|
for _, s := range catalogue.DefaultSeats() {
|
|
stored := s
|
|
stored.Serves = nil
|
|
for _, v := range s.Serves {
|
|
v.Optional = false // the store never keeps the mark
|
|
stored.Serves = append(stored.Serves, v)
|
|
}
|
|
rows = append(rows, stored)
|
|
}
|
|
catalogue.UseSeats(rows)
|
|
recorded := []catalogue.Held{{Claim: catalogue.LoginShellSeat, Scope: catalogue.ScopeNode, Node: "anchor", Module: "zsh"}}
|
|
expected := holdersToHear(catalogue.SeatsWithAProtocol(), recorded, nil, map[string]bool{"anchor": true}, nil, time.Now())
|
|
if _, asked := expected[catalogue.LoginShellSeat]; asked {
|
|
t.Fatalf("the login shell's holder is expected to answer, so withholding execute would be said silent: %v",
|
|
expected[catalogue.LoginShellSeat])
|
|
}
|
|
}
|