1

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:

  • phoenix web api ("api")
  • core business logic ("core")
  • user authentication ("auth")
  • database schema ("db")

"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.

Thorakas
  • 135
  • 5

1 Answers1

1

Here are few caveats running tests in umbrella mode (as described in error messages)

  1. Your dependent repos need to be "checked out"
  2. Your dependent repos might never started
  3. Your dependent repos might not running in "shared" mode

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
ardhitama
  • 1,949
  • 2
  • 18
  • 29
  • Thank you for your answer. Some thoughts on that: (1) There is only one Repo, the one of the "db" app. The repo is supervised and should be started when the "db" app is started. (2) When I write a test for the "api", the "api" app does not know that there is an ecto repo as the "api" has no direct dependency on "db". This is the reason why I do not know how I can checkout the Repo in my "app" tests. I include this in my question – Thorakas Nov 27 '16 at 21:16
  • @Thorakas my answer still stands, the tests must have the other otp app started. Not sure whether you are in async mode or not – ardhitama Nov 27 '16 at 22:00
  • These tests do not run in async mode. I also have configured the "api" project to require "core" and "auth" to be started, which themselves require "db" to be started. As I have stated before, I do not know how to apply your answer on my situation. I cannot check out the `Db.Repo` as this module is not known in the "api" project. – Thorakas Nov 29 '16 at 16:27
  • @Thorakas answer updated, with adding Db's dependency – ardhitama Nov 30 '16 at 04:34