# Testing Infrastructure Guide

Comprehensive testing strategies for Provisioning deployments.

## Test Types

### Unit Tests

Test individual components in isolation:

```rust
#[cfg(test)]
mod tests {
    use provisioning_sdk::*;

    #[test]
    fn test_configuration_parsing() {
        let config = r#"{
            "workspace": "test",
            "servers": [{"name": "web-01", "cpu": 2}]
        }"#;

        let parsed = parse_config(config);
        assert_eq!(parsed.workspace, "test");
        assert_eq!(parsed.servers.len(), 1);
    }

    #[test]
    fn test_schema_validation() {
        let schema = load_schema("schemas/infrastructure.ncl");
        let config = load_config("test-config.ncl");

        let result = validate(&config, &schema);
        assert!(result.is_ok());
    }
}
```

### Integration Tests

Test components working together:

```rust
#[test]
fn test_full_deployment_workflow() {
    // Setup
    let workspace = create_test_workspace("integration-test");
    let config = load_test_config();

    // Execute
    let result = provisioning::deploy(&workspace, &config);

    // Verify
    assert!(result.is_ok());
    assert_eq!(workspace.resource_count(), 5);

    // Cleanup
    workspace.cleanup();
}
```

### E2E Tests

Test complete workflows:

```bash
#!/usr/bin/env nu

def test-e2e [] {
  # Create workspace
  provisioning workspace create test-e2e

  # Deploy infrastructure
  provisioning workspace use test-e2e
  provisioning infra apply --config test-infrastructure.ncl

  # Run smoke tests
  provisioning test smoke-tests

  # Verify resources
  let resources = (provisioning resource list)
  assert ($resources | length) == 5

  # Cleanup
  provisioning workspace delete test-e2e --force
}
```

## Test Environment

### Container-Based Testing

Use Docker containers for isolated tests:

```dockerfile
# tests/Dockerfile.test
FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
    curl git build-essential cargo

COPY . /provisioning
WORKDIR /provisioning

CMD ["cargo", "test"]
```

### Test Cluster Setup

```yaml
# tests/test-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: provisioning-test
nodes:
  - role: control-plane
  - role: worker
  - role: worker
```

Create and use:

```bash
kind create cluster --config tests/test-cluster.yaml

# Run tests against cluster
export KUBECONFIG=$(kind get kubeconfig-path --name=provisioning-test)
provisioning test --cluster-context kind-provisioning-test
```

## Test Suites

### Smoke Tests

Quick sanity checks:

```bash
#!/usr/bin/env nu

def smoke-tests [] {
  print "Running smoke tests..."

  # Check CLI help
  provisioning help | grep -q "Commands:" && print "✓ CLI working"

  # Check version
  provisioning version | grep -q "^provisioning" && print "✓ Version displayed"

  # Check workspace
  provisioning workspace list | grep -q "production" && print "✓ Workspaces accessible"

  # Check providers
  provisioning provider list | grep -q "aws" && print "✓ Providers loaded"

  print "Smoke tests passed"
}
```

### Integration Tests

Test provider integrations:

```bash
#!/usr/bin/env nu

def test-aws-integration [] {
  print "Testing AWS integration..."

  # Verify credentials
  let creds = provisioning provider auth-test aws
  assert $creds.authenticated

  # Test resource creation
  let config = open test-aws-config.ncl | nickel eval
  let result = provisioning infra apply --dry-run --config $config
  assert $result.status == "success"

  print "AWS integration tests passed"
}
```

### Performance Tests

Benchmark operations:

```nushell
#!/usr/bin/env nu

def benchmark-deployment [] {
  let config = open test-config.ncl

  # Measure deployment time
  let start = (date now)
  provisioning infra apply --config $config
  let end = (date now)

  let duration = ($end - $start)
  print $"Deployment took: ($duration) seconds"

  # Assert performance bounds
  assert ($duration < 300)  # Must complete in under 5 minutes

  print "Performance test passed"
}
```

### Security Tests

Validate security configurations:

```bash
#!/usr/bin/env nu

def test-encryption [] {
  print "Testing encryption..."

  # Verify encryption at rest
  let db_config = provisioning resource describe db-01
  assert $db_config.encrypted_at_rest == true

  # Verify TLS in transit
  let lb_config = provisioning resource describe load-balancer
  assert $lb_config.tls_version == "1.3"

  # Verify secrets are not exposed
  let logs = provisioning logs | grep -i "password"
  assert ($logs | is-empty)  # No passwords in logs

  print "Security tests passed"
}
```

### Resilience Tests

Test failure scenarios:

```bash
#!/usr/bin/env nu

def test-failover [] {
  print "Testing failover behavior..."

  # Simulate primary node failure
  provisioning test simulate-failure --service database --component primary

  # Verify failover occurs
  sleep 30sec
  let current_primary = provisioning resource describe database | get primary_replica
  assert $current_primary != "primary-01"

  print "Failover test passed"
}
```

## Test Data Management

### Fixtures

Define test data:

```nushell
# tests/fixtures/test-data.nu

export def test-servers [] {
  [
    { name: "web-01", cpu: 2, memory: 4, image: "ubuntu-22.04" },
    { name: "web-02", cpu: 2, memory: 4, image: "ubuntu-22.04" },
    { name: "api-01", cpu: 4, memory: 8, image: "ubuntu-22.04" }
  ]
}

export def test-database [] {
  {
    engine: "postgres",
    version: "15",
    replicas: 2,
    backup_retention: 7
  }
}
```

### Seed Data

Populate test environment:

```bash
provisioning test seed \
  --servers tests/fixtures/test-servers.json \
  --databases tests/fixtures/test-databases.json
```

## Continuous Testing

### Pre-Commit Hooks

```bash
#!/bin/bash
# .git/hooks/pre-commit

# Validate Nickel syntax
nickel export provisioning/schemas/*.ncl | | exit 1

# Run unit tests
cargo test --lib | | exit 1

# Lint code
cargo clippy -- -D warnings | | exit 1

exit 0
```

### CI/CD Pipeline

```yaml
# .github/workflows/test.yml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Run unit tests
        run: cargo test --lib

      - name: Run integration tests
        run: cargo test --test '*'

      - name: Run e2e tests
        run: |
          kind create cluster
          ./tests/e2e-tests.nu

      - name: Security scan
        run: |
          cargo audit
          cargo clippy -- -D warnings
```

## Test Reporting

### Coverage Reports

```bash
# Generate coverage
cargo tarpaulin --out Html --output-dir coverage

# View results
open coverage/index.html
```

### Test Results

```bash
# Run with detailed output
cargo test -- --test-threads=1 --nocapture

# Generate JUnit XML for CI
cargo test -- --format=json | jq ... > test-results.xml
```

## Debugging Tests

### Verbose Logging

```bash
RUST_LOG=debug cargo test -- --nocapture
```

### Interactive Debugging

```bash
# Run single test with debugger
rust-gdb --args ./target/debug/test_name
```

## Best Practices

1. **Isolate tests** - No dependencies between test cases
2. **Use fixtures** - Consistent, reusable test data
3. **Clean up** - Always remove test resources
4. **Fast feedback** - Tests should run quickly
5. **Mock external** - Mock cloud APIs in unit tests
6. **Real integration** - Use real cloud for integration tests in staging
7. **Monitor costs** - Cap test resource usage

## Related Documentation

- [Testing Guide](../development/testing.md)
- [Build System](./build-system.md)
- [CI/CD Pipelines](../examples/cicd-pipeline-examples.md)
- [Troubleshooting](../troubleshooting/debug-guide.md)
