Skip to content

Commit acbaf81

Browse files
committed
small fixes and lint
1 parent 57c8b6f commit acbaf81

4 files changed

Lines changed: 47 additions & 13 deletions

File tree

apps/game_server_core/lib/game_server/matchmaking/worker.ex

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ defmodule GameServer.Matchmaking.Worker do
1010
Each tick, inside the lock: prune tickets of users that went offline, then
1111
group the queued tickets by `match_params` and create a hidden lobby per
1212
formed match. Broadcasts go out after the lock's transaction commits.
13+
14+
config :game_server_core, GameServer.Matchmaking.Worker,
15+
enabled: true # set false to leave the worker idle
16+
17+
Disabled in test configs, like the other periodic workers: the tick owns no
18+
sandbox connection, so it only produces "database is locked" noise. Tests
19+
call `sweep/0` directly.
1320
"""
1421

1522
use GenServer
@@ -28,10 +35,14 @@ defmodule GameServer.Matchmaking.Worker do
2835

2936
@impl true
3037
def init(_) do
31-
Process.send_after(self(), :tick, @initial_delay_ms)
38+
# Stays supervised but idle when disabled (tests): the sweep has no sandbox
39+
# connection to check out, so it would just stall and then error.
40+
if enabled?(), do: Process.send_after(self(), :tick, @initial_delay_ms)
3241
{:ok, %{}}
3342
end
3443

44+
defp enabled?, do: Application.get_env(:game_server_core, __MODULE__, [])[:enabled] != false
45+
3546
@impl true
3647
def handle_info(:tick, state) do
3748
_ =

apps/game_server_web/config/test.exs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,19 @@ config :game_server_web, GameServerWeb.Plugs.RateLimiter, enabled: false
7777
# keep logging after the test task itself is done.
7878
config :game_server_core, GameServer.Accounts.StalePresenceSweeper, enabled: false
7979

80-
# Run GameServer.Async side effects inline so assertions observe them without
81-
# racing, and so a fire-and-forget task can't outlive the test's DB sandbox
82-
# owner (that surfaced as "client #PID exited" Exqlite disconnects). Kept in
83-
# sync with the root config/test.exs, which only applies to umbrella runs.
84-
config :game_server_core, async_inline: true
80+
# The other periodic workers, for the same reason: neither owns a sandbox
81+
# connection, and on SQLite they collide with the test's open write transaction
82+
# ("database is locked"). Tests drive tick/0 and sweep/0 directly.
83+
config :game_server_core, GameServer.Tournaments.Ticker, enabled: false
84+
config :game_server_core, GameServer.Matchmaking.Worker, enabled: false
85+
86+
# NOTE: deliberately NOT setting `async_inline: true` here, unlike the root
87+
# config/test.exs. Payments call GameServer.Async.run/1 from inside a
88+
# Repo.transaction, and the hook fanout blocks on a Task that needs its own
89+
# connection — inline, that Task waits on the connection its own caller is
90+
# holding for the transaction, times out after 15s and rolls back. It fails
91+
# 7 payments/entitlement tests. The stray "client exited" disconnects that
92+
# inline mode would silence need a fix in Async/Hooks, not this knob.
8593

8694
# Jobs run inline on demand in tests (no queues/plugins/cron). Kept in sync with
8795
# the root config/test.exs.
@@ -90,4 +98,5 @@ config :game_server_core, Oban, testing: :manual
9098
# The declared setting, not just the endpoint's copy: GameServer.Settings
9199
# validates `auth.secret_key_base` at boot, and dev should not warn about a
92100
# secret it demonstrably has.
93-
config :game_server_core, GameServer.Accounts, secret_key_base: "dJoNJZBOt08JlBREyPV5xvuOdwgHPORxK9WHp/k3Cs+g0R9ctyheJ8/CMeg/AdI1"
101+
config :game_server_core, GameServer.Accounts,
102+
secret_key_base: "dJoNJZBOt08JlBREyPV5xvuOdwgHPORxK9WHp/k3Cs+g0R9ctyheJ8/CMeg/AdI1"

apps/game_server_web/test/game_server/leaderboards_test.exs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,17 +272,26 @@ defmodule GameServer.LeaderboardsTest do
272272

273273
# Ada is mid-table on purpose: her rank must survive being searched for.
274274
for {name, score} <- [{"Zoe Top", 900}, {"Ada Lovelace", 500}, {"Bob Last", 100}] do
275-
user =
276-
AccountsFixtures.user_fixture()
277-
|> Ecto.Changeset.change(display_name: name)
278-
|> GameServer.Repo.update!()
279-
275+
user = searchable_user(display_name: name)
280276
Leaderboards.submit_score(lb.id, user.id, score)
281277
end
282278

283279
%{leaderboard: lb}
284280
end
285281

282+
# Search covers username as well as display_name and label, and fixture
283+
# usernames come from a word list that can contain the terms these tests
284+
# search for - "foxglove-2812" matched a search for "LOVE" and made the
285+
# single-result assertions fail at random. Pin them to something no test
286+
# searches for.
287+
defp searchable_user(attrs) do
288+
attrs = Keyword.put(attrs, :username, "pinned-#{System.unique_integer([:positive])}")
289+
290+
AccountsFixtures.user_fixture()
291+
|> Ecto.Changeset.change(attrs)
292+
|> GameServer.Repo.update!()
293+
end
294+
286295
test "returns the board-wide rank, not the position within the results", %{leaderboard: lb} do
287296
assert [record] = Leaderboards.list_records(lb.id, search: "ada")
288297
assert record.user.display_name == "Ada Lovelace"
@@ -297,7 +306,7 @@ defmodule GameServer.LeaderboardsTest do
297306
end
298307

299308
test "matches a record's own label", %{leaderboard: lb} do
300-
user = AccountsFixtures.user_fixture()
309+
user = searchable_user([])
301310
{:ok, _} = Leaderboards.submit_score(lb.id, user.id, 700, %{})
302311
{:ok, record} = Leaderboards.get_user_record(lb.id, user.id)
303312
GameServer.Repo.update!(Ecto.Changeset.change(record, label: "Guest Runner"))

config/test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ config :game_server_core, async_inline: true
7676
# ticker supervised but idle. Tests drive GameServer.Tournaments.tick/0 directly.
7777
config :game_server_core, GameServer.Tournaments.Ticker, enabled: false
7878

79+
# Same for the matchmaking sweep: no sandbox connection, and on SQLite it
80+
# collides with the test's open write transaction ("database is locked").
81+
# Tests drive GameServer.Matchmaking.Worker.sweep/0 directly.
82+
config :game_server_core, GameServer.Matchmaking.Worker, enabled: false
83+
7984
# Disable app-level caching in tests to avoid stale reads across assertions.
8085
# Still provide the multilevel configuration so the cache can start.
8186
config :game_server_core, GameServer.Cache,

0 commit comments

Comments
 (0)