loco-rs/loco · error
db connection should success
Error message
db connection should success
What it means
In Loco's test support, the Postgres `init_db` connects to the server using a root/admin connection string before creating the per-test database. `Pool::connect` failing (server unreachable, bad credentials, wrong port) triggers `.expect("db connection should success")`, panicking the test-support boot with no retry.
Solutions
- Verify the test DB connection string (host, port, user, password) and start Postgres: `docker run -p 5432:5432 -e POSTGRES_PASSWORD=... postgres` or `docker compose up -d db`
- Check the env var feeding the test config (`LOCO_CONFIG_DATABASE_URI` / test.yaml `database.uri`) resolves correctly in the test environment
- Add a Postgres service container in CI before the test step and wait for readiness (healthcheck/pg_isready)
- Confirm the root user has CREATEDB privilege so subsequent schema creation can succeed
Example fix
// before (test.yaml) database: uri: "postgres://loco:secret@localhost:5433/loco_test" // after — match the running server # psql -h localhost -p 5432 -U postgres -c 'select 1' # verify first database: uri: "postgres://postgres:postgres@localhost:5432/loco_test"
Defensive patterns
Strategy: retry
Validate before calling
// Readiness probe before running tests
let ok = tokio::net::TcpStream::connect("127.0.0.1:5432").await.is_ok();
assert!(ok, "Postgres not reachable on 127.0.0.1:5432");
// Or: pg_isready -h localhost -p 5432 Try / catch
// Wrap test-support boot and fail with a readable message
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
// boot_test / request::<App,_,_> setup
})) {
Ok(v) => v,
Err(_) => panic!("test DB unreachable — is Postgres running and is the root URI correct?"),
} Prevention
- Start Postgres (docker compose) before cargo test in scripts and CI
- Verify the test connection string with psql first
- Add a CI healthcheck/wait step (pg_isready) before tests
- Give the test root user CREATEDB privileges
When it happens
Trigger: Running tests when the Postgres server at the configured `root_connection_string` is down, the URL has a wrong host/port/user/password, the database does not accept the root user, or networking/DNS in CI cannot reach the DB.
Common situations: Forgetting to start Postgres locally (`docker compose up db`), wrong `DATABASE_URL`-style test env var, CI runner without a Postgres service container, auth errors like `password authentication failed for user postgres`.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- create DB schema
- Drop database
- db cleanup thread panicked
- create cleanup runtime
- Could not delete sqlite test db
AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12).
Data as JSON: /api/errors/c2b72d79d0305753.
Report an issue: GitHub.
Appendix: source
Thrown at src/testing/db.rs:121
Ok(Self {
root_connection_string: root_url.to_string(),
connection_string: test_url.to_string(),
schema_name: test_schema_name,
})
}
}
impl TestSupport for PostgresTest {
fn get_connection_str(&self) -> &str {
&self.connection_string
}
fn init_db<'a>(&'a self) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let pool = Pool::<Postgres>::connect(&self.root_connection_string)
.await
.expect("db connection should success");
let query = format!("CREATE DATABASE {};", self.schema_name);
sqlx::query(AssertSqlSafe(query))
.execute(&pool)
.await
.expect("create DB schema");
})
}
fn cleanup_db(&self) {
let connection_string = self.root_connection_string.clone();
let table_name = self.schema_name.clone();
// Run the drop on a dedicated OS thread with its own runtime (not
// `tokio::task::spawn_blocking`, which schedules onto the ambient
// runtime and cannot be awaited from a sync/Drop context) and `.join()`
// it so cleanup fully completes before `cleanup_db` returns. This is
// safe to call from `Drop::drop` since nothing here is `.await`ed onView on GitHub (pinned to 23639d1e36)