The controller ended by its unassignment (ADR 0590), so its seat, the grants seat's lease write and hand-back and placement's take-over from it serve nothing. The dependence check becomes strict (clause 5): a read of the lease, a claim, a require or the module itself is refused like any other declaration. held and artifacts-gone are the artifact sweep seat's (ADR 0571 §2). Issue 1126 B1, B2. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
91 lines
2.9 KiB
Go
91 lines
2.9 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",
|
|
}
|
|
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 := decodeForTest([]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 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)
|
|
}
|
|
}
|
|
}
|