package store import ( "testing" "time" "github.com/cosmic-clash/cosmic-clash/server/domain" ) func TestAllocationMatchClaimSQLFencesConcurrentWorkers(t *testing.T) { checks := map[string][]string{ ClaimAllocatingMatchSQL: {"FOR UPDATE SKIP LOCKED", "allocation_id = 'allocation-' || candidate.match_id", "allocation_claimed_at <= $1", "ORDER BY created_at, match_id"}, AllocatingMatchBuildSQL: {"match_participants", "queue_tickets", "ORDER BY q.client_build"}, BindAllocatedMatchSQL: {"allocation_id = $2", "server_id IS NULL", "SET server_id = $3", "FROM allocations"}, ReleaseAllocatedMatchClaimSQL: {"allocation_id = $2", "allocation_id = NULL", "allocation_claimed_at = NULL"}, } for query, fragments := range checks { for _, fragment := range fragments { if !contains(query, fragment) { t.Fatalf("query missing %q", fragment) } } } } func TestAllocationMatchClaimRejectsInvalidArgumentsWithoutDatabase(t *testing.T) { now := time.Unix(1_000, 0) if _, _, err := ClaimAllocatingMatch(nil, nil, "enet", now); err == nil { t.Fatal("nil database accepted") } if _, _, err := ClaimAllocatingMatch(nil, nil, "udp", now); err == nil { t.Fatal("invalid transport accepted") } if _, _, err := ClaimAllocatingMatch(nil, nil, "enet", time.Time{}); err == nil { t.Fatal("zero claim time accepted") } allocated := domain.Allocation{AllocationID: "allocation-match-1", MatchID: "match-1", ServerID: "server-1", State: domain.ServerAllocated} if err := BindAllocatedMatch(nil, nil, allocated); err == nil { t.Fatal("nil database accepted for bind") } if err := ReleaseAllocatedMatchClaim(nil, nil, "match-1", "allocation-match-1"); err == nil { t.Fatal("nil database accepted for release") } }