Test failure due to Ecto and async task

693 views Asked by At

Interesting issue I'm getting. I have a test that deals with file uploading using arc-ecto. In the uploader module I override storage_dir function. There I do a database call to fetch id of the parent record of the thing I'm uploading. Works great in practice.

Tests freak out though. I'm guessing it has something to do with the fact that file saving is an async task. So test finishes before file is saved. Database connection is closed and uploader errors out. Here's the error:

15:33:10.457 [error] Postgrex.Protocol (#PID<0.325.0>) disconnected: ** (DBConnection.ConnectionError) owner #PID<0.535.0> exited while client #PID<0.538.0> is still running with: shutdown

15:33:10.645 [error] Postgrex.Protocol (#PID<0.331.0>) disconnected: ** (DBConnection.ConnectionError) owner #PID<0.596.0> exited while client #PID<0.599.0> is still running with: shutdown

15:33:10.674 [error] Task #PID<0.599.0> started from #PID<0.598.0> terminating
** (DBConnection.ConnectionError) tcp recv: closed
    (ecto) lib/ecto/adapters/postgres/connection.ex:115: Ecto.Adapters.Postgres.Connection.execute/4
    (ecto) lib/ecto/adapters/sql.ex:243: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:441: Ecto.Adapters.SQL.execute_or_reset/7
    (ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:35: Ecto.Repo.Queryable.all/4
    (ecto) lib/ecto/repo/queryable.ex:68: Ecto.Repo.Queryable.one/4
    (pedal_app) lib/pedal_app/web/uploaders/photo_uploader.ex:31: PedalApp.Web.PhotoUploader.storage_dir/2
    lib/arc/storage/local.ex:33: Arc.Storage.Local.build_local_path/3
    lib/arc/storage/local.ex:27: Arc.Storage.Local.delete/3
    (elixir) lib/task/supervised.ex:85: Task.Supervised.do_apply/2
    (elixir) lib/task/supervised.ex:36: Task.Supervised.reply/5
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Function: #Function<0.51838860/0 in Arc.Actions.Delete.async_delete_version/3>
    Args: []

Is this a common thing? How can I tell my test not to bail until everything is done?

Edit: My work-around is to do a preload for everything so I don't do db calls in the uploader. But question still stands.

1

There are 1 answers

0
Marcos Tapajós On

You can disable asynchronous processing adding @async false to your upload definition.

I'm sure that you don't want to disable it in dev/production, only on tests.

I would try this:

On config/test.exs you can add:

config :project_name, arc_async: false

On your uploader definition you can add:

@async Application.get_env(:project_name, :arc_async, true)

I didn't test it, so, not sure if it will work but at least is something to try.