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
85 lines
3.7 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|