Files
galaxy-game/backend/push/ring_test.go
T
2026-05-06 10:14:55 +03:00

106 lines
2.4 KiB
Go

package push
import (
"testing"
"time"
pushv1 "galaxy/backend/proto/push/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func mkEvent(cursor uint64, label string) *pushv1.PushEvent {
return &pushv1.PushEvent{
Cursor: formatCursor(cursor),
Kind: &pushv1.PushEvent_ClientEvent{
ClientEvent: &pushv1.ClientEvent{
Kind: label,
Payload: []byte(label),
},
},
}
}
func TestRingAppendAndSinceReturnsTail(t *testing.T) {
t.Parallel()
now := time.Unix(1_700_000_000, 0)
r := newRing(8, time.Minute)
for i := uint64(1); i <= 5; i++ {
r.append(i, mkEvent(i, "e"), now)
}
got, stale := r.since(2, now)
require.False(t, stale)
require.Len(t, got, 3)
assert.Equal(t, formatCursor(3), got[0].Cursor)
assert.Equal(t, formatCursor(4), got[1].Cursor)
assert.Equal(t, formatCursor(5), got[2].Cursor)
}
func TestRingSinceReturnsEmptyWhenCaughtUp(t *testing.T) {
t.Parallel()
now := time.Unix(1_700_000_000, 0)
r := newRing(8, time.Minute)
for i := uint64(1); i <= 3; i++ {
r.append(i, mkEvent(i, "e"), now)
}
got, stale := r.since(3, now)
require.False(t, stale)
assert.Empty(t, got)
got, stale = r.since(99, now)
require.False(t, stale)
assert.Empty(t, got)
}
func TestRingSinceFlagsStaleCursorBelowEvictedRange(t *testing.T) {
t.Parallel()
now := time.Unix(1_700_000_000, 0)
r := newRing(3, time.Minute)
for i := uint64(1); i <= 5; i++ {
r.append(i, mkEvent(i, "e"), now)
}
// Capacity=3 means cursors 1 and 2 were evicted.
require.Equal(t, 3, r.len())
got, stale := r.since(1, now)
assert.True(t, stale)
assert.Empty(t, got)
got, stale = r.since(2, now)
assert.False(t, stale)
require.Len(t, got, 3)
assert.Equal(t, formatCursor(3), got[0].Cursor)
}
func TestRingEvictsExpiredEntries(t *testing.T) {
t.Parallel()
t0 := time.Unix(1_700_000_000, 0)
r := newRing(8, 10*time.Second)
r.append(1, mkEvent(1, "e"), t0)
r.append(2, mkEvent(2, "e"), t0.Add(2*time.Second))
r.append(3, mkEvent(3, "e"), t0.Add(15*time.Second))
// At t0+13s the first two entries are past their 10s TTL but the
// third (added at t0+15s) is still within the freshness window.
got, stale := r.since(0, t0.Add(13*time.Second))
assert.True(t, stale)
assert.Empty(t, got)
assert.Equal(t, 1, r.len())
}
func TestRingEmptyIsNeverStale(t *testing.T) {
t.Parallel()
r := newRing(4, time.Minute)
got, stale := r.since(42, time.Now())
assert.False(t, stale)
assert.Empty(t, got)
}