143 lines
4.5 KiB
Go
143 lines
4.5 KiB
Go
package metricsracenamedir_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"galaxy/lobby/internal/adapters/metricsracenamedir"
|
|
"galaxy/lobby/internal/adapters/racenameinmem"
|
|
"galaxy/lobby/internal/ports"
|
|
"galaxy/lobby/internal/telemetry"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
|
|
"go.opentelemetry.io/otel/sdk/metric/metricdata"
|
|
)
|
|
|
|
func newRuntime(t *testing.T) (*telemetry.Runtime, sdkmetric.Reader) {
|
|
t.Helper()
|
|
reader := sdkmetric.NewManualReader()
|
|
provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
|
|
t.Cleanup(func() { _ = provider.Shutdown(context.Background()) })
|
|
runtime, err := telemetry.NewWithProviders(provider, nil)
|
|
require.NoError(t, err)
|
|
return runtime, reader
|
|
}
|
|
|
|
func newInner(t *testing.T) ports.RaceNameDirectory {
|
|
t.Helper()
|
|
stub, err := racenameinmem.NewDirectory()
|
|
require.NoError(t, err)
|
|
return stub
|
|
}
|
|
|
|
func TestDirectoryRecordsReserveAndReleaseOutcomes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
runtime, reader := newRuntime(t)
|
|
dir := metricsracenamedir.New(newInner(t), runtime)
|
|
|
|
ctx := context.Background()
|
|
require.NoError(t, dir.Reserve(ctx, "game-a", "user-1", "Apollon"))
|
|
require.NoError(t, dir.ReleaseReservation(ctx, "game-a", "user-1", "Apollon"))
|
|
|
|
rm := collect(t, reader)
|
|
counts := raceNameCounts(rm)
|
|
assert.Equal(t, int64(1), counts["reserved"])
|
|
assert.Equal(t, int64(1), counts["reservation_released"])
|
|
}
|
|
|
|
func TestDirectoryRecordsPendingAndRegistered(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
runtime, reader := newRuntime(t)
|
|
dir := metricsracenamedir.New(newInner(t), runtime)
|
|
|
|
ctx := context.Background()
|
|
now := time.Date(2026, 4, 25, 12, 0, 0, 0, time.UTC)
|
|
eligibleUntil := now.Add(30 * 24 * time.Hour)
|
|
|
|
require.NoError(t, dir.Reserve(ctx, "game-finished", "user-7", "Helios"))
|
|
require.NoError(t, dir.MarkPendingRegistration(ctx, "game-finished", "user-7", "Helios", eligibleUntil))
|
|
require.NoError(t, dir.Register(ctx, "game-finished", "user-7", "Helios"))
|
|
|
|
rm := collect(t, reader)
|
|
counts := raceNameCounts(rm)
|
|
assert.Equal(t, int64(1), counts["pending_created"])
|
|
assert.Equal(t, int64(1), counts["registered"])
|
|
}
|
|
|
|
func TestDirectoryRecordsExpiredPending(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
runtime, reader := newRuntime(t)
|
|
dir := metricsracenamedir.New(newInner(t), runtime)
|
|
|
|
ctx := context.Background()
|
|
old := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
require.NoError(t, dir.Reserve(ctx, "game-old", "user-9", "Aether"))
|
|
require.NoError(t, dir.MarkPendingRegistration(ctx, "game-old", "user-9", "Aether", old))
|
|
|
|
expired, err := dir.ExpirePendingRegistrations(ctx, old.Add(time.Hour))
|
|
require.NoError(t, err)
|
|
require.Len(t, expired, 1)
|
|
|
|
rm := collect(t, reader)
|
|
assert.Equal(t, int64(1), raceNameCounts(rm)["pending_released"])
|
|
}
|
|
|
|
func TestDirectoryReleaseAllByUserSnapshotsCounts(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
runtime, reader := newRuntime(t)
|
|
dir := metricsracenamedir.New(newInner(t), runtime)
|
|
|
|
ctx := context.Background()
|
|
now := time.Date(2026, 4, 25, 12, 0, 0, 0, time.UTC)
|
|
eligibleUntil := now.Add(30 * 24 * time.Hour)
|
|
|
|
require.NoError(t, dir.Reserve(ctx, "game-active", "user-z", "Boreas"))
|
|
require.NoError(t, dir.Reserve(ctx, "game-finished", "user-z", "Notos"))
|
|
require.NoError(t, dir.MarkPendingRegistration(ctx, "game-finished", "user-z", "Notos", eligibleUntil))
|
|
require.NoError(t, dir.Reserve(ctx, "game-other", "user-z", "Eurus"))
|
|
require.NoError(t, dir.MarkPendingRegistration(ctx, "game-other", "user-z", "Eurus", eligibleUntil))
|
|
require.NoError(t, dir.Register(ctx, "game-other", "user-z", "Eurus"))
|
|
|
|
require.NoError(t, dir.ReleaseAllByUser(ctx, "user-z"))
|
|
|
|
rm := collect(t, reader)
|
|
counts := raceNameCounts(rm)
|
|
assert.GreaterOrEqual(t, counts["reservation_released"], int64(1))
|
|
assert.GreaterOrEqual(t, counts["pending_released"], int64(1))
|
|
assert.GreaterOrEqual(t, counts["registered_released"], int64(1))
|
|
}
|
|
|
|
func collect(t *testing.T, reader sdkmetric.Reader) metricdata.ResourceMetrics {
|
|
t.Helper()
|
|
var rm metricdata.ResourceMetrics
|
|
require.NoError(t, reader.Collect(context.Background(), &rm))
|
|
return rm
|
|
}
|
|
|
|
func raceNameCounts(rm metricdata.ResourceMetrics) map[string]int64 {
|
|
counts := map[string]int64{}
|
|
for _, scope := range rm.ScopeMetrics {
|
|
for _, m := range scope.Metrics {
|
|
if m.Name != "lobby.race_name.outcomes" {
|
|
continue
|
|
}
|
|
sum, ok := m.Data.(metricdata.Sum[int64])
|
|
if !ok {
|
|
continue
|
|
}
|
|
for _, point := range sum.DataPoints {
|
|
outcome, _ := point.Attributes.Value("outcome")
|
|
counts[outcome.AsString()] += point.Value
|
|
}
|
|
}
|
|
}
|
|
return counts
|
|
}
|