Files
attune/crates/common/tests
David Culbreth 13749409cd
Some checks failed
CI / Rust Blocking Checks (push) Failing after 22s
CI / Web Blocking Checks (push) Failing after 26s
CI / Security Blocking Checks (push) Successful in 9s
CI / Web Advisory Checks (push) Successful in 32s
CI / Security Advisory Checks (push) Has been cancelled
making linters happy
2026-03-04 23:44:45 -06:00
..
2026-03-03 14:16:23 -06:00
2026-02-27 16:34:17 -06:00
2026-02-04 17:46:30 -06:00
2026-03-04 22:42:23 -06:00
2026-03-04 23:44:45 -06:00
2026-02-04 17:46:30 -06:00
2026-03-04 23:44:45 -06:00
2026-02-04 17:46:30 -06:00

Attune Common Library - Integration Tests

This directory contains integration tests for the Attune common library, specifically testing the database repository layer and migrations.

Overview

The test suite includes:

  • Migration Tests (migration_tests.rs) - Verify database schema, migrations, and constraints
  • Repository Tests - Comprehensive CRUD and transaction tests for each repository:
    • pack_repository_tests.rs - Pack repository operations
    • action_repository_tests.rs - Action repository operations
    • Additional repository tests for all other entities
  • Test Helpers (helpers.rs) - Fixtures, utilities, and common test setup

Prerequisites

Before running the tests, ensure you have:

  1. PostgreSQL installed and running
  2. Test database created and configured
  3. Environment variables set (via .env.test)

Setting Up the Test Database

# Create the test database
make db-test-create

# Run migrations on test database
make db-test-migrate

# Or do both at once
make db-test-setup

To reset the test database:

make db-test-reset

Running Tests

Run All Integration Tests

# Automatic setup and run
make test-integration

# Or manually
cargo test --test '*' -p attune-common -- --test-threads=1

Run Specific Test Files

# Run only migration tests
cargo test --test migration_tests -p attune-common

# Run only pack repository tests
cargo test --test pack_repository_tests -p attune-common

# Run only action repository tests
cargo test --test action_repository_tests -p attune-common

Run Specific Tests

# Run a single test by name
cargo test test_create_pack -p attune-common

# Run tests matching a pattern
cargo test test_create -p attune-common

# Run with output
cargo test test_create_pack -p attune-common -- --nocapture

Test Configuration

Test configuration is loaded from .env.test in the project root. Key settings:

# Test database URL
ATTUNE__DATABASE__URL=postgresql://postgres:postgres@localhost:5432/attune_test

# Enable SQL logging for debugging
ATTUNE__DATABASE__LOG_STATEMENTS=true

# Verbose logging
ATTUNE__LOG__LEVEL=debug
RUST_LOG=debug,sqlx=warn

Test Structure

Test Helpers (helpers.rs)

The helpers module provides:

  • Database Setup: create_test_pool(), clean_database()
  • Fixtures: Builder pattern for creating test data
    • PackFixture - Create test packs
    • ActionFixture - Create test actions
    • RuntimeFixture - Create test runtimes
    • And more for all entities
  • Utilities: Transaction helpers, assertions

Example fixture usage:

use helpers::*;

let pool = create_test_pool().await.unwrap();
clean_database(&pool).await.unwrap();

let pack_repo = PackRepository::new(&pool);

// Use fixture to create test data
let pack = PackFixture::new("test.pack")
    .with_version("2.0.0")
    .with_name("Custom Pack Name")
    .create(&pack_repo)
    .await
    .unwrap();

Test Organization

Each test file follows this pattern:

  1. Import helpers module: mod helpers;
  2. Setup phase: Create pool and clean database
  3. Test execution: Perform operations
  4. Assertions: Verify expected outcomes
  5. Cleanup: Automatic via clean_database() or transactions

Example test:

#[tokio::test]
async fn test_create_pack() {
    // Setup
    let pool = create_test_pool().await.unwrap();
    clean_database(&pool).await.unwrap();
    
    let repo = PackRepository::new(&pool);
    
    // Execute
    let pack = PackFixture::new("test.pack")
        .create(&repo)
        .await
        .unwrap();
    
    // Assert
    assert_eq!(pack.ref_name, "test.pack");
    assert!(pack.created_at.timestamp() > 0);
}

