The bus module's list, show and orphans answer each held entry's binding
Held.binding is the entry's plan binding, the value its created and recreated carry, present when the bus holds the entry's objects and absent on one it does not (waiting, refused). Table rows in the reading verbs' test: the binding of a held entry equals the one its created carries; a waiting entry has none. Builds: design 25 bindings-first-view §2, §7 (hq d0760629, PR 543) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||||
|
"git.novox.be/novox/mesh-sdk/go/membership"
|
||||||
"github.com/nats-io/nats.go/jetstream"
|
"github.com/nats-io/nats.go/jetstream"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-contracts/go/seats/meshbroker"
|
"git.novox.be/novox/mesh-contracts/go/seats/meshbroker"
|
||||||
@@ -98,10 +99,27 @@ func heldOf(module, local string, m keeper.Made, held map[string]busStream) mesh
|
|||||||
}
|
}
|
||||||
if len(settings) > 0 {
|
if len(settings) > 0 {
|
||||||
h.Settings, h.Fill = settings, &fill
|
h.Settings, h.Fill = settings, &fill
|
||||||
|
// The binding the entry's created and recreated carry, from its plan (design 25 bindings-first-view §2): present on an
|
||||||
|
// entry whose objects the bus holds, absent on one it does not.
|
||||||
|
h.Binding = bindingOf(m.Plan.Binding)
|
||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bindingOf is a plan's binding in the seat's form, the one the events carry (the seat's Binding takes the fields of mesh-sdk's
|
||||||
|
// membership binding, so the same JSON is both).
|
||||||
|
func bindingOf(b membership.BusBinding) *meshbroker.Binding {
|
||||||
|
raw, err := json.Marshal(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var out meshbroker.Binding
|
||||||
|
if json.Unmarshal(raw, &out) != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &out
|
||||||
|
}
|
||||||
|
|
||||||
// differencesOf are an entry's objects the bus holds otherwise than asked, or not at all, as the seat's check answers
|
// differencesOf are an entry's objects the bus holds otherwise than asked, or not at all, as the seat's check answers
|
||||||
// them: each object's settings asked and held by stream, and whether the difference only grows (apply may act on it).
|
// them: each object's settings asked and held by stream, and whether the difference only grows (apply may act on it).
|
||||||
func differencesOf(module, local string, m keeper.Made, held map[string]busStream) (meshbroker.CheckAnswerDifferencesItem, bool) {
|
func differencesOf(module, local string, m keeper.Made, held map[string]busStream) (meshbroker.CheckAnswerDifferencesItem, bool) {
|
||||||
@@ -166,7 +184,7 @@ func brokerTools(read heldEntries, jsz func() ([]byte, error), history func(modu
|
|||||||
entryArgs := map[string]any{"module": str("the module, e.g. mesh-knowledge"), "local-name": str("its local name, e.g. records")}
|
entryArgs := map[string]any{"module": str("the module, e.g. mesh-knowledge"), "local-name": str("its local name, e.g. records")}
|
||||||
return []stdio.Tool{
|
return []stdio.Tool{
|
||||||
{Name: "mesh-broker.list",
|
{Name: "mesh-broker.list",
|
||||||
Description: "Every module's kept data on the bus that the bus module created (design 25 § 12.3): each entry's bus name, template and options as asked, the settings the bus holds of each of its objects, and its fill against its cap. Narrowed by a module.",
|
Description: "Every module's kept data on the bus that the bus module created (design 25 § 12.3): each entry's bus name, template and options as asked, the settings the bus holds of each of its objects, its fill against its cap, and its binding (the names on the bus a module receives, as created carried them) where the bus holds its objects. Narrowed by a module.",
|
||||||
Input: map[string]any{"module": str("one module")},
|
Input: map[string]any{"module": str("one module")},
|
||||||
Run: func(a map[string]any) (any, error) {
|
Run: func(a map[string]any) (any, error) {
|
||||||
entries, held, err := both()
|
entries, held, err := both()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ func TestTheSeatsReadingVerbsAnswerFromTheKeeperAndTheBus(t *testing.T) {
|
|||||||
"drafts": {Plan: plan("drafts", "key-value", "state", ""), Created: true},
|
"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"},
|
"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},
|
"old": {Plan: plan("old", "stream", "events", ""), Created: true, Orphaned: true},
|
||||||
|
"later": {Plan: plan("later", "key-value", "state", ""), Waiting: "a grant not composed yet"},
|
||||||
}}}
|
}}}
|
||||||
jsz := `{"account_details":[{"stream_detail":[
|
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":"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}},
|
||||||
@@ -52,9 +54,12 @@ func TestTheSeatsReadingVerbsAnswerFromTheKeeperAndTheBus(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
// Each answers the seat's contract (mesh-contracts meshbroker ListAnswer, Held, CheckAnswer, OrphansAnswer).
|
// Each answers the seat's contract (mesh-contracts meshbroker ListAnswer, Held, CheckAnswer, OrphansAnswer).
|
||||||
{"mesh-broker.list", nil, []string{`{"entries":[`, `"bus-name":"m_drafts"`, `"local-name":"drafts"`, `"storage-type":"key-value"`,
|
{"mesh-broker.list", nil, []string{`{"entries":[`, `"bus-name":"m_drafts"`, `"local-name":"drafts"`, `"storage-type":"key-value"`,
|
||||||
`"KV_m_drafts":{"max-bytes":67108864`, `"fill":{"bytes":1048576,"cap":67108864,"count":3}`, `"options":{"max-mib":16}`}, ""},
|
`"KV_m_drafts":{"max-bytes":67108864`, `"fill":{"bytes":1048576,"cap":67108864,"count":3}`, `"options":{"max-mib":16}`,
|
||||||
|
// The binding of an entry the bus holds is the one its created carries (design 25 bindings-first-view §2).
|
||||||
|
`"binding":{"bucket":"m_drafts","local":"drafts","storage":"key-value","template":"state"}`}, ""},
|
||||||
{"mesh-broker.show", map[string]any{"module": "m", "local-name": "log"}, []string{`"bus-name":"m_log"`, `"template":"log"`,
|
{"mesh-broker.show", map[string]any{"module": "m", "local-name": "log"}, []string{`"bus-name":"m_log"`, `"template":"log"`,
|
||||||
`"m_log":{"max-bytes":33554432`}, ""},
|
`"m_log":{"max-bytes":33554432`}, ""},
|
||||||
|
{"mesh-broker.show", map[string]any{"module": "m", "local-name": "later"}, []string{`"local-name":"later"`}, ""},
|
||||||
{"mesh-broker.show", map[string]any{"module": "m", "local-name": "none"}, nil, `made no entry "none" of "m"`},
|
{"mesh-broker.show", map[string]any{"module": "m", "local-name": "none"}, nil, `made no entry "none" of "m"`},
|
||||||
{"mesh-broker.check", nil, []string{`{"differences":[{`, `"local-name":"log"`, `"asked":{"m_log":{"max-bytes":16777216`,
|
{"mesh-broker.check", nil, []string{`{"differences":[{`, `"local-name":"log"`, `"asked":{"m_log":{"max-bytes":16777216`,
|
||||||
`"held":{"m_log":{"max-bytes":33554432`}, ""},
|
`"held":{"m_log":{"max-bytes":33554432`}, ""},
|
||||||
@@ -81,6 +86,28 @@ func TestTheSeatsReadingVerbsAnswerFromTheKeeperAndTheBus(t *testing.T) {
|
|||||||
t.Errorf("%s lacks %s", raw, w)
|
t.Errorf("%s lacks %s", raw, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// list's binding is, field by field, the binding the entry's created carries (the event's body takes the plan's binding whole).
|
||||||
|
if row.tool == "mesh-broker.list" {
|
||||||
|
var got struct {
|
||||||
|
Entries []struct {
|
||||||
|
Local string `json:"local-name"`
|
||||||
|
Binding map[string]any `json:"binding"`
|
||||||
|
} `json:"entries"`
|
||||||
|
}
|
||||||
|
var created map[string]any
|
||||||
|
wire, _ := json.Marshal(held["m"].Made["drafts"].Plan.Binding)
|
||||||
|
_ = json.Unmarshal(raw, &got)
|
||||||
|
_ = json.Unmarshal(wire, &created)
|
||||||
|
for _, e := range got.Entries {
|
||||||
|
if e.Local == "drafts" && !reflect.DeepEqual(e.Binding, created) {
|
||||||
|
t.Errorf("list names the binding %v for drafts, its created carries %v", e.Binding, created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// An entry the bus does not hold has no binding.
|
||||||
|
if row.args["local-name"] == "later" && strings.Contains(string(raw), `"binding"`) {
|
||||||
|
t.Errorf("show names a binding for later, whose objects the bus does not hold: %s", raw)
|
||||||
|
}
|
||||||
if row.tool == "mesh-broker.check" && strings.Contains(string(raw), `"local-name":"drafts"`) {
|
if row.tool == "mesh-broker.check" && strings.Contains(string(raw), `"local-name":"drafts"`) {
|
||||||
t.Errorf("check names drafts, which the bus holds as asked: %s", raw)
|
t.Errorf("check names drafts, which the bus holds as asked: %s", raw)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user