mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestAdmissionGateDefaultsToAllowAndBlocksOnlyNewWork(t *testing.T) {
|
|
gate := NewAdmissionGate(false)
|
|
for _, operation := range []string{"login", "queue", "proposal", "allocation", "result", "events"} {
|
|
if !gate.Allow(operation) {
|
|
t.Fatalf("normal mode rejected %q", operation)
|
|
}
|
|
}
|
|
gate.SetDegraded(true)
|
|
for _, operation := range []string{"login", "queue", "proposal", "allocation"} {
|
|
if gate.Allow(operation) {
|
|
t.Fatalf("degraded mode allowed %q", operation)
|
|
}
|
|
}
|
|
for _, operation := range []string{"result", "events", "read", ""} {
|
|
if !gate.Allow(operation) {
|
|
t.Fatalf("degraded mode rejected live-safe operation %q", operation)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAdmissionOperationClassifiesOnlyMutations(t *testing.T) {
|
|
tests := []struct {
|
|
path, method, want string
|
|
}{
|
|
{"/v1/session/steam", http.MethodPost, "login"},
|
|
{"/api/v1/session/steam/", http.MethodPost, "login"},
|
|
{"/v1/queue", http.MethodPost, "queue"},
|
|
{"/api/v1/queue/tickets/abc/heartbeat", http.MethodPost, "queue"},
|
|
{"/v1/proposals/abc/accept", http.MethodPost, "proposal"},
|
|
{"/api/v1/proposals/abc", http.MethodDelete, "proposal"},
|
|
{"/v1/queue", http.MethodGet, ""},
|
|
{"/v1/queue-not-a-route", http.MethodPost, ""},
|
|
{"/v1/servers/abc/result", http.MethodPost, ""},
|
|
{"/v1/events", http.MethodPost, ""},
|
|
}
|
|
for _, test := range tests {
|
|
if got := admissionOperation(test.path, test.method); got != test.want {
|
|
t.Errorf("admissionOperation(%q, %q) = %q, want %q", test.path, test.method, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAdmissionGateConcurrentToggle(t *testing.T) {
|
|
gate := NewAdmissionGate(false)
|
|
var wg sync.WaitGroup
|
|
for i := 0; i < 8; i++ {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
for j := 0; j < 1000; j++ {
|
|
gate.SetDegraded(j%2 == 0)
|
|
_ = gate.Allow("queue")
|
|
}
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
}
|
|
|
|
func TestHandlerReturnsDegradedOnlyForNewMatchmakingMutations(t *testing.T) {
|
|
service := &Service{Admission: NewAdmissionGate(true)}
|
|
tests := []struct {
|
|
path, want string
|
|
}{
|
|
{"/v1/queue", "service_degraded"},
|
|
{"/api/v1/proposals/proposal-1/accept", "service_degraded"},
|
|
{"/v1/servers/server-1/result", "server_unavailable"},
|
|
{"/v1/events", ""},
|
|
}
|
|
for _, test := range tests {
|
|
req := httptest.NewRequest(http.MethodPost, test.path, strings.NewReader(`{}`))
|
|
rec := httptest.NewRecorder()
|
|
service.Handler().ServeHTTP(rec, req)
|
|
if test.want != "" && !strings.Contains(rec.Body.String(), test.want) {
|
|
t.Errorf("%s body = %q, want %q", test.path, rec.Body.String(), test.want)
|
|
}
|
|
if test.want == "service_degraded" && rec.Code != http.StatusServiceUnavailable {
|
|
t.Errorf("%s status = %d, want 503", test.path, rec.Code)
|
|
}
|
|
}
|
|
}
|