Tests put back the package state they set, so a loaded check machine trips no leaked bound
mesh/delivery merged: source.main moved to novox/mesh-sdk@7c015b652d36
mesh/delivery-group group feat/sdk1 merged: every member is merged
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
mesh/check failed: the composition: the composer at mesh-sdk f02f142af128b336c32a7f0059c5e1606bf9b1dc did not run: failed the composer git.novox.be/no…
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:
+28
-14
@@ -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:
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user