feat: backend service
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user