mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 18:33:43 +00:00
feat(multiplayer): expose server shutdown acknowledgement
This commit is contained in:
@@ -52,6 +52,20 @@ type serverRegistrarSpy struct {
|
||||
err error
|
||||
}
|
||||
|
||||
type serverShutdownerSpy struct {
|
||||
calls int
|
||||
binding domain.WorkloadBinding
|
||||
reason string
|
||||
key string
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *serverShutdownerSpy) ShutdownServer(_ context.Context, binding domain.WorkloadBinding, reason, key string, _ time.Time) error {
|
||||
s.calls++
|
||||
s.binding, s.reason, s.key = binding, reason, key
|
||||
return s.err
|
||||
}
|
||||
|
||||
func (s *serverRegistrarSpy) RegisterServer(_ context.Context, binding domain.WorkloadBinding, protocol int, assignmentReady bool, _ string, _ time.Time) error {
|
||||
s.calls++
|
||||
s.binding, s.protocol, s.assignmentReady = binding, protocol, assignmentReady
|
||||
@@ -1358,6 +1372,40 @@ func TestServerRegistrationAPIRequiresBoundWorkloadAndValidDigest(t *testing.T)
|
||||
response.Body.Close()
|
||||
}
|
||||
|
||||
func TestServerShutdownAPIRequiresBoundWorkloadAndDelegatesAcknowledgement(t *testing.T) {
|
||||
now := time.Unix(1000, 0).UTC()
|
||||
binding := domain.WorkloadBinding{AllocationID: "allocation-1", MatchID: "match-1", ServerID: "server-1"}
|
||||
shutdowner := &serverShutdownerSpy{}
|
||||
service := &Service{Now: func() time.Time { return now }, WorkloadVerify: func(token string, at time.Time) (domain.WorkloadBinding, error) {
|
||||
if token != "workload-token" || !at.Equal(now) {
|
||||
t.Fatalf("verifier input=%q %v", token, at)
|
||||
}
|
||||
return binding, nil
|
||||
}, ServerShutdowner: shutdowner}
|
||||
server := httptest.NewServer(service.Handler())
|
||||
defer server.Close()
|
||||
req, _ := http.NewRequest(http.MethodPost, server.URL+"/v1/servers/server-1/shutdown", strings.NewReader(`{"reason":"server_draining"}`))
|
||||
req.Header.Set("Authorization", "Bearer workload-token")
|
||||
req.Header.Set("Idempotency-Key", "shutdown-key-123456")
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
if err != nil || response.StatusCode != http.StatusNoContent {
|
||||
t.Fatalf("status=%v err=%v", response.StatusCode, err)
|
||||
}
|
||||
response.Body.Close()
|
||||
if shutdowner.calls != 1 || shutdowner.binding != binding || shutdowner.reason != "server_draining" || shutdowner.key != "shutdown-key-123456" {
|
||||
t.Fatalf("shutdown=%+v", shutdowner)
|
||||
}
|
||||
|
||||
req, _ = http.NewRequest(http.MethodPost, server.URL+"/v1/servers/server-1/shutdown", strings.NewReader(`{"reason":"bad\nreason"}`))
|
||||
req.Header.Set("Authorization", "Bearer workload-token")
|
||||
req.Header.Set("Idempotency-Key", "shutdown-key-123456")
|
||||
response, err = http.DefaultClient.Do(req)
|
||||
if err != nil || response.StatusCode != http.StatusUnprocessableEntity || shutdowner.calls != 1 {
|
||||
t.Fatalf("invalid shutdown status=%v err=%v calls=%d", response.StatusCode, err, shutdowner.calls)
|
||||
}
|
||||
response.Body.Close()
|
||||
}
|
||||
|
||||
func TestProbeAPIUsesServerEvidenceAndRejectsClientRTTField(t *testing.T) {
|
||||
now := time.Unix(1000, 0).UTC()
|
||||
sessions := domain.NewSessionStore()
|
||||
|
||||
Reference in New Issue
Block a user