[…] migrations cannot run dynamically during test under the Ecto.Adapters.SQL.Sandbox, as the sandbox has to share a single connection across processes to guarantee the changes can be reverted.
I was previously able to run migrations during a test and this allowed me to test from end to end a signup registration.
What would be a good alternative to using Ecto.Migrator from the tests ?
For whoever has a similar issue, the solution for me was to create a second repo dedicated to running the migrations on test:
I struggled a lot with the settings queue_target and queue_interval as reported by my stacktraces, but in the end, I was mislead as I simply forgot to start the new repo.
In my test_helper, I now have:
defmodule Datastore.MigrationRepo do
use Ecto.Repo, [
adapter: Ecto.Adapters.Postgres,
otp_app: :datastore,
migration_lock: nil
]
end
Datastore.MigrationRepo.start_link
At the beginning, I used this repo only for testing, then saw benefits in having it in production as well, in my codebase.
With Ecto3, my migrator module has lost lots of LoC and now looks like this:
defmodule Datastore.Migrator do
@moduledoc false
def run(prefix, repo) do
migrations_path = tenant_migrations_path()
opts =
add_prefix_option( [all: true, log: :info, log_sql: :info ], prefix)
pool = repo.config[:pool]
_migrated =
if function_exported?(pool, :unboxed_run, 2) do
pool.unboxed_run(repo, fn ->
Ecto.Migrator.run(repo, migrations_path, :up, opts)
end)
else
Ecto.Migrator.run(repo, migrations_path, :up, opts)
end
end
defp add_prefix_option(opts, "public"), do: opts
defp add_prefix_option(opts, prefix) do
Keyword.merge(opts, prefix: prefix)
end
# My migrations live in Repo, but could be moved to
# MigrationRepo.
def tenant_migrations_path() do
Path.join(build_repo_priv(Datastore.Repo), "migrations")
end
def build_repo_priv(repo) do
Application.app_dir(
Keyword.fetch!(repo.config(), :otp_app),
source_repo_priv(repo)
)
end
def source_repo_priv(repo) do
repo.config()[:priv] || "priv/#{repo |> Module.split() |> List.last() |> Macro.underscore()}"
end
end