dwyl / learn-phoenix-framework

:fire: Phoenix is the web framework without compromise on speed, reliability or maintainability! Don't settle for less. :rocket:
648 stars 45 forks source link

** (DBConnection.OwnershipError) cannot find ownership process for #PID #128

Open nelsonic opened 5 years ago

nelsonic commented 5 years ago

When attempting to create/run a test that inserts data:

defmodule UseragentTest do
  use ExUnit.Case
  alias Hits.Useragent

  test "Useragent.insert" do
    useragent = "Mozilla/5.0 (Windows; Windows NT 5.0; rv:1.1) Gecko/20020826"
    ip = "127.0.0.1"
    useragent_id = Useragent.insert(%Useragent{name: useragent, ip: ip})

    IO.inspect(useragent_id, label: "useragent_id")
  end

end

attempting to run it with the command:

mix test test/useragent_test.exs

I get the following error:

  1) test Useragent.insert (UseragentTest)
     test/useragent_test.exs:8
     ** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.390.0>.

     When using ownership, you must manage connections in one
     of the four ways:

     * By explicitly checking out a connection
     * By explicitly allowing a spawned process
     * By running the pool in shared mode
     * By using :caller option with allowed process

     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.

     The fourth option requires [caller: pid] to be used when
     checking out a connection from the pool. The caller process
     should already be allowed on a connection.

     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.
     code: useragent_id = Useragent.insert(%Useragent{name: useragent, ip: ip})
     stacktrace:
       (ecto_sql) lib/ecto/adapters/sql.ex:602: Ecto.Adapters.SQL.raise_sql_call_error/1
       (ecto_sql) lib/ecto/adapters/sql.ex:538: Ecto.Adapters.SQL.execute/5
       (ecto) lib/ecto/repo/queryable.ex:153: Ecto.Repo.Queryable.execute/4
       (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
       (ecto) lib/ecto/repo/queryable.ex:67: Ecto.Repo.Queryable.one/3
       (hits) lib/hits/useragent.ex:31: Hits.Useragent.insert/1
       test/useragent_test.exs:11: (test)

Obviously the Useragent.insert works when I run the app mix phx.server ... But the test does not run because it does not have ownership of the connection ... 😞

nelsonic commented 5 years ago

After reading: https://hexdocs.pm/ecto_sql/Ecto.Adapters.SQL.Sandbox.html

Add the following code to the top of the test:

  setup do
    # Explicitly get a connection before each test
    :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo)
  end

Now the test runs as expected:

Finished in 0.05 seconds
1 test, 0 failures
HoffsMH commented 5 years ago

@nelsonic I wonder if the intended path is to use MyApp.Datacase instead of use ExUnit.Case as defined in test/support/data_case.ex

Had this problem myself what do you think?

EDIT: oops I guess its model_case.ex for older versions of phoenix

nelsonic commented 5 years ago

@HoffsMH good thinking! 💡

romenigld commented 5 years ago

Thank's @nelsonic !

jarrodmoldrich commented 3 years ago

I wonder if the intended path is to use MyApp.Datacase instead of use ExUnit.Case as defined in test/support/data_case.ex

Because I ran into an intermittent error with this, it's worth noting: when you're implicitly affecting a repo controlled by another module in a test, you'll still need to do an explicit checkout(..).