go-nostr/eose_test.go
fiatjaf 5938a71146 replace close() with actually sending a value to .EndOfStoredEvents and .Closed channels.
I thought `close()` would be nice because it would be cheap and not lock the goroutine while waiting for the receiver to acknowledge the thing, but turns out it introduces the serious risk of users putting <- sub.EndOfStoredEvents in the same for { select {} } statement as sub.Events, for example, and they they get into an infinite loop.

we had this same problem here inside this same library, and what is fixed in 242af0bf76e4b23de47012244efb95ccec9e4374 by @mattn.
2024-01-01 10:18:16 -03:00

53 lines
831 B
Go

package nostr
import (
"context"
"testing"
"time"
)
func TestEOSEMadness(t *testing.T) {
rl := mustRelayConnect(RELAY)
defer rl.Close()
sub, err := rl.Subscribe(context.Background(), Filters{
{Kinds: []int{KindTextNote}, Limit: 2},
})
if err != nil {
t.Errorf("subscription failed: %v", err)
return
}
timeout := time.After(3 * time.Second)
n := 0
e := 0
for {
select {
case event := <-sub.Events:
if event == nil {
t.Fatalf("event is nil: %v", event)
}
n++
case <-sub.EndOfStoredEvents:
e++
if e > 1 {
t.Fatalf("eose infinite loop")
}
continue
case <-rl.Context().Done():
t.Fatalf("connection closed: %v", rl.Context().Err())
case <-timeout:
goto end
}
}
end:
if e != 1 {
t.Fatalf("didn't get an eose")
}
if n < 2 {
t.Fatalf("didn't get events")
}
}