mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
test: expand offline multiplayer failure matrix
This commit is contained in:
+1
-1
@@ -1239,7 +1239,7 @@ the local/CI/community transport, not a silent production fallback.
|
||||
| 8.44 `[D:8.3,8.4,8.28,8.31]` | **IN PROGRESS.** Go observability package encodes queue/proposal/match/server IDs and lifecycle stage in structured events while recursively redacting auth/relay tokens and credentials | `server/observability/` covers correlation fields, nested secret redaction and unnamed-event rejection; production logger/metrics/traces/replay integration and secret-canary coverage remain |
|
||||
| 8.45 `[D:8.2,8.44]` | **IN PROGRESS.** Go observability package turns the documented RTT, allocation/connect latency, result-success, API-latency and tick/headroom thresholds into executable window checks | `server/observability/slo.go` covers healthy/violating/empty windows; production metrics export, dashboards, alert routing, wait/MMR/proposal/flood/cost series and runbooks remain |
|
||||
| 8.46 `[D:8.5,8.7,8.9,8.10,8.14,8.18,8.21,8.23,8.25]` | **IN PROGRESS.** Go unit/race coverage spans the current domain/store/supervisor policies, and fuzz targets now exercise queue input, result payload hashing and revision events | `server/domain/*_test.go`, `server/store/*_test.go`, `server/supervisor/*_test.go` and `server/domain/fuzz_test.go` pass normal/race suites; `go test -fuzz`, PostgreSQL concurrency/migration execution, fake Steam/allocator and full lost-Redis/transaction fixtures remain |
|
||||
| 8.47 `[D:8.7,8.30]` | **IN PROGRESS.** Offline testkit provides deterministic fake Steam verification and fake allocation with forced failure injection | `server/testkit/` covers verified identity/replay and cloud-free forced allocation failure; API/Compose integration and exhaustive success/failure matrix remain |
|
||||
| 8.47 `[D:8.7,8.30]` | **IN PROGRESS.** Offline testkit provides deterministic fake Steam verification and fake allocation with forced failure injection | `server/testkit/` covers verified identity/replay, unknown identity, wrong App ID, expiry, no capacity, compatibility-key conflict, idempotent allocation replay and cloud-free forced allocation failure in `TestOfflineFakesCoverVerificationAndAllocationFailureMatrix`; API/Compose integration and live exhaustive matrix remain |
|
||||
| 8.48 `[D:8.10,8.14,8.17,8.18,8.27,8.31,8.35,8.47]` | **IN PROGRESS.** Offline testkit exercises verified queue projection → ranked six-player proposal → ENet allocation → assignment-ready manifest → certified durable result receipt | `server/testkit/pipeline_test.go` covers the cross-domain success path without Steam/cloud secrets; independent Compose fixture, process shutdown, result ack over HTTP and legacy fixture non-regression remain |
|
||||
| 8.49 `[D:8.25,8.26,8.28,8.29,8.30,8.31,8.35,8.36]` | Disposable `kind` + Agones integration gate | CI covers dynamic ports, both readiness stages, roster/no-show, races, multi-match node, result-pending reconciliation, drain and rollback |
|
||||
| 8.50 `[D:8.25,8.37,8.43,8.49]` | Network/chaos suite: 100 ms RTT, jitter/loss, client/API/matcher restart, game-pod death, node drain, Redis failover and control-plane loss | System recovers to a defined state; infrastructure-caused cases cannot penalise affected players |
|
||||
|
||||
@@ -36,3 +36,57 @@ func TestFakeAllocatorCanForceFailureWithoutCloudState(t *testing.T) {
|
||||
t.Fatalf("forced failure = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOfflineFakesCoverVerificationAndAllocationFailureMatrix(t *testing.T) {
|
||||
now := time.Unix(1000, 0)
|
||||
fakeSteam, err := NewFakeSteamVerifier(480)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fakeSteam.Identities["steam-good"] = "player-good"
|
||||
tests := []struct {
|
||||
name string
|
||||
ticket domain.SteamTicket
|
||||
wantOK bool
|
||||
}{
|
||||
{name: "unknown identity", ticket: domain.SteamTicket{TicketID: "ticket-unknown", SteamID: "steam-unknown", AppID: 480, ExpiresAt: now.Add(time.Minute)}},
|
||||
{name: "wrong app", ticket: domain.SteamTicket{TicketID: "ticket-wrong-app", SteamID: "steam-good", AppID: 481, ExpiresAt: now.Add(time.Minute)}},
|
||||
{name: "expired", ticket: domain.SteamTicket{TicketID: "ticket-expired", SteamID: "steam-good", AppID: 480, ExpiresAt: now}},
|
||||
{name: "valid", ticket: domain.SteamTicket{TicketID: "ticket-valid", SteamID: "steam-good", AppID: 480, ExpiresAt: now.Add(time.Minute)}, wantOK: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
identity, verifyErr := fakeSteam.Verify(test.ticket, now)
|
||||
if (verifyErr == nil) != test.wantOK {
|
||||
t.Fatalf("identity = %+v err = %v", identity, verifyErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
if _, err := fakeSteam.Verify(tests[3].ticket, now); err == nil {
|
||||
t.Fatal("valid Steam ticket replay was accepted")
|
||||
}
|
||||
|
||||
fakeAllocator, err := NewFakeAllocator([]domain.ReadyServer{{ServerID: "server-eu", Region: "EU", Build: "build-1", Protocol: 1, Transport: "enet", State: domain.ServerReady}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
base := domain.AllocationRequest{AllocationID: "allocation-1234567890123456", MatchID: "match-1234567890123456", Region: "EU", Build: "build-1", Protocol: 1, Transport: "enet"}
|
||||
if _, err := fakeAllocator.Allocate(base, now); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := fakeAllocator.Allocate(base, now); err != nil {
|
||||
t.Fatalf("identical allocation replay failed: %v", err)
|
||||
}
|
||||
conflict := base
|
||||
conflict.Transport = "steam_sdr"
|
||||
if _, err := fakeAllocator.Allocate(conflict, now); err == nil {
|
||||
t.Fatal("allocation key reuse with changed compatibility was accepted")
|
||||
}
|
||||
noCapacity := base
|
||||
noCapacity.AllocationID = "allocation-no-capacity-123456"
|
||||
noCapacity.MatchID = "match-no-capacity-123456"
|
||||
noCapacity.Region = "NA"
|
||||
if _, err := fakeAllocator.Allocate(noCapacity, now); err != domain.ErrNoCapacity {
|
||||
t.Fatalf("no-capacity error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user