Docker-Based Tests¶
Backend tests for Redis, MongoDB, PostgreSQL, and RabbitMQ run against real database instances managed by testcontainers.
Prerequisites¶
Docker must be running locally
No manual container setup is needed — testcontainers handles image pull, startup, port mapping, and cleanup automatically
How It Works¶
Each Docker-backed test file follows this pattern:
use testcontainers::runners::AsyncRunner;
use testcontainers_modules::redis::Redis;
async fn make_broker() -> (testcontainers::ContainerAsync<Redis>, RedisBroker) {
// 1. Start a fresh container
let container = Redis::default().start().await.unwrap();
// 2. Get the mapped port
let port = container.get_host_port_ipv4(6379).await.unwrap();
let uri = format!("redis://127.0.0.1:{port}/");
// 3. Create the backend
let broker = RedisBroker::new(RedisPool::new(&uri).unwrap());
// 4. Return both — the container guard keeps Docker alive
(container, broker)
}
The ContainerAsync<T> guard implements Drop — when it goes out of scope,
the container is stopped and removed. Each test function binds it as _c to
keep it alive for the test’s duration:
#[tokio::test]
#[ignore = "requires Docker"]
async fn suite_broker_route_and_retrieve() {
let (_c, broker) = make_broker().await;
test_route_and_retrieve(&broker).await;
}
Running Docker Tests¶
Docker tests are annotated #[ignore = "requires Docker"] and skipped by
default:
# Run only Docker tests for Redis:
cargo test -p rustvello-redis -- --ignored
# Run ALL Redis tests (unit + Docker):
cargo test -p rustvello-redis -- --include-ignored
# Run Docker tests across all backends:
cargo test --workspace -- --ignored
# Run a specific Docker test:
cargo test -p rustvello-redis -- --ignored suite_broker_route_and_retrieve
Backend-Specific Notes¶
Redis¶
Image:
redis:latest(viatestcontainers_modules::redis::Redis)Default port: 6379
Connection:
RedisPool::new(uri)withredis://127.0.0.1:{port}/
MongoDB (v3 driver)¶
Image:
mongo:latest(viatestcontainers_modules::mongo::Mongo)Default port: 27017
Connection:
MongoPool::new(uri)withmongodb://127.0.0.1:{port}/
MongoDB (v2 driver — mongo3)¶
Image:
mongo:latest(viatestcontainers_modules::mongo::Mongo)Default port: 27017
Connection:
Mongo3Pool::new(uri)withmongodb://127.0.0.1:{port}/Uses optimistic CAS for status transitions (no transaction support)
PostgreSQL¶
Image:
postgres:latest(viatestcontainers_modules::postgres::Postgres)Default port: 5432
Connection:
Database::connect(conn_string)with libpq-style connection stringDefault credentials:
user=postgres password=postgres dbname=postgresAuto-migration: The
Database::connect()method runs schema migrations on first connection
RabbitMQ¶
Image:
rabbitmq:latest(viatestcontainers_modules::rabbitmq::RabbitMq)Default port: 5672
Only
Brokertrait is tested (RabbitMQ is a message queue, not a database)
Test Isolation¶
Each test function starts its own container, so tests are fully isolated and can run in parallel. This means:
No shared state between tests
No cleanup needed — containers are ephemeral
Slower than in-memory — container startup adds ~1-3 seconds per test
For faster iteration during development, consider running in-memory backend tests first:
cargo test -p rustvello-mem # Fast: in-memory, no Docker
cargo test -p rustvello-redis -- --ignored # Slower: real Redis
Troubleshooting¶
“Cannot connect to the Docker daemon”¶
Ensure Docker Desktop or dockerd is running:
docker info
Tests hang or time out¶
Testcontainers waits for the container to be “ready” (port open, health check passing). If a container image is being pulled for the first time, it may take longer. Pre-pull images to avoid timeout:
docker pull redis:latest
docker pull mongo:latest
docker pull postgres:latest
docker pull rabbitmq:latest
Port conflicts¶
Testcontainers maps container ports to random host ports, so port conflicts should not occur. If they do, check for stale containers:
docker ps -a | grep testcontainers
docker container prune