test(pubsub): stop racing the Redis SUBSCRIBE ack (#38661)

`RedisBroker.Subscribe` returns before the server acks `SUBSCRIBE`, so a
publish right after it can be dropped, making
`TestRedisBroker/CrossBroker` fail intermittently on loaded CI runners
([example](https://github.com/go-gitea/gitea/actions/runs/30257188479/job/89948425118)).

Each scenario now uses its own topic and waits for `PUBSUB NUMSUB`
before publishing. `MemoryBroker` registers synchronously and skips the
wait.
This commit is contained in:
silverwind
2026-07-27 16:12:06 +02:00
committed by GitHub
parent 341caf8aa7
commit 7efcb8d6ca
3 changed files with 48 additions and 22 deletions
+5 -4
View File
@@ -39,14 +39,14 @@ func TestRedisBroker(t *testing.T) {
// state once the last local subscriber cancels.
t.Run("CancelCleansTopicState", func(t *testing.T) {
b := newBroker(t).(*RedisBroker)
ch, cancel := b.Subscribe("topic")
ch, cancel := b.Subscribe(t.Name())
cancel()
_, ok := <-ch
assert.False(t, ok, "channel must be closed after cancel")
b.mu.RLock()
_, present := b.topics["topic"]
_, present := b.topics[t.Name()]
b.mu.RUnlock()
assert.False(t, present, "topic state must be removed after last subscriber cancels")
})
@@ -56,10 +56,11 @@ func TestRedisBroker(t *testing.T) {
t.Run("CrossBroker", func(t *testing.T) {
publisher, subscriber := newBroker(t), newBroker(t)
ch, cancel := subscriber.Subscribe("topic")
ch, cancel := subscriber.Subscribe(t.Name())
defer cancel()
waitSubscribed(t, subscriber, t.Name())
publisher.Publish("topic", []byte("cross-process"))
publisher.Publish(t.Name(), []byte("cross-process"))
select {
case msg := <-ch: