prop/test/test_helper.exs
Graham McIntire 05d038abcd
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 5m12s
fix: Elixir 1.20 test suite compatibility
- Use DBConnection.Ownership pool (not Ecto.Adapters.SQL.Sandbox) to
  satisfy Ecto 3.14's Sandbox.start_owner!/2 pool check
- Set pool in config/test.exs and config/runtime.exs before app start
- mix test --no-start via alias prevents Mix from launching app before
  test_helper can configure the sandbox pool
- ExUnit.start() without capture_log: true avoids Logger cascade
- :auto sandbox mode lets background processes (migrations, backfill,
  Oban) access the DB during Application boot
- Load test support modules and dep ebin paths in test_helper for
  Elixir 1.20 lazy test compilation
2026-08-02 16:44:53 -05:00

62 lines
2.7 KiB
Elixir

alias Ecto.Adapters.SQL.Sandbox
# Elixir 1.20 loads test_helper before dependency ebin dirs are on the
# code path. Add them manually so `use` / `import` in test files can
# resolve modules from :only test deps (Mox, ExUnitProperties, etc.).
for dep_dir <- Path.wildcard("_build/test/lib/*/ebin") do
:code.add_patha(String.to_charlist(dep_dir))
end
# Ensure test support modules are compiled and loaded before ExUnit
# starts lazily compiling the test suite. The parallel compiler workers
# inherit the code server state, so loading them here makes them visible
# everywhere.
Code.require_file("test/support/data_case.ex")
Code.require_file("test/support/conn_case.ex")
Code.require_file("test/support/fixtures/accounts_fixtures.ex")
Code.require_file("test/support/fixtures/beacons_fixtures.ex")
# ExUnit.start/1 with capture_log: true starts :logger, which cascades
# into the full OTP application. mix.exs now runs `mix test --no-start`
# so *we* control when the app boots. Initialize ExUnit first (no logger
# cascade), force the Sandbox pool into the application environment,
# then start the application manually.
ExUnit.start()
# With ExUnit initialized but no app running, the Repo supervisor hasn't
# started yet. Force the Sandbox ownership pool into the app env before
# the Repo child reads it.
for repo <- [Microwaveprop.Repo, Microwaveprop.AprsRepo] do
existing = Application.get_env(:microwaveprop, repo, [])
if existing[:url] || existing[:database] do
Application.put_env(:microwaveprop, repo, Keyword.put(existing, :pool, DBConnection.Ownership))
end
end
# Now start the full OTP app. The Repo supervisor reads pool:
# DBConnection.Ownership from the app env and initializes with it.
{:ok, _} = Application.ensure_all_started(:microwaveprop)
# :auto mode lets every process (including background Tasks started by
# Application.init and Oban workers) auto-checkout from the sandbox.
# DataCase.setup_sandbox/1 still calls start_owner!/2 for per-test
# isolation, which is compatible with :auto mode.
Sandbox.mode(Microwaveprop.Repo, :auto)
Sandbox.mode(Microwaveprop.AprsRepo, :auto)
# Silence sandbox-cleanup disconnect noise. When a test process exits
# while still owning a Postgrex connection, the protocol logs an
# `[error] Postgrex.Protocol ... disconnected: ... client #PID<...>
# exited`. It's benign — the connection is being torn down on purpose
# — but at :error level it bypasses `capture_log: true` (which only
# captures logs from the test process). Pinning these modules to
# :critical drops the noise without affecting real DB error logging.
Logger.put_module_level(
[Postgrex.Protocol, DBConnection.Connection],
:critical
)
if Code.ensure_loaded?(Mox) do
Mox.defmock(Microwaveprop.Valkey.MockAdapter, for: Microwaveprop.Valkey.Adapter)
end