commanded / eventstore

Event store using PostgreSQL for persistence
MIT License
1.06k stars 146 forks source link

Setup for Async Testing #190

Closed PJUllrich closed 4 years ago

PJUllrich commented 4 years ago

I have problems running tests asynchonously (that is in parallel) using the EventStore. I was wondering whether it is possible at all to set up the library in a way that supports async tests.

Currently, whenever I have more than around 5 tests that use the EventStore library for testing, they run into race conditions over the database connection with errors like this:

** (exit) exited in: DBConnection.Holder.checkout(EventStore.Postgrex, [timeout: 15000])
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started

My current setup tags function in my test cases (e.g. DataCase) looks like this:

  setup tags do
    :ok = Sandbox.checkout(MyApp.Repo)

    unless tags[:async] do
      Sandbox.mode(MyApp.Repo, {:shared, self()})
    end

    config = EventStore.Config.parsed()
    postgrex_config = EventStore.Config.default_postgrex_opts(config)
    {:ok, eventstore_connection} = Postgrex.start_link(postgrex_config)
    Storage.Initializer.reset!(eventstore_connection)
    {:ok, _} = Application.ensure_all_started(:eventstore)

    on_exit(fn ->
        Application.stop(:eventstore)
        Process.exit(eventstore_connection, :shutdown)
      end)
    end

    :ok
  end
slashdotdash commented 4 years ago

EventStore can be used for async tests as long as you don't attempt to reset the database schema between test runs. The issue you have is that Storage.Initializer.reset!/1 will truncate the tables being used by any EventStore operations running concurrently.

I'd suggest one of these approaches:

Testing with Commanded

Commanded provides an in-memory event store adapter which can be used for testing.

PJUllrich commented 4 years ago

Thank you! Then I'll wait for the next release and consider which option suits my requirements best :)