Files
mesh-controller/internal/conditions/memory_test.go
T
jochen fe857ba081
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
Switch the memory store's failure under its lock, so a test cannot race the keeper
The keeper keeps each transition from its own goroutine, which reads the memory
store's Fail field under the store's lock; tests assigned the exported field
bare, so TestAnUnreadableStoreClearsNothing failed under -race whenever the
goroutine appended in that window. The field is now set only through SetFail
(and Told's likewise), and a test makes the race certain rather than rare.
Test-only: the controller runs the bus store, never InMemory.
2026-10-09 01:25:04 +02:00

31 lines
986 B
Go

package conditions
import (
"errors"
"fmt"
"testing"
)
// **A test may take the store away while the keeper is still telling.** The keeper keeps every
// transition from a goroutine of its own, so the memory store's failure is read there while a test
// switches it: it is switched under the store's lock, or the race detector fails the suite at random
// (it once failed TestAnUnreadableStoreClearsNothing). A hundred transitions still being kept while
// the failure is switched a hundred times makes the race certain, not rare, when the lock is skipped.
func TestTheStoreIsTakenAwayWhileTheKeeperIsTelling(t *testing.T) {
k, store, told, _ := keeper(t)
ctx := t.Context()
const n = 100
for i := range n {
if _, err := k.Observe(ctx, silent(fmt.Sprintf("m%d", i))); err != nil {
t.Fatal(err)
}
}
for range n {
store.SetFail(errors.New("the bus is away"))
store.SetFail(nil)
}
told.SetFail(errors.New("no responders"))
told.SetFail(nil)
settled(t, told, n)
}