mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 00:14:00 +00:00
feat(multiplayer): add shared allocation quota
This commit is contained in:
@@ -44,7 +44,7 @@ func openIntegrationPostgres(t *testing.T) *sql.DB {
|
||||
|
||||
func applyIntegrationMigrations(t *testing.T, db *sql.DB) {
|
||||
t.Helper()
|
||||
if _, err := db.ExecContext(context.Background(), `DROP TABLE IF EXISTS schema_migrations, assignments, audit_events, outbox, result_receipts, ranked_season_rollovers, penalties, seasons, ratings, match_participants, matches, proposal_participants, proposals, allocations, game_servers, queue_tickets, idempotency_keys, sessions, identities CASCADE`); err != nil {
|
||||
if _, err := db.ExecContext(context.Background(), `DROP TABLE IF EXISTS schema_migrations, allocation_quotas, assignments, audit_events, outbox, result_receipts, ranked_season_rollovers, penalties, seasons, ratings, match_participants, matches, proposal_participants, proposals, allocations, game_servers, queue_tickets, idempotency_keys, sessions, identities CASCADE`); err != nil {
|
||||
t.Fatalf("reset PostgreSQL schema: %v", err)
|
||||
}
|
||||
if err := migrations.Apply(context.Background(), db, filepath.Join("..", "migrations")); err != nil {
|
||||
@@ -104,6 +104,41 @@ func TestPostgreSQLAllocatorClaimReplayAndCapacityFence(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostgreSQLSharedAllocationQuotaFencesClaimsAndReplays(t *testing.T) {
|
||||
db := openIntegrationPostgres(t)
|
||||
applyIntegrationMigrations(t, db)
|
||||
now := time.Now().UTC().Truncate(time.Microsecond)
|
||||
ctx := context.Background()
|
||||
if err := SetAllocationQuota(ctx, db, "EU", 1, time.Minute, now); err != nil {
|
||||
t.Fatalf("set quota: %v", err)
|
||||
}
|
||||
for _, server := range []domain.ReadyServer{
|
||||
{ServerID: "quota-server-a", Region: "EU", Build: "build-1", Protocol: 1, Transport: "enet", State: domain.ServerReady},
|
||||
{ServerID: "quota-server-b", Region: "EU", Build: "build-1", Protocol: 1, Transport: "enet", State: domain.ServerReady},
|
||||
} {
|
||||
if err := RegisterReadyServer(ctx, db, server, now); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
first := domain.AllocationRequest{AllocationID: "quota-allocation-1", MatchID: "quota-match-1", Region: "EU", Build: "build-1", Protocol: 1, Transport: "enet"}
|
||||
if _, err := ClaimAllocation(ctx, db, first, now); err != nil {
|
||||
t.Fatalf("first claim: %v", err)
|
||||
}
|
||||
if _, err := ClaimAllocation(ctx, db, first, now.Add(time.Second)); err != nil {
|
||||
t.Fatalf("idempotent replay was fenced: %v", err)
|
||||
}
|
||||
second := domain.AllocationRequest{AllocationID: "quota-allocation-2", MatchID: "quota-match-2", Region: "EU", Build: "build-1", Protocol: 1, Transport: "enet"}
|
||||
if _, err := ClaimAllocation(ctx, db, second, now.Add(2*time.Second)); !errors.Is(err, ErrAllocationQuotaExceeded) {
|
||||
t.Fatalf("second claim err=%v, want shared quota fence", err)
|
||||
}
|
||||
if err := SetAllocationQuota(ctx, db, "EU", 1, time.Minute, now.Add(time.Minute)); err != nil {
|
||||
t.Fatalf("reset quota: %v", err)
|
||||
}
|
||||
if _, err := ClaimAllocation(ctx, db, second, now.Add(time.Minute)); err != nil {
|
||||
t.Fatalf("claim after quota window reset: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPostgreSQLConcurrentAllocationClaimNeverDoubleBooksAReadyServer is the
|
||||
// live counterpart to TestPostgreSQLAllocatorClaimReplayAndCapacityFence: that
|
||||
// test claims strictly one request at a time, so it cannot show what happens
|
||||
@@ -1249,8 +1284,8 @@ func TestPostgreSQLMigrationsRollBackAndReapplyCleanly(t *testing.T) {
|
||||
// Roll back every migration one at a time, in reverse, checking each
|
||||
// down file actually undoes what its forward file created — not just
|
||||
// that Rollback returns nil.
|
||||
if err := migrations.Rollback(context.Background(), db, dir, 1); err != nil {
|
||||
t.Fatalf("rollback 0006: %v", err)
|
||||
if err := migrations.Rollback(context.Background(), db, dir, 2); err != nil {
|
||||
t.Fatalf("rollback 0007 and 0006: %v", err)
|
||||
}
|
||||
var hasAllocationClaimColumn bool
|
||||
if err := db.QueryRow(`SELECT count(*) > 0 FROM information_schema.columns WHERE table_name = 'matches' AND column_name = 'allocation_id'`).Scan(&hasAllocationClaimColumn); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user