mesh-config: the whole test waits on the module's views subscriptions, never a second's sleep

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 17:05:55 +01:00
parent 70fd02e8da
commit 3b01711e1f
@@ -38,6 +38,7 @@ import (
"git.novox.be/novox/mesh-sdk/go/health"
"git.novox.be/novox/mesh-sdk/go/process"
"git.novox.be/novox/mesh-sdk/go/testbus"
"git.novox.be/novox/mesh-sdk/go/views"
)
type wire struct {
@@ -506,6 +507,22 @@ func (p *player) get(state, key string) ([]byte, bool) {
return e.Value(), true
}
// hearsTheViews waits until the module subscribed to every owner's views family it follows: a change said before that
// would reach it only as a gap. Waited on, never slept for.
func (p *player) hearsTheViews() {
p.t.Helper()
eventually(p.t, "the module subscribed to every views family it follows", func() bool {
p.mu.Lock()
defer p.mu.Unlock()
for _, f := range followed {
if !slices.Contains(p.subs, f.Owner+"."+views.EventName(f.State)) {
return false
}
}
return true
})
}
// viewsReady waits until every first view of the module is answered (config_first_views).
func (p *player) viewsReady() {
p.t.Helper()
@@ -664,7 +681,7 @@ func TestConfigWholeRenamesAndRetiresAgainstTheBus(t *testing.T) {
if _, err := p.call(ResyncTool, nil); err != nil {
t.Fatal(err)
}
time.Sleep(time.Second) // the watches start after the first call
p.hearsTheViews()
set := func(module, key string, value any) {
t.Helper()
if _, err := p.call(Seat+"."+Verb, map[string]any{"action": "set", "module": module, "node": "g14", "key": key,
@@ -710,17 +727,15 @@ func TestConfigWholeRenamesAndRetiresAgainstTheBus(t *testing.T) {
// The module restarted inside the window keeps it, and says renamed no more.
said := p.publishedCount(EventRenamed)
cancelOld := p.ctx
_ = cancelOld
p2 := start(t, bin, js, router, haves, nil)
p2.viewsReady()
if _, err := p2.call(ResyncTool, nil); err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
if v, ok := resolvedValue(p2, "g14", "player", "volume"); !ok || v != "8" {
t.Errorf("after the restart the old name answers %q (%v), want 8", v, ok)
}
eventually(t, "after the restart the old name answers 8", func() bool {
v, ok := resolvedValue(p2, "g14", "player", "volume")
return ok && v == "8"
})
if n := p2.publishedCount(EventRenamed); n != 0 || said != 1 {
t.Errorf("renamed was said %d times before the restart and %d after", said, n)
}