aboutsummaryrefslogtreecommitdiff
path: root/internal/game/quit_state_race_test.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-16 21:35:55 -0400
committerhistoria <[not public]>2026-09-16 21:35:55 -0400
commitfea2cc6839ec3ee17940a2dea69622dc6f4deabf (patch)
tree9d893525ca20d2cc920e9e866f84f71b605d8ae9 /internal/game/quit_state_race_test.go
parent35ddd0ad2215760bb1d3dc7724480f179ea33fa6 (diff)
downloadthehouseoficarus-fea2cc6839ec3ee17940a2dea69622dc6f4deabf.tar.gz
fix: unify crafting ingredient resolution; fix superheat alternatives, quantity gates, and dropped combine byproducts
Diffstat (limited to 'internal/game/quit_state_race_test.go')
-rw-r--r--internal/game/quit_state_race_test.go32
1 files changed, 32 insertions, 0 deletions
diff --git a/internal/game/quit_state_race_test.go b/internal/game/quit_state_race_test.go
new file mode 100644
index 0000000..68f4770
--- /dev/null
+++ b/internal/game/quit_state_race_test.go
@@ -0,0 +1,32 @@
+package game
+
+// Regression: network input may arrive on a connection goroutine at any
+// moment, including while the tick-driven logout countdown (owner goroutine)
+// transitions the session to the character menu. The dispatch read
+// sess.State as a plain field, which the race detector flagged; the state is
+// now an atomic on net.Session. This test drives both sides concurrently and
+// must run clean under -race.
+
+import (
+ "testing"
+ "time"
+)
+
+func TestInputDuringLogoutCountdownIsRaceFree(t *testing.T) {
+ h := newHarness(t)
+ h.seedAccount("alice")
+ h.seedCharacter("alice", "alice")
+ sess, _ := h.connect("alice")
+
+ h.g.RunOnOwner(func() {
+ h.g.beginQuitCountdown(sess)
+ })
+
+ // Pump input while the countdown ticks toward the state change to the
+ // character menu (and past it, when the countdown completes early).
+ deadline := time.Now().Add(100 * time.Millisecond)
+ for time.Now().Before(deadline) {
+ h.g.HandleSessionOnOwner(sess, "notacommand")
+ }
+ h.barrier()
+}