Test Categories

CRUD Operations

Tests verify basic Create, Read, Update, Delete operations:

  • Creating entities with valid data
  • Retrieving entities by ID and other fields
  • Listing and pagination
  • Updating partial and full records
  • Deleting entities

Constraint Validation

Tests verify database constraints:

  • Unique constraints (e.g., pack ref_name + version)
  • Foreign key constraints
  • NOT NULL constraints
  • Check constraints

Transaction Support

Tests verify transaction behavior:

  • Commit preserves changes
  • Rollback discards changes
  • Isolation between transactions

Error Handling

Tests verify proper error handling:

  • Duplicate key violations
  • Foreign key violations
  • Not found scenarios

Cascading Deletes

Tests verify cascade delete behavior:

  • Deleting a pack deletes associated actions
  • Deleting a runtime deletes associated workers
  • And other cascade relationships

Best Practices

1. Clean Database Before Tests

Always clean the database at the start of each test:

let pool = create_test_pool().await.unwrap();
clean_database(&pool).await.unwrap();

2. Use Fixtures for Test Data

Use fixture builders instead of manual creation:

// Good
let pack = PackFixture::new("test.pack").create(&repo).await.unwrap();

// Avoid
let create = CreatePack { /* ... */ };
let pack = repo.create(&create).await.unwrap();

3. Test Isolation

Each test should be independent:

  • Don't rely on data from other tests
  • Clean database between tests
  • Use unique names/IDs

4. Single-Threaded Execution

Run integration tests single-threaded to avoid race conditions:

cargo test -- --test-threads=1

5. Descriptive Test Names

Use clear, descriptive test names:

#[tokio::test]
async fn test_create_pack_duplicate_ref_version() { /* ... */ }

6. Test Both Success and Failure

Test both happy paths and error cases:

#[tokio::test]
async fn test_create_pack() { /* success case */ }

#[tokio::test]
async fn test_create_pack_duplicate_ref_version() { /* error case */ }

Debugging Tests

Enable SQL Logging

Set in .env.test:

ATTUNE__DATABASE__LOG_STATEMENTS=true
RUST_LOG=debug,sqlx=debug

Run with Output

cargo test test_name -- --nocapture

Use Transaction Rollback

Wrap tests in transactions that rollback to inspect state:

let mut tx = pool.begin().await.unwrap();
// ... test operations ...
// Drop tx without commit to rollback

Check Database State

Connect to test database directly:

psql -d attune_test -U postgres

Continuous Integration

For CI environments:

# Setup test database
createdb attune_test
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/attune_test sqlx migrate run

# Run tests
cargo test --test '*' -p attune-common -- --test-threads=1

Common Issues

Database Connection Errors

Issue: Cannot connect to database

Solution:

  • Ensure PostgreSQL is running
  • Check credentials in .env.test
  • Verify test database exists

Migration Errors

Issue: Migrations fail

Solution:

  • Run make db-test-reset to reset test database
  • Ensure migrations are in migrations/ directory

Flaky Tests

Issue: Tests fail intermittently

Solution:

  • Run single-threaded: --test-threads=1
  • Clean database before each test
  • Avoid time-dependent assertions

Foreign Key Violations

Issue: Cannot delete entity due to foreign keys

Solution:

  • Use clean_database() which handles dependencies
  • Test cascade deletes explicitly
  • Delete in correct order (children before parents)

Adding New Tests

To add tests for a new repository:

  1. Create test file: tests/<entity>_repository_tests.rs
  2. Import helpers: mod helpers;
  3. Create fixtures in helpers.rs if needed
  4. Write comprehensive CRUD tests
  5. Test constraints and error cases
  6. Test transactions
  7. Run and verify: cargo test --test <entity>_repository_tests

Test Coverage

To generate test coverage reports:

# Install tarpaulin
cargo install cargo-tarpaulin

# Generate coverage
cargo tarpaulin --out Html --output-dir coverage --test '*' -p attune-common

Additional Resources

Support

For issues or questions:

  • Check existing tests for examples
  • Review helper functions in helpers.rs
  • Consult the main project documentation
  • Open an issue on the project repository