Files
foxhunt/services/AGENT_22_TEST_PATTERNS.md
jgrusewski 9ffdb03e89 🚀 Wave 134: Zero Compilation Errors - 65 Agents, 194 Fixes, 530+ Tests
## Summary
- **Total Agents**: 65 (24 coverage + 41 error fixes)
- **Compilation Errors**: 194 → 0 
- **New Tests**: 530+ tests (~17,500 lines)
- **Success Rate**: 100%

## Phase 1: Test Coverage Expansion (Waves 1-3)
- Wave 1-3: 24 agents deployed
- Created comprehensive test suites across all modules
- Added 530+ tests for baseline, advanced, and integration coverage

## Phase 2: Error Elimination (Waves 4-14)
- Wave 4 (12 agents): Fixed 162 errors (Enum Display, tower util, borrow checker)
- Wave 7 (1 agent): Fixed 52 ML proto errors (DataSource, Hyperparameters)
- Wave 8 (1 agent): Fixed 33 Trading proto errors (SubmitOrderRequest)
- Wave 12 (4 agents): Fixed 13 ComplianceRequirements field errors
- Wave 13 (3 agents): Fixed 16 data crate test errors
- Wave 14 (2 agents): Fixed final 2 data lib errors

## Infrastructure Improvements
- Added MinIO Docker service for S3 E2E testing
- Created S3Config::for_minio_testing() helper
- Added storage test_helpers module
- Fixed proto field mappings across all services
- Added tower "util" feature for ServiceExt

## Key Error Patterns Fixed
- Proto field name changes (120+ instances)
- Enum Display trait usage (31 instances)
- Borrow checker errors (20+ instances)
- Missing methods/features (40+ instances)
- Struct field additions (Order, ComplianceRequirements)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 17:06:02 +02:00

5.8 KiB

Agent 22: Health Check Test Patterns Reference

Test Pattern Examples

1. Basic Health Check Pattern

#[tokio::test]
async fn test_health_check_basic_healthy() {
    let state = MockHealthState::new();
    let app = create_health_router(state.clone());

    let response = app
        .oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
        .await
        .unwrap();

    assert_eq!(response.status(), StatusCode::OK);
}

2. Dependency Failure Pattern

#[tokio::test]
async fn test_database_disconnection() {
    let state = MockHealthState::new();
    state.set_database_connected(false).await;
    let app = create_health_router(state.clone());

    let response = app
        .oneshot(Request::builder().uri("/health/deep").body(Body::empty()).unwrap())
        .await
        .unwrap();

    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);
}

3. Latency Measurement Pattern

#[tokio::test]
async fn test_health_check_latency() {
    let state = MockHealthState::new();
    let app = create_health_router(state.clone());

    let start = Instant::now();
    let response = app
        .oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
        .await
        .unwrap();
    let latency = start.elapsed();

    assert_eq!(response.status(), StatusCode::OK);
    assert!(latency < Duration::from_millis(100), "Health check latency: {:?}", latency);
}

4. Concurrent Testing Pattern

#[tokio::test]
async fn test_concurrent_health_checks() {
    let state = MockHealthState::new();

    let mut handles = vec![];
    for _ in 0..100 {
        let state_clone = state.clone();
        let handle = tokio::spawn(async move {
            let app = create_health_router(state_clone);
            let response = app
                .oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
                .await
                .unwrap();
            assert_eq!(response.status(), StatusCode::OK);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.await.unwrap();
    }
}

5. State Transition Pattern

#[tokio::test]
async fn test_service_startup_transition() {
    let state = MockHealthState::new();
    state.set_ready(false).await;

    // Initially not ready
    assert!(!state.is_ready().await);
    assert!(state.is_healthy().await);

    // Simulate initialization
    tokio::time::sleep(Duration::from_millis(50)).await;
    state.set_ready(true).await;

    assert!(state.is_ready().await);
}

6. Recovery Pattern

#[tokio::test]
async fn test_health_recovery_after_failure() {
    let state = MockHealthState::new();

    // Service fails
    state.set_healthy(false).await;
    let app = create_health_router(state.clone());

    let response = app.clone()
        .oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
        .await
        .unwrap();
    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);

    // Service recovers
    state.set_healthy(true).await;
    let response = app
        .oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
        .await
        .unwrap();
    assert_eq!(response.status(), StatusCode::OK);
}

Mock Health State Implementation

Trading Service Mock

#[derive(Clone)]
struct MockHealthState {
    healthy: Arc<RwLock<bool>>,
    ready: Arc<RwLock<bool>>,
    database_connected: Arc<RwLock<bool>>,
    redis_connected: Arc<RwLock<bool>>,
}

ML Training Service Mock

#[derive(Clone)]
struct MockMlHealthState {
    healthy: Arc<RwLock<bool>>,
    ready: Arc<RwLock<bool>>,
    gpu_available: Arc<RwLock<bool>>,
    checkpoints_accessible: Arc<RwLock<bool>>,
    database_connected: Arc<RwLock<bool>>,
    training_active: Arc<RwLock<bool>>,
    gpu_memory_available: Arc<RwLock<bool>>,
}

API Gateway Mock

#[derive(Clone)]
struct MockGatewayHealthState {
    startup_complete: Arc<RwLock<bool>>,
    service_healthy: Arc<RwLock<bool>>,
    trading_service_up: Arc<RwLock<bool>>,
    backtesting_service_up: Arc<RwLock<bool>>,
    ml_service_up: Arc<RwLock<bool>>,
    rate_limiter_healthy: Arc<RwLock<bool>>,
    circuit_breaker_open: Arc<RwLock<bool>>,
}

Edge Cases Covered

Service-Specific Edge Cases

Trading Service:

  • Database down + Redis up (partial degradation)
  • Cascade failure (database + Redis)
  • 1000 rapid health checks
  • 100 concurrent health checks
  • Graceful shutdown (liveness OK, readiness FAIL)

Backtesting Service:

  • Storage unavailable during backtest
  • Database down + storage up
  • Health during active backtest
  • 500 rapid health checks

ML Training Service:

  • GPU available + memory exhausted
  • Checkpoints inaccessible + GPU working
  • Health during training
  • GPU recovery after failure
  • 4-way dependency failure

API Gateway:

  • Single backend down
  • All backends down
  • Circuit breaker open
  • Rate limiter at capacity
  • Kubernetes probe compatibility

Performance Requirements

Test Type Target Validation
Health Check Latency <100ms 4 tests
Concurrent Requests 100 parallel 4 tests
Rapid Fire 500-1000 req/s 4 tests
Deep Health <100ms 4 tests

Test Execution

# Run all health check tests
cargo test --test health_check_tests

# Run specific service tests
cargo test -p trading_service --test health_check_tests
cargo test -p backtesting_service --test health_check_tests
cargo test -p ml_training_service --test health_check_tests
cargo test -p api_gateway --test health_check_tests

# Run single test
cargo test test_health_check_latency

# Run with output
cargo test --test health_check_tests -- --nocapture

# Run with single thread (for debugging)
cargo test --test health_check_tests -- --test-threads=1