Files
mesh-controller/internal/testbus/testbus.go
T
jschoubben 09aa063a13
mesh/merge-gate out of date: judged against trunk 5be1cfaed19b, the trunk is now f10fbda1f619; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk 5be1cfaed19b, the trunk is now f10fbda1f619; judged again on a recheck or when it is merged
mesh/delivery delivered
Measure a declaration against the bus's largest message, raise a condition near it, and send the vault's export compact (issue 1689)
A declaration is one bus message and the control node's passed the limit by 2 KB. The size is checked at every send
against the connection's own limit, with a condition from 90% and a message naming size and limit when over; the
export, 138 KB compact of 165 KB indented, is sent compact.
2026-10-21 13:54:11 +02:00

82 lines
3.3 KiB
Go

// Package testbus is the bus a test runs against: a server of its own, of the release the mesh runs,
// started for the one test and gone after it.
//
// **Why one per test.** The live tests reached one shared bus, and on it they assert, read and remove the
// mesh's own objects — streams and consumers with fixed names, because those names are the mesh's. Two
// packages at once was one deleting a consumer the other was reading through, and a test left a stream
// behind for the next to trip on: the suite passed one package at a time and failed or hung run as Go
// runs it, which taught everybody to read a red suite as noise. A server per test makes every test start
// from nothing and leave nothing, so the suite is the same run in any order, at any parallelism, under
// the race detector, on a workstation or on the build seat.
//
// **Why this release.** The server is linked in at the version go.mod pins, and a test beside this one
// holds that pin to the release the mesh runs — the catalogue's bus image, and the facts snapshot's when
// a merge check has one (novox/hq ADR 0227 rule 9: a version the mesh runs is the one its tests run).
// A bus the 2.10 line skipped messages on (issue 266) would have been caught by the tests that ran on it,
// had they run on it.
//
// A person may still point a run at a bus of their own — another release, a lab's — with
// MESH_TEST_NATS_EXTERNAL=1 and MESH_TEST_NATS; then the run is theirs to serialise.
package testbus
import (
"os"
"sync"
"testing"
"time"
"github.com/nats-io/nats-server/v2/server"
)
// Version is the release of the server the tests run.
const Version = server.VERSION
// URL is the bus of this test alone: started at its first ask, the same one at every ask after — a
// test that dials twice, or hands the address to the code it tests, reaches one bus — and shut down
// when the test ends.
func URL(t testing.TB) string {
t.Helper()
if os.Getenv("MESH_TEST_NATS_EXTERNAL") == "1" {
if url := os.Getenv("MESH_TEST_NATS"); url != "" {
return url
}
t.Fatal("MESH_TEST_NATS_EXTERNAL=1 and MESH_TEST_NATS names no bus")
}
if url, ok := buses.Load(t); ok {
return url.(string)
}
url := Start(t).ClientURL()
buses.Store(t, url)
t.Cleanup(func() { buses.Delete(t) })
return url
}
// buses are the running tests' buses, by test.
var buses sync.Map
// Start is a server with JetStream, for this test alone: on loopback, on a port the system chooses, its
// store in the test's own directory.
func Start(t testing.TB) *server.Server { return StartWithMaxPayload(t, 0) }
// StartWithMaxPayload is Start with the largest message the server takes set to maxPayload bytes; zero keeps the
// server's default (1 MiB, as the mesh's bus has).
func StartWithMaxPayload(t testing.TB, maxPayload int32) *server.Server {
t.Helper()
opts := &server.Options{Host: "127.0.0.1", Port: server.RANDOM_PORT, JetStream: true, StoreDir: t.TempDir(),
NoLog: true, NoSigs: true, MaxPayload: maxPayload}
s, err := server.NewServer(opts)
if err != nil {
t.Fatalf("a bus for this test could not be made: %v", err)
}
go s.Start()
if !s.ReadyForConnections(30 * time.Second) {
s.Shutdown()
t.Fatal("a bus for this test did not come up within 30s")
}
t.Cleanup(func() {
s.Shutdown()
s.WaitForShutdown()
})
return s
}