# Chaos Mode Inject controlled failures into contract tests to validate resilience guarantees. ## Usage ```typescript const result = await fastify.apophis.contract({ depth: 'standard', chaos: { probability: 0.1, // 10% of requests get chaos delay: { probability: 1, minMs: 100, maxMs: 500 }, error: { probability: 1, statusCode: 503 }, dropout: { probability: 1 }, corruption: { probability: 1 }, }, }) ``` ## Event Types ### Delay Adds artificial latency. Tests timeout contracts: ```apostl timeout_occurred(this) == false response_time(this) < 1000 ``` ### Error Forces HTTP status codes. Tests error-handling contracts: ```apostl if status:503 then response_body(this).retry_after != null ``` ### Dropout Simulates network failure (status 0). Tests fallback contracts: ```apostl status:200 || status:0 ``` ### Corruption Mutates response bodies. Tests parsing robustness: ```apostl response_body(this).id != null ``` ## Content-Type Aware Corruption Built-in strategies for common formats: | Content-Type | Strategy | Effect | |-------------|----------|--------| | `application/json` | Truncate or null field | Removes fields or sets random field to null | | `application/x-ndjson` | Chunk corrupt | Corrupts one NDJSON chunk | | `text/event-stream` | Event corrupt | Adds malformed SSE line | | `multipart/form-data` | Field corrupt | Replaces field with corrupted data | | `text/plain` | Truncate | Cuts string in half | ## Custom Corruption via Extensions ```typescript const myExtension = { name: 'custom-corrupt', corruptionStrategies: { 'application/vnd.api+json': (data) => ({ ...data as object, corrupted: true, }), 'text/*': (data) => `CORRUPTED:${String(data)}`, }, } await fastify.register(apophis, { extensions: [myExtension], }) ``` Extension strategies take precedence over built-ins. Wildcard patterns (`text/*`) match any subtype. ## Environment Guard Low-level contract chaos APIs require `NODE_ENV=test`. For CLI qualification, environment policy controls whether chaos gates may run. ``` Error: Chaos mode is only available in test environment. ``` ## Interpreting Results Failed tests include chaos events in diagnostics: ```json { "statusCode": 503, "error": "Contract violation: status:200", "chaosEvents": [ { "type": "error", "injected": true, "details": { "statusCode": 503, "reason": "Chaos error: overridden 200 with 503" } } ] } ``` ## Best Practices 1. **Start small**: `probability: 0.05` (5% of requests) 2. **Test one failure mode at a time**: Comment out other chaos types 3. **Verify contracts handle chaos**: `if status:503 then response_body(this).error != null` 4. **Use seeds for reproducibility**: `seed: 42` makes chaos deterministic ## Example: Testing Retry Logic ```typescript fastify.get('/data', { schema: { 'x-ensures': [ 'if status:503 then response_headers(this).retry-after != null', 'redirect_count(this) <= 3', ], }, }, handler) // Test const result = await fastify.apophis.contract({ chaos: { probability: 0.2, error: { probability: 1, statusCode: 503 }, }, }) ```