diff options
Diffstat (limited to 'internal/game/shutdown_admission_test.go')
| -rw-r--r-- | internal/game/shutdown_admission_test.go | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/internal/game/shutdown_admission_test.go b/internal/game/shutdown_admission_test.go new file mode 100644 index 0000000..6aa4be5 --- /dev/null +++ b/internal/game/shutdown_admission_test.go @@ -0,0 +1,55 @@ +package game + +// Shutdown-admission regression: once shutdown has begun, session input must +// never mutate game state — not during the drain window, and especially not +// after the owner has stopped (the transports keep draining until they +// close, so an accepted line would execute concurrently with the shutdown +// sequence or after the final-save barrier). + +import ( + "testing" + + "thehouseoficarus/internal/net" +) + +func TestShutdownRejectsSessionInput(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice", "pw", false) + h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + sess.State = net.StateGame + h.g.setShuttingDown() + h.g.stopOwner() + + // The network listeners are closed only AFTER the owner stops, so + // connections can still submit lines through the production entry + // point. Every one of them must be rejected. + h.g.HandleSessionOnOwner(sess, "look") + + // A durable mutation gives an unambiguous admission check: description + // input would rewrite the character. + sess.State = net.StateChangeDesc + h.g.HandleSessionOnOwner(sess, "Input after final save") + if sess.Player.Description == "Input after final save" { + t.Error("session input still mutates character after shutdown/owner stop") + } +} + +func TestShutdownRejectsInputDuringDrain(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice", "pw", false) + h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + sess.State = net.StateGame + h.g.setShuttingDown() + + // During the drain window the owner is still alive, but new input is + // already rejected: only work accepted before shutdown executes. + h.g.HandleSessionOnOwner(sess, "look") + sess.State = net.StateChangeDesc + h.g.HandleSessionOnOwner(sess, "Input during drain") + if sess.Player.Description == "Input during drain" { + t.Error("session input accepted after shutdown began") + } + h.barrier() +} |
