re-uploading work

This commit is contained in:
2026-02-04 17:46:30 -06:00
commit 3b14c65998
1388 changed files with 381262 additions and 0 deletions

View File

@@ -0,0 +1,391 @@
# 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
```bash
# 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:
```bash
make db-test-reset
```
## Running Tests
### Run All Integration Tests
```bash
# Automatic setup and run
make test-integration
# Or manually
cargo test --test '*' -p attune-common -- --test-threads=1
```
### Run Specific Test Files
```bash
# 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
```bash
# 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:
```bash
# 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:
```rust
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:
```rust
#[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:
```rust
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:
```rust
// 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:
```bash
cargo test -- --test-threads=1
```
### 5. Descriptive Test Names
Use clear, descriptive test names:
```rust
#[tokio::test]
async fn test_create_pack_duplicate_ref_version() { /* ... */ }
```
### 6. Test Both Success and Failure
Test both happy paths and error cases:
```rust
#[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`:
```bash
ATTUNE__DATABASE__LOG_STATEMENTS=true
RUST_LOG=debug,sqlx=debug
```
### Run with Output
```bash
cargo test test_name -- --nocapture
```
### Use Transaction Rollback
Wrap tests in transactions that rollback to inspect state:
```rust
let mut tx = pool.begin().await.unwrap();
// ... test operations ...
// Drop tx without commit to rollback
```
### Check Database State
Connect to test database directly:
```bash
psql -d attune_test -U postgres
```
## Continuous Integration
For CI environments:
```bash
# 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:
```bash
# Install tarpaulin
cargo install cargo-tarpaulin
# Generate coverage
cargo tarpaulin --out Html --output-dir coverage --test '*' -p attune-common
```
## Additional Resources
- [SQLx Documentation](https://docs.rs/sqlx)
- [Tokio Testing Guide](https://tokio.rs/tokio/topics/testing)
- [Rust Testing Best Practices](https://doc.rust-lang.org/book/ch11-00-testing.html)
## 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