Check the tool runtime's own code before it merges, every test on a bus of its own (hq ADR 0237)

A merge-check.sh, the repository's layer of the mesh's merge check (mesh/repo-check):
format, vet, and node-tools' suite under the race detector. The tests shared one bus and
had to run one package at a time; like the controller's (#97), each now starts a server
of its own at the release go.mod pins, held to the catalogue's bus image by a test. What
cannot run in the check — bundles that need @novox/mesh-sdk — is said as not tested.
This commit is contained in:
jochen
2026-10-06 22:04:46 +02:00
parent c2a0683115
commit 14bff5dfd7
5 changed files with 180 additions and 7 deletions
+44 -7
View File
@@ -1,9 +1,13 @@
// Package meshtest raises what the controller would, for tests against a real bus: the ASSIGNMENTS
// and EVENTS streams, memberships issued by hand, and a fixture's path.
//
// **The packages share one bus, so run them one at a time: `go test -p 1 ./...`.** Each test raises
// the streams afresh, and the console discovers every runtime that announces itself on the bus
// (novox/hq ADR 0197) — a runtime from another package's test is, correctly, found.
// **Every test has a bus of its own** (novox/hq ADR 0237, the controller's internal/testbus): a server
// linked in at the release go.mod pins — the release the mesh runs, held so by a test beside this one —
// started for the one test and gone after it. The packages shared one bus and had to run one at a time:
// each test raised the streams afresh, and the console discovers every runtime that announces itself on
// the bus (ADR 0197), so a runtime from another package's test was, correctly, found. Now the suite runs
// as Go runs it, in parallel and under the race detector. A person may still point a run at a bus of
// their own with MESH_TEST_NATS_EXTERNAL=1 and MESH_TEST_NATS; then the run is theirs to serialise.
package meshtest
import (
@@ -12,24 +16,57 @@ import (
"path/filepath"
"runtime"
"strings"
"sync"
"testing"
"time"
"github.com/nats-io/nats-server/v2/server"
"github.com/nats-io/nats.go"
"github.com/novox/mesh-tools/node-tools/internal/bus"
)
// URL is the test bus, or the test is skipped.
// 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.T) string {
t.Helper()
url := os.Getenv("MESH_TEST_NATS")
if url == "" {
t.Skip("MESH_TEST_NATS unset")
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)
}
opts := &server.Options{Host: "127.0.0.1", Port: server.RANDOM_PORT, JetStream: true, StoreDir: t.TempDir(),
NoLog: true, NoSigs: true}
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")
}
url := s.ClientURL()
buses.Store(t, url)
t.Cleanup(func() {
buses.Delete(t)
s.Shutdown()
s.WaitForShutdown()
})
return url
}
// buses are the running tests' buses, by test.
var buses sync.Map
// Mesh is the controller's job, done by hand.
type Mesh struct {
nc *nats.Conn