#How do I reuse a pog db pool over multiple tests.

1 messages · Page 1 of 1 (latest)

shrewd swan
#

I'm currently using the following helper in my tests.
I'm seeing the error ConnectionUnavailable when I run it now. only in one test. I guess the problems is I start the pool per test.
Is there a way to have a transaction per test but not a pool? is that the right approach to db testing? Does anyone have an example that's public?

pub fn test_context(then) {
  // Only the db service should be accessed during tests
  let assert Ok(postgres_password) = envoy.get("POSTGRES_PASSWORD")
  let config =
    config.Config(
      postgres_pool_name: process.new_name("postgres_pool"),
      postgres_password:,
    )
  let assert Ok(context) = context.from_config(config)

  let assert Ok(conn) = pool.start(config)

  let assert Error(pog.TransactionRolledBack(Nil)) =
    pog.transaction(conn.data, fn(db) {
      let ai = process.new_subject()

      let context = context.Context(..context, db:, ai:)
      then(context, ai)
      Error(Nil)
    })
}
quiet gull
#

If you make a connection per test you'll exhaust the db's connections eventually

#

which could be what happened here

#

I would create one pool with several (20?) connections before running the tests, and use that as a global singleton

#

Unfortunately gleeunit doesn't have a way to pass in state to all tests, so you'll need to cheat somehow

#

You could modify the test_context to then refer to that pool instead of creating a new one, still using the transaction approach you have there for cleanup

maiden shuttle
#

heh, i wrote a test framework to circumvent the global singleton. not ideal, either.

shrewd swan
#

I've ended up using an atom and writing my own unsafe_cast_to_name seems simpler than a new dependency for global_value

shrewd swan
#

This is my approach
In test_helpers.gleam

@external(erlang, "server_ffi", "identity")
fn unsafe_global_name(atom: Atom) -> Name(a)

/// The one place where we assert the message type of this global singleton
pub fn test_pool_name() -> Name(pog.Message) {
  unsafe_global_name(atom.create("server_test_postgres_pool"))
}

in main test file

import gleeunit
import server/db/pool
import server/test_helpers

pub fn main() -> Nil {
  let config = test_helpers.test_config()
  let assert Ok(_) = pool.start(config)
  gleeunit.main()
}