Reputation: 135
I am working on a phoenix application. This application is part of an umbrella app. In this umbrella I have small applications responsible for different areas for the application, which are:
"api" depends upon both "core" and "auth", while these two applications depend upon "db".
Only the "db" app has an ecto repo, all other apps don't. The repo is started by the "db" app and is supervised.
Now I want to test my controllers in the "api" application. This is where I run into an issue with ecto. When I test a controller action this action will call a function from "auth" or "core", which calls functions of the Repo
from "db" (such as Repo.insert/2
). This results in a OwnershipError
:
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.458.0>.
When using ownership, you must manage connections in one
of the three ways:
* By explicitly checking out a connection
* By explicitly allowing a spawned process
* By running the pool in shared mode
The first two options require every new process to explicitly
check a connection out or be allowed by calling checkout or
allow respectively.
The third option requires a {:shared, pid} mode to be set.
If using shared mode in tests, make sure your tests are not
async.
If you are reading this error, it means you have not done one
of the steps above or that the owner process has crashed.
See Ecto.Adapters.SQL.Sandbox docs for more information.
My problem now is that I do not know how I can fix this error using the suggested solutions in the "api" tests as the "api" application does not know the "db" application and therefore cannot do a connection checkout. When I encountered this error on an application which directly depended upon the "db" project I was able to apply the "shared mode" solution.
My question would be how I can solve the ownership problem with my "api" integration tests.
Upvotes: 1
Views: 849
Reputation: 1982
Here are few caveats running tests in umbrella mode (as described in error messages)
From there, perhaps your test_helper.exs
might looks like this (pseudocode):
ExUnit.start
Db.Repo.start_link()
Core.Repo.start_link()
Auth.Repo.start_link()
Ecto.Adapters.SQL.Sandbox.checkout(Db.Repo)
Ecto.Adapters.SQL.Sandbox.checkout(Core.Repo)
Ecto.Adapters.SQL.Sandbox.checkout(Auth.Repo)
Ecto.Adapters.SQL.Sandbox.mode(Api.Repo, :manual)
Ecto.Adapters.SQL.Sandbox.mode(Db.Repo, :shared)
Ecto.Adapters.SQL.Sandbox.mode(Core.Repo, :shared)
Ecto.Adapters.SQL.Sandbox.mode(Auth.Repo, :shared)
Update:
Don't forget to include DB's project path in mix.exs
defp deps do
[
...
{:db, path: "path/to/db"},
...
]
end
Upvotes: 1