s3cur3
s3cur3

Reputation: 3025

Cleanup ExUnit from within the same process (unlike on_exit)

In our codebase, we have lots of tests that involve interacting with the database (via Postgrex). We have a handful of shared ExUnit.CaseTemplates whose setup hook prepares the Ecto sandbox and such, and this works great.

The problem I'm running into is that processes spawned by our tests may still be communicating with the database when the test process exits, so we get errors in the logs that look like this:

09:56:51.517 [error] Postgrex.Protocol (#PID<0.2127.0>) disconnected: ** (DBConnection.ConnectionError) owner #PID<0.11626.0> exited

(The "owner" PID here is the test process, which of course spawned the database connection in its setup.)

Things I've tried:

I gather from spelunking in the Elixir core mailing list that before on_exit/2 existed, there was once a teardown hook that ran synchronously at the end of the test process. I'd really appreciate any solution that could imitate such functionality.

Edited to add: Here's a sample of what our shared ExUnit.CaseTemplate looks like:

defmodule PersistenceTestCase do
  use ExUnit.CaseTemplate

  setup tags do
    # This line would be in test_helper.exs, but it breaks tests not using
    # this test case that have implicit data-persistence side-effects
    Ecto.Adapters.SQL.Sandbox.mode(App.Repo, :manual)

    :ok = Ecto.Adapters.SQL.Sandbox.checkout(App.Repo)

    unless tags[:async] do
      Ecto.Adapters.SQL.Sandbox.mode(App.Repo, {:shared, self()})
    end

    on_exit(fn ->
      # Reset on exit to not interfere with tests not using this test case
      Ecto.Adapters.SQL.Sandbox.mode(App.Repo, :auto)
    end)
  end
end

Upvotes: 2

Views: 580

Answers (0)

Related Questions