Files
mesh-catalog/modules/mesh-build-node/cmd/mesh-build-node/announce_integration_test.go
T
jschoubben 075b61901c mesh-build-node: announce the states it keeps from its code, so readers are granted from its word (issue 1790, ADR 0495 §2 §5)
Kept (toolchains, keys, steps, each read by another module today) is said with stdio.Keeps
before the module serves; announcetest.Check holds the announcement equal to the code. The
module is pinned to mesh-sdk feat/r4e-sdk 9cb4d59.
2026-10-22 18:08:06 +02:00

64 lines
1.9 KiB
Go

//go:build integration
package main
import (
"bufio"
"encoding/json"
"io"
"testing"
"github.com/nats-io/nats.go"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/announcetest"
)
// 1790 (ADR 0495 §5): served as the runtime serves it, the module announces on the bus every state it keeps, as its
// code declares them. The runtime's part, publishing what the bundle asks to publish, is played by relay.
func TestTheModuleAnnouncesEveryStateItKeeps(t *testing.T) {
const module = "mesh-build-node"
announcetest.Check(t, module, Kept, func(url string) func() {
t.Setenv("MESH_MODULE", module)
t.Setenv("MESH_NODE", "shanks")
nc, err := nats.Connect(url)
if err != nil {
t.Fatal(err)
}
if err := keepStates(); err != nil {
t.Fatal(err)
}
inR, inW := io.Pipe()
outR, outW := io.Pipe()
go func() { _ = stdio.ServeOn(module, nil, inR, outW) }()
go relay(t, module, nc, outR, inW)
return func() { _ = inW.Close(); _ = outW.Close(); nc.Close() }
})
}
// relay is the runtime's side of the channel: each mesh/publish the bundle asks is published on its module's event
// subject, mesh.mod.<module>.event.<key>, and answered.
func relay(t *testing.T, module string, nc *nats.Conn, from io.Reader, to io.Writer) {
sc := bufio.NewScanner(from)
sc.Buffer(make([]byte, 1<<20), 1<<24)
enc := json.NewEncoder(to)
for sc.Scan() {
var m struct {
ID json.RawMessage `json:"id"`
Method string `json:"method"`
Params struct {
Key string `json:"key"`
Body json.RawMessage `json:"body"`
} `json:"params"`
}
if json.Unmarshal(sc.Bytes(), &m) != nil || m.Method != "mesh/publish" {
continue
}
if err := nc.Publish("mesh.mod."+module+".event."+m.Params.Key, m.Params.Body); err != nil {
t.Errorf("publishing %s: %v", m.Params.Key, err)
}
_ = nc.Flush()
_ = enc.Encode(map[string]any{"id": m.ID, "result": map[string]any{}})
}
}