asupersync 0.3.4

Spec-first, cancel-correct, capability-secure async runtime for Rust.
Documentation
# ATP Testing Patterns and Guidelines

This document provides testing patterns and guidelines for ATP module development to ensure consistent, reliable, and deterministic tests.

## Core Testing Principles

1. **Deterministic by Default**: All tests should use deterministic inputs and produce reproducible results
2. **Cx-First**: Use proper `Cx` context with appropriate budgets and cancellation behavior
3. **Outcome Handling**: Test all `Outcome` variants (Ok, Err, Cancelled, Panicked) explicitly
4. **Lab Runtime**: Use lab runtime for complex concurrency and timing scenarios
5. **No External Dependencies**: Test ATP components in isolation without external QUIC crates

## Test Structure

```rust
use asupersync::net::atp::test_utils::*;
use asupersync::cx::Cx;

#[test]
fn test_atp_component() {
    let cx = test_cx();
    
    // Arrange
    let input_data = test_data::pattern_data(1024);
    let peer_id = fixtures::test_peer_id(1);
    
    // Act
    let result = component_under_test(&cx, input_data, peer_id);
    
    // Assert
    let value = assertions::assert_atp_ok(result);
    assert_eq!(value.len(), expected_len);
}
```

## Test Data Patterns

### Use Provided Test Data
- `test_data::SMALL_DATA` - 64 bytes of 0x42
- `test_data::MEDIUM_DATA` - 4KB of 0xAB
- `test_data::pattern_data(size)` - Incrementing byte pattern
- `test_data::deterministic_data(size, seed)` - Pseudo-random deterministic data

### Example
```rust
#[test]
fn test_chunking() {
    let cx = test_cx();
    let data = test_data::deterministic_data(8192, 12345);
    
    let chunks = chunk_data(&cx, &data, 1024);
    let outcome = assertions::assert_atp_ok(chunks);
    assert_eq!(outcome.len(), 8); // 8KB / 1KB = 8 chunks
}
```

## Outcome Testing Patterns

### Test Success Path
```rust
#[test]
fn test_success_case() {
    let result = operation_that_succeeds();
    let value = assertions::assert_atp_ok(result);
    // Verify value properties
}
```

### Test Error Conditions
```rust
#[test]
fn test_error_case() {
    let result = operation_that_fails();
    let error = assertions::assert_atp_err(result);
    assert!(matches!(error, SpecificError::ExpectedVariant));
}
```

### Test Cancellation
```rust
#[test]
fn test_cancellation() {
    let cx = test_cx();
    cx.request_cancel(); // Cancel before operation
    
    let result = cancellable_operation(&cx);
    assertions::assert_atp_cancelled(result);
}
```

## Deterministic Fixture Objects

Use provided fixtures for consistent test behavior:

```rust
#[test]
fn test_with_fixtures() {
    let peer_a = fixtures::test_peer_id(1);
    let peer_b = fixtures::test_peer_id(2);
    let session = fixtures::test_session_id(100);
    
    // Fixtures are deterministic - same input always produces same output
    assert_eq!(peer_a, fixtures::test_peer_id(1));
    assert_ne!(peer_a, peer_b);
}
```

## Async Testing

For async ATP operations, use proper async test setup:

```rust
#[tokio::test]
async fn test_async_operation() {
    let cx = test_cx();
    
    // Use timeout to prevent hanging tests
    let timeout = tokio::time::timeout(
        TEST_TIMEOUT,
        async_operation(&cx)
    ).await;
    
    let result = timeout.expect("Operation should not timeout");
    let value = assertions::assert_atp_ok(result);
    // Verify async result
}
```

## Property-Based Testing

For complex ATP components, consider property-based tests:

```rust
use proptest::prelude::*;

proptest! {
    #[test]
    fn test_roundtrip_property(data in prop::collection::vec(any::<u8>(), 0..4096)) {
        let cx = test_cx();
        
        let encoded = encode_data(&cx, &data);
        let encoded_value = assertions::assert_atp_ok(encoded);
        
        let decoded = decode_data(&cx, &encoded_value);
        let decoded_value = assertions::assert_atp_ok(decoded);
        
        prop_assert_eq!(data, decoded_value);
    }
}
```

## Lab Runtime Testing

For deterministic concurrency testing:

```rust
use asupersync::lab::{LabConfig, LabRuntime};

#[test]
fn test_concurrent_behavior() {
    let mut runtime = LabRuntime::new(LabConfig::new(42)); // Fixed seed
    
    // Create deterministic scenario
    runtime.run_until_quiescent();
    
    // Verify deterministic outcome
}
```

## Test Organization

### Module Tests
Place tests alongside implementation:
```rust
// In src/net/atp/component.rs
#[cfg(test)]
mod tests {
    use super::*;
    use crate::net::atp::test_utils::*;
    
    #[test]
    fn test_component_basic() {
        // Unit tests here
    }
}
```

### Integration Tests
Place in `tests/` directory for cross-component testing:
```rust
// In tests/atp_integration_test.rs
use asupersync::net::atp;
use asupersync::net::atp::test_utils::*;

#[tokio::test]
async fn test_end_to_end_scenario() {
    // Integration tests here
}
```

## Common Pitfalls to Avoid

1. **Non-deterministic seeds**: Always use fixed seeds for test data
2. **Timeout without budget**: Set appropriate `Cx` budget for operations
3. **Ignoring cancellation**: Test cancellation paths explicitly
4. **External dependencies**: Don't depend on external QUIC crates in tests
5. **Race conditions**: Use lab runtime for deterministic concurrency testing

## Test Categories

### Unit Tests
- Test individual functions and components
- Use deterministic fixtures for dependencies
- Focus on single responsibility
- Fast execution (< 1ms per test)

### Integration Tests
- Test component interactions
- Use real ATP types but controlled scenarios
- Moderate execution time (< 100ms per test)

### End-to-End Tests
- Test complete ATP workflows
- Use lab runtime for determinism
- Longer execution time acceptable (< 1s per test)

## Example Test Suite Structure

```
src/net/atp/
├── component/
│   ├── mod.rs          // Implementation
│   └── tests/         // Component-specific tests
├── test_utils.rs      // Shared test utilities
└── testing_patterns.md // This document

tests/
├── atp_infrastructure_test.rs  // Basic compilation test
├── atp_integration_test.rs     // Cross-component tests
└── atp_e2e_test.rs            // End-to-end scenarios
```