Files
mesh-controller/internal/broker/jetstream_test.go
T
jochen 1e04670052 Serve the read verbs on the serving controller's own connection, and name every connection
Each verb ran as a process that dialled the bus, so hundreds of short
connections an hour, all named mesh-controller, hid any client reconnecting
in a loop (hq issue 327). D15 now says a user whose connections keep dropping.
2026-10-08 21:08:34 +02:00

100 lines
3.0 KiB
Go

package broker
import (
"testing"
"github.com/nats-io/nats.go"
"github.com/novox/mesh-controller/internal/testbus"
)
// Against a real server, because the questions here are all "does the server accept this" —
// which a mock would answer by agreeing with whatever this file already believes.
//
// Skipped unless MESH_TEST_NATS names one, so the ordinary suite stays fast and offline:
//
// go test ./internal/broker/ -run TestAgainstARealServer (each test on a bus of its own: internal/testbus)
func TestAgainstARealServer(t *testing.T) {
url := testbus.URL(t)
js, err := Dial(url)
if err != nil {
t.Fatal(err)
}
defer js.Close()
t.Run("the mesh's own streams are accepted", func(t *testing.T) {
if err := AssertMeshStreams(js); err != nil {
t.Fatal(err)
}
})
t.Run("asserting again changes nothing and fails nothing", func(t *testing.T) {
if err := AssertMeshStreams(js); err != nil {
t.Fatalf("the second assertion failed, so the controller cannot restart: %v", err)
}
})
t.Run("a seat's work queue is accepted beside them", func(t *testing.T) {
seats := []DeclaredSeat{{Name: "telegram-sender", Accepts: []string{"send"}}}
for _, s := range SeatStreams(seats) {
if err := js.EnsureStream(s); err != nil {
t.Fatal(err)
}
}
if c := AllOverlaps(seats); len(c) != 0 {
t.Fatalf("overlaps the server would refuse: %v", c)
}
})
t.Run("a module's consumer is accepted and is idempotent", func(t *testing.T) {
c, ok := ConsumerFor(Principal{Kind: KindModule, Node: "one", Module: "audit",
Consumes: []string{"shop.order.placed", "billing.invoice.sent"}, PasswordHash: "x"})
if !ok {
t.Fatal("no consumer derived")
}
if err := js.EnsureConsumer(c); err != nil {
t.Fatal(err)
}
if err := js.EnsureConsumer(c); err != nil {
t.Fatalf("the second assertion failed: %v", err)
}
})
t.Run("a holder's worker is accepted with its queue group", func(t *testing.T) {
c, _ := HolderConsumerFor("one", "telegram",
DeclaredSeat{Name: "telegram-sender", Accepts: []string{"send"}})
if err := js.EnsureConsumer(c); err != nil {
t.Fatal(err)
}
})
}
// A connection says what it is in the server's list (novox/hq issue 327): the process's name, unless the
// caller names this one; and a lent connection's Close leaves its owner's open.
func TestAConnectionIsNamedAndALentOneIsNotClosed(t *testing.T) {
url := testbus.URL(t)
was := ConnectionName
ConnectionName = "mesh-controller verb conditions"
defer func() { ConnectionName = was }()
named, err := Dial(url)
if err != nil {
t.Fatal(err)
}
defer named.Close()
if got := named.Conn().Opts.Name; got != "mesh-controller verb conditions" {
t.Errorf("named %q", got)
}
lease, err := Dial(url, nats.Name("mesh-controller serving lease"))
if err != nil {
t.Fatal(err)
}
defer lease.Close()
if got := lease.Conn().Opts.Name; got != "mesh-controller serving lease" {
t.Errorf("a name the caller gave became %q", got)
}
Borrow(named).Close()
if !named.Conn().IsConnected() {
t.Error("closing a lent connection closed its owner's")
}
}