# Testing Guide
WarpDrive includes comprehensive unit and integration tests covering all major features.
## Quick Start
**Run all tests with Docker Compose** (recommended - includes PostgreSQL and Redis):
```bash
docker-compose up --build test
```
**Run tests locally** (requires PostgreSQL and Redis):
```bash
# Start services
docker-compose up -d postgres redis
# Set environment variables
export WARPDRIVE_DATABASE_URL=postgresql://warpdrive:warpdrive_test@localhost:5432/warpdrive_test
export WARPDRIVE_REDIS_URL=redis://localhost:6379
# Run tests
cargo test --workspace --all-features
```
## Test Structure
### Unit Tests
Located in `src/` alongside implementation code using `#[cfg(test)]` modules:
```bash
# Run all unit tests
cargo test --lib
# Run specific module tests
cargo test --lib cache
cargo test --lib middleware
cargo test --lib router
```
### Integration Tests
Located in `tests/`:
- `config_test.rs` — Configuration parsing and validation
- `memory_cache_test.rs` — In-memory LRU cache
- `redis_test.rs` — Redis distributed cache (requires Redis)
- `postgres_test.rs` — PostgreSQL connection and LISTEN/NOTIFY (requires PostgreSQL)
- `process_supervisor_test.rs` — Process supervision
- `mock-upstream.rs` — Test HTTP server
```bash
# Run integration tests
cargo test --test '*'
# Run specific integration test
cargo test --test redis_test
cargo test --test postgres_test
```
## Docker Compose Test Services
The `docker-compose.yml` includes services for testing:
### PostgreSQL (`postgres`)
- **Image**: `postgres:17-alpine`
- **Port**: `5432`
- **Database**: `warpdrive_test`
- **User/Password**: `warpdrive` / `warpdrive_test`
- **Schema**: Auto-loaded from `tests/fixtures/schema.sql`
- **Health Check**: `pg_isready`
### Redis (`redis`)
- **Image**: `redis:7-alpine`
- **Port**: `6379`
- **Persistence**: AOF enabled
- **Health Check**: `redis-cli ping`
### Test Runner (`test`)
- **Dockerfile**: `Dockerfile.test`
- **Dependencies**: Waits for PostgreSQL and Redis to be healthy
- **Volumes**: Mounts source code and caches cargo registry + target
- **Environment**:
- `WARPDRIVE_DATABASE_URL=postgresql://warpdrive:warpdrive_test@postgres:5432/warpdrive_test`
- `WARPDRIVE_REDIS_URL=redis://redis:6379`
- `RUST_LOG=debug`
- `RUST_BACKTRACE=1`
## Running Tests
### Full Test Suite
```bash
# Docker Compose (isolated environment)
docker-compose up --build test
# Local (faster if services already running)
docker-compose up -d postgres redis
cargo test --workspace --all-features
```
### Specific Test Categories
**Cache Tests:**
```bash
# Memory cache only (no services needed)
cargo test --lib cache::memory
# Redis cache (requires Redis)
cargo test --test redis_test
# PostgreSQL invalidation (requires PostgreSQL)
cargo test --test postgres_test
```
**Middleware Tests:**
```bash
cargo test --lib middleware::rate_limit
cargo test --lib middleware::circuit_breaker
cargo test --lib middleware::headers
```
**Router Tests:**
```bash
cargo test --lib router
```
**ACME Tests:**
```bash
cargo test --lib acme
```
### Test Output Options
```bash
# Show test output (useful for debugging)
cargo test -- --nocapture
# Run tests serially (helpful for database tests)
cargo test -- --test-threads=1
# Show ignored tests
cargo test -- --ignored
# Run with verbose output
cargo test -- --nocapture --test-threads=1
```
## Test Environment Variables
Tests use these environment variables (auto-configured in Docker Compose):
```bash
# PostgreSQL connection
WARPDRIVE_DATABASE_URL=postgresql://warpdrive:warpdrive_test@localhost:5432/warpdrive_test
# Redis connection
WARPDRIVE_REDIS_URL=redis://localhost:6379
# Logging (optional)
RUST_LOG=debug
RUST_BACKTRACE=1
```
## Continuous Integration
For CI environments (GitHub Actions, GitLab CI, etc.):
```yaml
# Example GitHub Actions workflow
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:17-alpine
env:
POSTGRES_USER: warpdrive
POSTGRES_PASSWORD: warpdrive_test
POSTGRES_DB: warpdrive_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-cargo-target-${{ hashFiles('**/Cargo.lock') }}
- name: Initialize database
run: |
PGPASSWORD=warpdrive_test psql -h localhost -U warpdrive -d warpdrive_test -f tests/fixtures/schema.sql
- name: Run tests
env:
WARPDRIVE_DATABASE_URL: postgresql://warpdrive:warpdrive_test@localhost:5432/warpdrive_test
WARPDRIVE_REDIS_URL: redis://localhost:6379
run: cargo test --workspace --all-features
```
## Test Coverage
Generate code coverage report:
```bash
# Install tarpaulin
cargo install cargo-tarpaulin
# Generate coverage
cargo tarpaulin --workspace --all-features --out Html --output-dir coverage
# Open report
open coverage/index.html
```
## Troubleshooting
### Tests Hang
**Symptom**: Tests appear to hang indefinitely
**Cause**: Usually waiting for PostgreSQL or Redis connection
**Solution**:
```bash
# Check services are running
docker-compose ps
# Check service health
docker-compose logs postgres
docker-compose logs redis
# Restart services
docker-compose restart postgres redis
```
### Connection Refused
**Symptom**: `Connection refused` errors
**Cause**: PostgreSQL or Redis not running or wrong port
**Solution**:
```bash
# Verify services are listening
docker-compose ps
# Check environment variables
echo $WARPDRIVE_DATABASE_URL
echo $WARPDRIVE_REDIS_URL
```
### Permission Denied
**Symptom**: `permission denied` or `could not connect` to PostgreSQL
**Cause**: Database user/password mismatch
**Solution**:
```bash
# Recreate PostgreSQL service
docker-compose down -v postgres
docker-compose up -d postgres
# Verify connection manually
docker-compose exec postgres psql -U warpdrive -d warpdrive_test
```
### Tests Fail Sporadically
**Symptom**: Tests pass sometimes, fail other times
**Cause**: Race conditions or shared state
**Solution**:
```bash
# Run tests serially
cargo test -- --test-threads=1
# Check for test isolation issues
cargo test --lib -- --test-threads=1 --nocapture
```
## Writing New Tests
### Unit Test Template
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_feature_name() {
// Arrange
let input = setup_test_data();
// Act
let result = function_under_test(input);
// Assert
assert_eq!(result, expected_value);
}
#[tokio::test]
async fn test_async_feature() {
// Async test using tokio runtime
let result = async_function().await;
assert!(result.is_ok());
}
}
```
### Integration Test Template
```rust
// tests/my_feature_test.rs
use wrap_drive::*;
#[tokio::test]
async fn test_feature_integration() {
// Setup
let config = Config::default();
// Test
let result = integration_function(config).await;
// Verify
assert!(result.is_ok());
}
```
## Test Data
Test fixtures are in `tests/fixtures/`:
- `schema.sql` — PostgreSQL database schema
- Add other test data files as needed
## Performance Tests
```bash
# Run benchmarks (if added)
cargo bench
# Profile tests
cargo test --release -- --nocapture
```