test(nodes): recompute region placements when the startup load is done (#1879)

Review on #2190: the prewarm runs after FirstChunkReady, so for up to one
interval a node whose zero-hop advert is in a later chunk gets a partial
or no placement. Fails: nothing recomputes until the next tick.
This commit is contained in:
Adam Nieto committed 2026-10-15 08:24:23 -05:00
1 parent b8a8c1f81a
commit 95f2aca49e
1 file changed
+30
+30
View File
@@ -8,6 +8,7 @@ import (
"reflect"
"sort"
"testing"
"time"
)
// #1879: the region filter put a node in every region where any observer heard
@@ -333,6 +334,35 @@ func TestRegionFilterListingEveryRegionOmitsUnplacedNodes(t *testing.T) {
}
}
// The recomputer starts at the first load chunk, so its prewarm misses
// adverts in later chunks. It recomputes once the startup load is done
// instead of up to one interval later (#2190 review).
func TestNodeRegionsRecomputeWhenStartupLoadDone(t *testing.T) {
resetStarted := func() {
nodeHomeRegionsRecompStartedMu.Lock()
nodeHomeRegionsRecompStarted = false
nodeHomeRegionsRecompStartedMu.Unlock()
}
resetStarted()
t.Cleanup(resetStarted)
ps := newRegionTestStore(t, map[string]string{"o-aus": "AUS"})
stop := ps.StartNodeHomeRegionsRecomputer(time.Hour)
defer stop()
// A later chunk lands, then the background fill finishes.
addToStore(ps, mkHomeRegionAdvert(1, "pk_late", homeZeroHopDirect, "o-aus"))
ps.signalStartupLoadDone()
deadline := time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {
if _, ok := ps.GetNodeRegionPlacements()["pk_late"]; ok {
return
}
time.Sleep(10 * time.Millisecond)
}
t.Fatal("pk_late not placed after the startup load finished")
}
// newRegionRecomputeBenchStore builds BenchmarkRegionNodePubkeys' scale: 220k
// adverts from 4,000 nodes, each heard by 8 observers across 10 regions over
// 0-7 hop paths (one in eight sent zero-hop direct), plus nonAdverts channel