feat(multiplayer): add shared allocation quota

This commit is contained in:
Josh Creek
2026-09-01 18:38:06 +01:00
parent 55706ba9ea
commit 72e8d27633
11 changed files with 211 additions and 4 deletions
+35
View File
@@ -32,6 +32,16 @@ type rosterSpy struct {
err error
}
type quotaSpy struct {
calls int
err error
}
func (q *quotaSpy) Consume(context.Context, string, time.Time) error {
q.calls++
return q.err
}
func (r *rosterSpy) PublishRoster(_ context.Context, _ domain.Assignment, _ []domain.SignedJoinAuthorisation, _ func([]byte, []byte) bool) error {
r.calls++
return r.err
@@ -63,6 +73,31 @@ func TestServiceDoesNotReturnProviderResultAfterDurableFailure(t *testing.T) {
}
}
func TestServiceConsumesSharedQuotaBeforeFreshProviderCall(t *testing.T) {
provider := &providerSpy{result: agones.AllocatedServer{Allocation: domain.Allocation{AllocationID: "a", State: domain.ServerAllocated}, Endpoint: "127.0.0.1:7777"}}
quota := &quotaSpy{err: errors.New("quota exhausted")}
service := Service{Provider: provider, Durable: &durableSpy{}, Quota: quota, Now: func() time.Time { return time.Unix(1000, 0) }}
if _, err := service.Allocate(context.Background(), domain.AllocationRequest{AllocationID: "a", MatchID: "m", Region: "EU", Build: "b", Protocol: 1, Transport: "enet"}, nil); err == nil {
t.Fatal("quota rejection was ignored")
}
if quota.calls != 1 || provider.calls != 0 {
t.Fatalf("quota/provider calls = %d/%d, want 1/0", quota.calls, provider.calls)
}
}
func TestServiceConsumesSharedQuotaOnceWhenReconcilingProviderResult(t *testing.T) {
quota := &quotaSpy{}
durable := &durableSpy{}
service := Service{Durable: durable, Quota: quota, Now: func() time.Time { return time.Unix(1000, 0) }}
result := agones.AllocatedServer{Allocation: domain.Allocation{AllocationID: "a", MatchID: "m", Region: "EU", State: domain.ServerAllocated}, Endpoint: "127.0.0.1:7777"}
if _, err := service.RecordProviderAllocation(context.Background(), result, time.Unix(1000, 0)); err != nil {
t.Fatalf("reconciliation failed: %v", err)
}
if quota.calls != 1 || durable.calls != 1 {
t.Fatalf("quota/durable calls = %d/%d, want 1/1", quota.calls, durable.calls)
}
}
func TestServiceAllocatesOnlyUnanimouslyAcceptedMatchingProposal(t *testing.T) {
proposal := domain.Proposal{
ProposalID: "proposal-1", Playlist: domain.Casual, State: domain.Accepted,