Files
CosmicClash/server/store/allocation_match_sql_test.go

48 lines
2.3 KiB
Go

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", "m.playlist"},
AllocatingMatchBuildSQL: {"match_participants", "queue_tickets", "ORDER BY q.client_build"},
BindAllocatedMatchParticipantsSQL: {"allocation_id = $2", "server_id IS NULL", "SET server_id = $3", "FROM allocations", "state = 'ALLOCATING'", "revision = revision + 1", "SELECT revision FROM bound"},
ReleaseAllocatedMatchClaimSQL: {"allocation_id = $2", "allocation_id = NULL", "allocation_claimed_at = NULL"},
AdvanceServerRegistrationSQL: {"state = $4", "initial_connect_ready_at", "$6", "protocol_version = $7", "ASSIGNMENT_READY", "RETURNING match_id, revision", "revision = q.revision + 1", "SELECT revision FROM matched"},
ServerRegistrationIdempotencyInsertSQL: {"idempotency_keys", "ON CONFLICT (scope, idempotency_key) DO NOTHING", "payload_digest"},
ServerRegistrationIdempotencySelectSQL: {"scope = $1", "idempotency_key = $2", "FOR UPDATE"},
}
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")
}
}