F-tools: the runner's views consumer is proven on the real bus; the heartbeat is asked of the bus only when a bundle wants it, with no race; a seat record says when the bus wrote it; the beat test counts ticks, not sleeps

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 16:26:50 +01:00
parent 76e025dbbc
commit db3b5fe63d
9 changed files with 290 additions and 32 deletions
+26 -1
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"sync"
"sync/atomic"
"testing"
"time"
@@ -68,6 +69,13 @@ func TestAConsumerSaysItIsBoundWhileIdleAndOnceWhenTheBusEndedIt(t *testing.T) {
restore := bus.IdleHeartbeat
bus.IdleHeartbeat = 200 * time.Millisecond
t.Cleanup(func() { bus.IdleHeartbeat = restore })
ticks := make(chan struct{}, 64)
t.Cleanup(bus.SetTickHook(func() {
select {
case ticks <- struct{}{}:
default:
}
}))
mesh.Consumer(t, "anchor", "quiet", []string{"mesh.mod.alpha.event.>"}, time.Second)
c, err := bus.Connect(bus.Credential{URL: mt.URL(t), Module: "node-tools", Node: "anchor"})
if err != nil {
@@ -87,6 +95,14 @@ func TestAConsumerSaysItIsBoundWhileIdleAndOnceWhenTheBusEndedIt(t *testing.T) {
t.Fatal(err)
}
t.Cleanup(stop)
// A consume nobody asked a heartbeat of says nothing and asks the bus nothing, however many intervals pass.
var unaskedBeats atomic.Int32
unasked, err := c.ConsumeAsBeatingWhen("quiet", func(bus.Envelope) error { return nil },
func(bus.Beat) { unaskedBeats.Add(1) }, func() bool { return false })
if err != nil {
t.Fatal(err)
}
t.Cleanup(unasked)
last := func() (bus.Beat, int) {
mu.Lock()
defer mu.Unlock()
@@ -116,7 +132,13 @@ func TestAConsumerSaysItIsBoundWhileIdleAndOnceWhenTheBusEndedIt(t *testing.T) {
}
}
mu.Unlock()
time.Sleep(600 * time.Millisecond)
for n := 0; n < 3; n++ { // three more intervals pass, counted by the loop's own tick
select {
case <-ticks:
case <-time.After(10 * time.Second):
t.Fatal("the heartbeat loop handled no more intervals")
}
}
mu.Lock()
defer mu.Unlock()
after := 0
@@ -125,6 +147,9 @@ func TestAConsumerSaysItIsBoundWhileIdleAndOnceWhenTheBusEndedIt(t *testing.T) {
after++
}
}
if unaskedBeats.Load() != 0 {
t.Errorf("a consume with no heartbeat asked said %d words", unaskedBeats.Load())
}
if after != missed || missed != 1 {
t.Errorf("Missed is said once, not at every beat: %d then %d", missed, after)
}