tests: (p2p) TestBroadcaster is flaky#2821
Conversation
Both TestRun_ActualExecution and TestRun_ActualExecutionFullMode repeated the same 5-line listen-then-release-port dance. Factor it out into a reserveFreePort helper matching the one added to exporter/api/server_test.go in the prior commit, so the two packages use the same pattern. Also drop the now-stale cross-reference comment in the exporter helper now that api/server has the same thing.
Callers may send on the feed immediately after Start returns; previously the subscribe happened inside a goroutine, so early sends could be lost. Split FromFeed into a synchronous Subscribe + an internal pump goroutine so the subscription is live before Start returns. Also tidies wsServer.Start: scope httpServer locally, wrap listen error with fmt.Errorf, and use errors.Is for the ErrServerClosed check.
…sageValidation The count assertion is incompatible with libp2p gossipsub's peer-score filtering (misbehaving peers get filtered at the pubsub layer before reaching the validator callback once their score crosses the threshold), and the strict ordering assertion flaked because peers with identical rejected-rates (nodes 0 and 1) differ only within scoring noise. Replace both with a rejected-rate invariant: peers with a strictly lower rejected-rate must not be ranked below peers with a higher rate. Ties within the same rate group are allowed. Also drop dead TotalAccepted/TotalIgnored/TotalRejected fields and the roleBroadcasts tracker that fed the removed count assertion.
Codecov Report❌ Patch coverage is ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Greptile SummaryThis PR fixes the flaky Confidence Score: 5/5Safe to merge; all remaining findings are minor style suggestions with no correctness impact. The core flakiness fix is logically sound: waiting for both subscribers to confirm receipt of msg1 guarantees the broadcast goroutine has returned before bm2 is deregistered, making the ordering deterministic. The mDNS tag isolation and peer-score invariant simplification are straightforward improvements. The only open item is a stray fmt.Println debug statement in the test mock, which is noisy but harmless. exporter/api/broadcaster_test.go — remove leftover fmt.Println("sent") from broadcastedMock.Send Important Files Changed
Sequence DiagramsequenceDiagram
participant Test
participant Feed
participant BroadcastGoroutine
participant bm1
participant bm2
Test->>Feed: Subscribe(buffer) [synchronous]
Test->>BroadcastGoroutine: spawn goroutine
Test->>Feed: Send(msg1)
Feed-->>BroadcastGoroutine: buffer <- msg1
BroadcastGoroutine->>bm1: Send(msg1)
BroadcastGoroutine->>bm2: Send(msg1)
Note over Test: require.Eventually: bm1.Size()==1 && bm2.Size()==1
Test->>Test: Deregister(bm2) [safe: goroutine idle in select]
Test->>Feed: Send(msg2)
Feed-->>BroadcastGoroutine: buffer <- msg2
BroadcastGoroutine->>bm1: Send(msg2)
Note over BroadcastGoroutine: bm2 not in snapshot — skipped
Note over Test: require.Eventually: bm1.Size()==2
Test->>Test: assert bm2.Size()==1 ✓
|
Rebased onto #2819 (only the latest commit here is new).
Resolves flaky pipeline https://github.com/ssvlabs/ssv/actions/runs/24669605966/job/72136402325?pr=2819
Related to https://github.com/ssvlabs/ssv-node-board/issues/941 (discovered during investigation).