I have a test in my Phoenix app that is testing a Phoenix.PubSub
subscriber that uses Genserver. The subscriber does some database work as part of its handle_info/2
.
test "sending creating a referral code upon user registration" do
start_supervised(MyApp.Accounts.Subscriber)
user = insert(:user)
Phoenix.PubSub.broadcast(MappApp.PubSub, "accounts", {:register, user})
assert_eventually(Repo.exists?(ReferralCode))
stop_supervised(MyApp.Accounts.Subscriber)
end
Running this test module by itself is fine. However when I run my entire test suite I get an error like so (the test still passes):
[error] GenServer MyApp.Accounts.Subscriber terminating
** (stop) exited in: DBConnection.Holder.checkout(#PID<0.970.0>, [log: #Function<9.124843621/1 in Ecto.Adapters.SQL.with_log/3>, cache_statement: "ecto_insert_referral_codes", timeout: 15000, pool_size: 10, pool: DBConnection.Ownership])
** (EXIT) shutdown: "owner #PID<0.969.0> exited"
<stacktrace...>
This looks like it's an issue with the database connection still being open when the process is terminated so it doesn't die gracefully. But I'm not sure how to deal with this.
Any advice on how to prevent this error?
I ran into this today. Any time you are doing database operations in separate child processes (e.g. database operations triggered inside a
GenStage
orGenServer
et al), then you need to read the Sandbox adapter documentation carefully. There is an FAQ that deals with this error specifically, and the solution can be either to explicitly grant the Sandbox adapter access to the child process like this (from the docs):or you can enabled "shared" mode by altering your test
setup
to set theSandbox
mode:I had more luck with the latter, but be aware that if you are using some other adapter anywhere explicitly (e.g. to make raw database calls), then it might cause tests to fail (because it can no longer get a connection).