Tests put back the package state they set, so a loaded check machine trips no leaked bound
mesh/check failed: the composition: the composer at mesh-sdk f02f142af128b336c32a7f0059c5e1606bf9b1dc did not run: failed the composer git.novox.be/no…
mesh/delivery merged: source.main moved to novox/mesh-sdk@7c015b652d36
mesh/delivery-group group feat/sdk1 merged: every member is merged

The check of release sdk1 failed on TestStatePutWritesAKeyWhole: TestACallIsAskedAgainOnlyWhenItReachedNoOne
left busretry's Bound at 50 ms, and on a loaded machine the state test's first pause overran it. Second failure
of the kind "tests leave package-level state set".

Quick fix: restore busretry's waits in the one test and lengthen the state test's bound.
Thorough fix (chosen, the kind met twice): busretry.Waits sets the waits and returns their restore, used as
t.Cleanup(busretry.Waits(...)) by every test that sets them, each with a bound of seconds where it waits to
succeed; and servesAlone gives every test that serves its own runtime channel and Served, put back after it,
instead of tests clearing the channel an earlier one left. A scan of every test assignment to a package-level
variable found no other unrestored one.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 20:10:58 +01:00
parent 1c7356c247
commit f02f142af1
15 changed files with 58 additions and 22 deletions
+10
View File
@@ -29,6 +29,16 @@ var (
MostWait = 4 * time.Second
)
// Waits sets Bound, FirstWait and MostWait and returns what puts the earlier values back. They are state every caller
// in a process shares, so a test sets them only through it, as t.Cleanup(busretry.Waits(...)): a test that set them
// and left them set shortened the next test's bound to milliseconds, and a loaded check machine overran it (the check
// of release sdk1, 2026-11-02). A bound a test waits on to succeed is seconds: no slow machine reaches it.
func Waits(bound, first, most time.Duration) (restore func()) {
was := [3]time.Duration{Bound, FirstWait, MostWait}
Bound, FirstWait, MostWait = bound, first, most
return func() { Bound, FirstWait, MostWait = was[0], was[1], was[2] }
}
// Undelivered says err means the request reached no one: no responders, JetStream not enabled (for the account), or
// no response from the stream after the client's own retries on no responders; also said in words by a runtime that
// passed the error on.
+8 -2
View File
@@ -15,7 +15,6 @@ import (
// Issue 774 (bus blackouts at every user-list reload): only a request that reached no one is asked again, within the
// bound; a blackout probe that says the bus answers ends the wait at once.
func TestABusThatAnswersNothingIsWaitedOut(t *testing.T) {
Bound, FirstWait, MostWait = 60*time.Millisecond, time.Millisecond, 4*time.Millisecond
for _, row := range []struct {
name string
errs []error // what each try answers; the last repeats
@@ -30,8 +29,15 @@ func TestABusThatAnswersNothingIsWaitedOut(t *testing.T) {
{"a timeout may have been delivered: never asked again", []error{context.DeadlineExceeded}, nil, 1, 1, false},
{"an answer that refuses is an answer", []error{errors.New("refused")}, nil, 1, 1, false},
{"nobody answers on a bus that answers: the callee is not running", []error{nats.ErrNoResponders}, func() bool { return false }, 1, 1, false},
{"blacked out past the bound: said", []error{jetstream.ErrJetStreamNotEnabledForAccount}, func() bool { return true }, 3, 1000, false},
{"blacked out past the bound: said", []error{jetstream.ErrJetStreamNotEnabledForAccount}, func() bool { return true }, 2, 1000, false},
} {
// A row that ends in an answer waits on a bound of seconds, which no slow machine reaches; only the row that
// runs past it has a short one, and asks only that it was asked again at least once.
bound := 10 * time.Second
if strings.HasPrefix(row.name, "blacked out") {
bound = 100 * time.Millisecond
}
t.Cleanup(Waits(bound, time.Millisecond, 4*time.Millisecond))
tries := 0
_, err := Do("the test", func() (int, error) {
e := row.errs[min(tries, len(row.errs)-1)]
+1
View File
@@ -11,6 +11,7 @@ import (
// callWith serves one tool that answers the caller CallerOf reads from its arguments, sends it one tools/call
// with the params given, and returns the caller it answered.
func callWith(t *testing.T, params map[string]any) string {
servesAlone(t)
t.Helper()
inR, inW := io.Pipe()
outR, outW := io.Pipe()
+1
View File
@@ -34,6 +34,7 @@ func (r *emitRuntime) next() map[string]any {
}
func serveEmit(t *testing.T, tools []Tool) *emitRuntime {
servesAlone(t)
t.Helper()
t.Setenv(ServedAs, "chime")
inR, inW := io.Pipe()
+1 -4
View File
@@ -15,14 +15,11 @@ import (
// announces through the runtime once the bundle serves, as the module the runtime names; and a state of its own that it
// did not announce is refused at the call, naming it, so code and announcement cannot drift.
func TestABundleAnnouncesWhatItKeepsAndBindsNothingElse(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "chime")
t.Setenv("MESH_MODULE", "chime")
t.Setenv("MESH_NODE", "anchor")
defer forgetKeeps()
// Not yet serving: an earlier test's channel is gone with its test.
currentMu.Lock()
current = nil
currentMu.Unlock()
if err := Keeps(announce.State{Name: "rings", Readable: true}, announce.State{Name: "own"}); err != nil {
t.Fatal(err)
}
+1
View File
@@ -130,6 +130,7 @@ func (r *logRuntime) answer(m message) map[string]any {
// logging serves a bundle whose one tool, "log", runs run against r, answering each mesh/log ask beside
// the loop as the runtime does. It returns what the tool answered.
func logging(t *testing.T, r *logRuntime, run func() (any, error)) map[string]any {
servesAlone(t)
t.Helper()
t.Setenv(ServedAs, "issues")
inR, inW := io.Pipe()
+1 -1
View File
@@ -103,7 +103,7 @@ func TestCallOnRefusesANodeThatIsNotOneToken(t *testing.T) {
// The review of 2026-10-30 (issue 774): a callee's own answer is delivered, whatever its words, and is never asked
// again during a blackout; only the transport's no responders is.
func TestACallIsAskedAgainOnlyWhenItReachedNoOne(t *testing.T) {
busretry.Bound, busretry.FirstWait, busretry.MostWait = 50*time.Millisecond, time.Millisecond, 2*time.Millisecond
t.Cleanup(busretry.Waits(10*time.Second, time.Millisecond, 2*time.Millisecond))
for _, row := range []struct {
name string
answer []error // per ask; the last repeats
+1 -1
View File
@@ -208,7 +208,7 @@ func TestStatePutWritesAKeyWhole(t *testing.T) {
t.Fatalf("Get after Put: %+v, %v", e, err)
}
// Issue 774: a bus that answers nothing for a moment (a user-list reload) is waited out, not a lost write.
busretry.FirstWait = time.Millisecond
t.Cleanup(busretry.Waits(10*time.Second, time.Millisecond, 2*time.Millisecond))
kv, blackedOut := newFakeKV(), 2
dark := State{Module: "mesh-mail", Name: "sends", kv: func(context.Context) (jetstream.KeyValue, error) {
if blackedOut > 0 {
+1
View File
@@ -14,6 +14,7 @@ import (
// returns and each change after is named by the watch's id; what the module does not declare and every secret come
// back refused, in the runtime's words; a change for no watch of this bundle is refused.
func TestABundleReadsAndWatchesItsValuesThroughTheRuntime(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "claude-code")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
+1
View File
@@ -11,6 +11,7 @@ import (
// 1887/A11: a bundle pulls one message through its runtime, naming the worker and the wait, and settles it by the id the
// runtime gave.
func TestABundlePullsAndSettlesThroughTheRuntime(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "mesh-build-go")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
+1
View File
@@ -12,6 +12,7 @@ import (
// novox/hq ADR 0259 §3: a bundle takes a seat's work and answers proofs through the runtime; a piece of
// work it fails is answered as an error, so the runtime offers it again, and a proof's error is said.
func TestABundleTakesWorkAndAnswersProofsThroughTheRuntime(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "router")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
+1
View File
@@ -76,6 +76,7 @@ func (r *casRuntime) answer(m message) map[string]any {
// beside the loop, as the runtime does, so two writers' reads and writes interleave. It returns what the
// tool answered.
func counting(t *testing.T, r *casRuntime, run func() (any, error)) map[string]any {
servesAlone(t)
t.Helper()
t.Setenv(ServedAs, "issues")
inR, inW := io.Pipe()
+1
View File
@@ -13,6 +13,7 @@ import (
// historying serves a bundle whose one tool, "history", runs run, answering each mesh/state ask with
// answer beside the loop, as the runtime does; it returns what the bundle asked.
func historying(t *testing.T, answer func(message) map[string]any, run func()) []message {
servesAlone(t)
t.Helper()
t.Setenv(ServedAs, "issues")
inR, inW := io.Pipe()
+1
View File
@@ -15,6 +15,7 @@ import (
// current values are handled before it returns, its changes are named by the watch's id, a change for
// no watch of this bundle is refused, and put, get and keys are asked of the runtime as the module.
func TestABundleKeepsAndWatchesStateThroughTheRuntime(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "keeper")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
+28 -14
View File
@@ -18,16 +18,7 @@ func TestABundleEmitsThroughTheRuntimeAndServesAsItsModule(t *testing.T) {
t.Setenv("MESH_MODULE", "chime")
t.Setenv("MESH_NODE", "anchor")
// 1887/AC-wake: Served closes once Serve has the runtime's channel, not before; the globals are put back after.
oldServed := served
served, servedOnce = make(chan struct{}), sync.Once{}
t.Cleanup(func() {
served, servedOnce = oldServed, sync.Once{}
select {
case <-oldServed: // it was closed: its Once is spent too
servedOnce.Do(func() {})
default:
}
})
servesAlone(t)
select {
case <-Served():
t.Fatal("Served closed before Serve")
@@ -94,6 +85,7 @@ func TestABundleEmitsThroughTheRuntimeAndServesAsItsModule(t *testing.T) {
// A Go bundle subscribes and asks through the runtime (novox/hq ADR 0198): the event is answered only
// after the handler took it, a handler's error is answered as one, and a tool call is asked as the module.
func TestABundleSubscribesAndAsksThroughTheRuntime(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "watcher")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
@@ -172,6 +164,7 @@ func TestABundleSubscribesAndAsksThroughTheRuntime(t *testing.T) {
// A subscribe the runtime refused leaves no handler behind: asked again until the runtime takes it, a
// module's handler is handed each event once, not once per attempt (novox/hq issue 276).
func TestARefusedSubscribeLeavesNoHandlerBehind(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "plex")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
@@ -257,14 +250,11 @@ func TestARefusedSubscribeLeavesNoHandlerBehind(t *testing.T) {
// answer blocked on the pipe, a refused subscribe is still delivered to Subscribe, which returns the
// refusal — no lock of the channel is held across a write to the pipe (novox/hq issue 1286/AC1, 1286/AC2).
func TestARefusedSubscribeIsDeliveredWhileAMessageWaitsOnThePipe(t *testing.T) {
servesAlone(t)
t.Setenv(ServedAs, "plex")
inR, inW := io.Pipe()
outR, outW := io.Pipe()
defer func() { _ = inW.Close() }()
// Not the channel an earlier run left behind: Subscribe goes to the one this run serves.
currentMu.Lock()
current = nil
currentMu.Unlock()
go func() {
_ = ServeOn("", []Tool{{Name: "quick", Run: func(map[string]any) (any, error) { return "ok", nil }}}, inR, outW)
}()
@@ -303,3 +293,27 @@ func TestARefusedSubscribeIsDeliveredWhileAMessageWaitsOnThePipe(t *testing.T) {
// Let the waiting answer go, so nothing is left blocked.
go func() { _, _ = io.Copy(io.Discard, outR) }()
}
// servesAlone gives a test that serves its own serving state, put back when it ends: no runtime's channel yet and a
// Served not yet closed. ServeOn sets both for the whole process, so without it a test saw the channel and the closed
// Served an earlier test left behind (the check of release sdk1, 2026-11-02: tests leaking package state).
func servesAlone(t *testing.T) {
t.Helper()
currentMu.Lock()
oldCurrent := current
current = nil
currentMu.Unlock()
oldServed := served
served, servedOnce = make(chan struct{}), sync.Once{}
t.Cleanup(func() {
currentMu.Lock()
current = oldCurrent
currentMu.Unlock()
served, servedOnce = oldServed, sync.Once{}
select {
case <-oldServed: // it was closed: its Once is spent too
servedOnce.Do(func() {})
default:
}
})
}