Files
galaxy-game/lobby/internal/adapters/redisstate/streamlagprobe_test.go
T
2026-04-25 23:20:55 +02:00

103 lines
2.9 KiB
Go

package redisstate_test
import (
"context"
"strconv"
"testing"
"time"
"galaxy/lobby/internal/adapters/redisstate"
"github.com/alicebob/miniredis/v2"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func newLagTestProbe(t *testing.T, now time.Time) (*redisstate.StreamLagProbe, *miniredis.Miniredis, *redis.Client) {
t.Helper()
server := miniredis.RunT(t)
client := redis.NewClient(&redis.Options{Addr: server.Addr()})
t.Cleanup(func() {
_ = client.Close()
})
probe, err := redisstate.NewStreamLagProbe(client, func() time.Time { return now })
require.NoError(t, err)
return probe, server, client
}
func TestStreamLagProbeReturnsAgeOfNextEntry(t *testing.T) {
now := time.UnixMilli(2_000_000_000_000).UTC()
probe, _, client := newLagTestProbe(t, now)
ctx := context.Background()
addEntry := func(ms int64) string {
id, err := client.XAdd(ctx, &redis.XAddArgs{
Stream: "demo",
ID: formatEntryID(ms, 0),
Values: map[string]any{"k": "v"},
}).Result()
require.NoError(t, err)
return id
}
saved := addEntry(now.UnixMilli() - 5_000) // already processed
addEntry(now.UnixMilli() - 1_500) // first unprocessed → 1.5s old
age, ok, err := probe.OldestUnprocessedAge(ctx, "demo", saved)
require.NoError(t, err)
require.True(t, ok)
assert.InDelta(t, (1_500 * time.Millisecond).Milliseconds(), age.Milliseconds(), 50)
}
func TestStreamLagProbeReturnsFalseWhenAtTail(t *testing.T) {
now := time.UnixMilli(2_000_000_000_000).UTC()
probe, _, client := newLagTestProbe(t, now)
ctx := context.Background()
id, err := client.XAdd(ctx, &redis.XAddArgs{
Stream: "demo",
ID: formatEntryID(now.UnixMilli()-2_000, 0),
Values: map[string]any{"k": "v"},
}).Result()
require.NoError(t, err)
age, ok, err := probe.OldestUnprocessedAge(ctx, "demo", id)
require.NoError(t, err)
require.False(t, ok)
assert.Zero(t, age)
}
func TestStreamLagProbeFallsBackToHeadOnEmptyOffset(t *testing.T) {
now := time.UnixMilli(2_000_000_000_000).UTC()
probe, _, client := newLagTestProbe(t, now)
ctx := context.Background()
_, err := client.XAdd(ctx, &redis.XAddArgs{
Stream: "demo",
ID: formatEntryID(now.UnixMilli()-3_000, 0),
Values: map[string]any{"k": "v"},
}).Result()
require.NoError(t, err)
age, ok, err := probe.OldestUnprocessedAge(ctx, "demo", "")
require.NoError(t, err)
require.True(t, ok)
assert.InDelta(t, (3 * time.Second).Milliseconds(), age.Milliseconds(), 50)
}
func TestStreamLagProbeReturnsFalseOnEmptyStream(t *testing.T) {
now := time.UnixMilli(2_000_000_000_000).UTC()
probe, _, _ := newLagTestProbe(t, now)
ctx := context.Background()
age, ok, err := probe.OldestUnprocessedAge(ctx, "demo", "")
require.NoError(t, err)
require.False(t, ok)
assert.Zero(t, age)
}
func formatEntryID(ms int64, seq int64) string {
return strconv.FormatInt(ms, 10) + "-" + strconv.FormatInt(seq, 10)
}