Files
mesh-catalog/modules/nats/cmd/nats-tools/broker_test.go
T
jschoubben 6be2e91da8 CAT-N7: the seat mesh-broker's reading verbs list, show, check and orphans, and nats_history
Served by the bus module's bundle from the keeper's own state asked and the
bus's monitoring endpoint (design 25 § 12.3): each entry's template, bus
names, settings asked and held and fill against its cap; check names each
object missing or differing; orphans what no accepted manifest asks for.
nats_history reads one entry's events, in order, from the bus module's own
stream BROKER_EVENTS on the tools' credential. The manifest test now holds
every tool and reading verb the manifest names to what the bundle serves.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 12:34:59 +01:00

85 lines
3.7 KiB
Go

package main
import (
"encoding/json"
"fmt"
"strings"
"testing"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"nats-tools/internal/keeper"
)
// The seat's reading verbs and nats_history (design 25 § 12.3; CAT-N7): list and show answer every entry the keeper
// made with its settings asked and held and its fill against its cap; check names what is missing or differs; orphans
// what no manifest asks for; history one entry's events in order. Each from the keeper's own state and the bus's
// monitoring endpoint.
func TestTheSeatsReadingVerbsAnswerFromTheKeeperAndTheBus(t *testing.T) {
plan := func(local, storage, template string, options string) keeper.Plan {
e := catalogue.BusStateEntry{Name: local, Storage: storage, Template: template}
if options != "" {
_ = json.Unmarshal([]byte(options), &e.Options)
}
p, err := keeper.PlanOf("m", e)
if err != nil {
t.Fatal(err)
}
return p
}
held := map[string]keeper.Asked{"m": {Module: "m", Made: map[string]keeper.Made{
"drafts": {Plan: plan("drafts", "key-value", "state", ""), Created: true},
"log": {Plan: plan("log", "stream", "log", `{"max-mib":16}`), Created: true, Drift: "m_log: max-bytes asked 16777216, held 33554432"},
"old": {Plan: plan("old", "stream", "events", ""), Created: true, Orphaned: true},
}}}
jsz := `{"account_details":[{"stream_detail":[
{"name":"KV_m_drafts","config":{"name":"KV_m_drafts","retention":"limits","discard":"new","max_bytes":67108864,"max_msgs_per_subject":1,"max_msg_size":262144},"state":{"messages":3,"bytes":1048576}},
{"name":"m_log","config":{"name":"m_log","retention":"limits","discard":"new","max_bytes":33554432,"max_msg_size":262144},"state":{"messages":9,"bytes":9000}}]}]}`
tools := map[string]stdio.Tool{}
for _, tl := range brokerTools(func() (map[string]keeper.Asked, error) { return held, nil },
func() ([]byte, error) { return []byte(jsz), nil },
func(module, local string, limit int) ([]keeper.Event, error) {
return []keeper.Event{{Module: module, Local: local, Why: "first"}, {Module: module, Local: local, Why: "second"}}[:limit], nil
}) {
tools[tl.Name] = tl
}
for _, row := range []struct {
tool string
args map[string]any
want []string
err string
}{
{"mesh-broker.list", nil, []string{`"count":3`, `"stream":"KV_m_drafts"`, `"bytes":1048576`, `"max_bytes":67108864`, `"bucket":"m_drafts"`}, ""},
{"mesh-broker.show", map[string]any{"module": "m", "local": "log"}, []string{`"stream":"m_log"`, `"differs":"max-bytes asked 16777216, held 33554432"`, `"drift":"m_log`}, ""},
{"mesh-broker.show", map[string]any{"module": "m", "local": "none"}, nil, `made no entry "none" of "m"`},
{"mesh-broker.check", nil, []string{`"checked":2`, `"local":"log"`}, ""},
{"mesh-broker.orphans", nil, []string{`"count":1`, `"local":"old"`, `"orphaned":true`}, ""},
{"nats_history", map[string]any{"module": "m", "local": "log", "limit": float64(1)}, []string{`"why":"first"`}, ""},
{"nats_history", map[string]any{"module": "m"}, nil, "names one entry"},
} {
t.Run(fmt.Sprintf("%s %v", row.tool, row.args), func(t *testing.T) {
args := row.args
if args == nil {
args = map[string]any{}
}
out, err := tools[row.tool].Run(args)
if row.err != "" {
if err == nil || !strings.Contains(err.Error(), row.err) {
t.Fatalf("answered %v (%v): refused, naming %q", out, err, row.err)
}
return
}
raw, _ := json.Marshal(out)
for _, w := range row.want {
if !strings.Contains(string(raw), w) {
t.Errorf("%s lacks %s", raw, w)
}
}
if row.tool == "mesh-broker.check" && strings.Contains(string(raw), `"local":"drafts"`) {
t.Errorf("check names drafts, which the bus holds as asked: %s", raw)
}
})
}
}