Chaos testing validates how the SoroTask keeper behaves under realistic network and RPC failure conditions. Standard tests often assume dependencies either work perfectly or fail completely, but real-world incidents involve partial failures, slow responses, and flaky connections.
This framework helps you:
- Test keeper resilience under degraded conditions
- Validate circuit breaker and retry logic
- Observe recovery behavior
- Identify regressions in resilience features
- Educate contributors about expected behavior during incidents
The chaos testing framework consists of:
- ChaosRpcServer - Extends the mock RPC server with fault injection capabilities
- ChaosTestHarness - Orchestrates chaos scenarios and collects observations
- Chaos Test Scenarios - Predefined failure patterns simulating real incidents
- Test Runner Script - Command-line tool for running chaos tests
- Description: Inject random latency spikes on RPC calls
- Purpose: Test timeout handling and adaptive polling
- Expected Behavior: Circuit breaker stays CLOSED, retry logic handles timeouts
- Description: Some RPC methods fail while others work
- Purpose: Test graceful degradation and method-specific fallbacks
- Expected Behavior: Keeper continues polling, execution attempts fail gracefully
- Description: Simulate RPC rate limiting
- Purpose: Test backoff and retry behavior under throttling
- Expected Behavior: Keeper backs off, circuit breaker may trip
- Description: Network goes up and down periodically
- Purpose: Test circuit breaker recovery and reconnection logic
- Expected Behavior: Circuit breaker trips and recovers appropriately
- Description: RPC gradually becomes less reliable over time
- Purpose: Test adaptive behavior to worsening conditions
- Expected Behavior: Failure rate increases, circuit breaker eventually trips
- Description: RPC becomes completely unavailable
- Purpose: Test worst-case scenario handling
- Expected Behavior: Circuit breaker trips quickly, keeper stops executions
# Navigate to keeper directory
cd keeper
# Run all chaos scenarios
npm run chaos-test
# Run specific scenarios
npm run chaos-test -- --scenario=latency,ratelimit
# Run with custom duration
npm run chaos-test -- --duration=10000
# Save report to file
npm run chaos-test -- --output=json --file=chaos-report.json# List available scenarios
node scripts/chaos-test.js list
# Run all scenarios
node scripts/chaos-test.js run
# Run single scenario
node scripts/chaos-test.js single latency
# Run with options
node scripts/chaos-test.js run --scenario=latency,outage --duration=15000 --output=markdown --file=report.mdconst { ChaosTestHarness } = require('./src/chaosTestHarness');
async function runChaosTests() {
const harness = new ChaosTestHarness();
const results = await harness.runAllScenarios();
console.log(`Passed ${results.summary.passedScenarios}/${results.summary.totalScenarios} scenarios`);
const report = harness.generateReport(results);
console.log(JSON.stringify(report, null, 2));
}
runChaosTests();Chaos tests are integrated into the existing Jest test suite:
# Run all tests including chaos tests
npm test
# Run only chaos tests
npm test -- chaos.test.js
# Run with verbose output
npm test -- chaos.test.js --verboseEach scenario can be configured with:
{
name: 'Latency Spikes',
description: 'Inject random latency spikes',
config: {
latencyMs: 5000, // Base latency in milliseconds
latencyJitterMs: 2000, // Random jitter
latencyProbability: 0.3, // Probability of injecting latency
durationMs: 30000, // Test duration
}
}The ChaosRpcServer supports these fault injection mechanisms:
- Latency: Add delays to RPC responses
- Failures: Return error responses
- Partial Failures: Some methods fail, others work
- Rate Limiting: Enforce request limits
- Flaky Behavior: Periodic availability
- Gradual Degradation: Increasing failure probability over time
# Enable verbose chaos logging
CHAOS_LOG_LEVEL=debug
# Override default scenario durations
CHAOS_DEFAULT_DURATION_MS=10000
# Enable/disable specific fault types
CHAOS_ENABLE_LATENCY=true
CHAOS_ENABLE_FAILURES=trueEach chaos test collects:
- RPC request count
- RPC failure count
- Circuit breaker transitions
- Average latency
- Error classifications
During chaos tests, the keeper's health endpoint should reflect:
healthyduring normal operationdegradedduring partial failuresunhealthyduring complete outages
| Scenario | Circuit Breaker | Retry Logic | Health |
|---|---|---|---|
| Latency Spikes | CLOSED | Handles timeouts | degraded |
| Partial Failure | CLOSED | Retries appropriate errors | degraded |
| Rate Limiting | MAY trip | Backs off | degraded |
| Flaky Network | TRIPS and RECOVERS | Retries during up periods | unstable |
| Complete Outage | TRIPS quickly | Stops retrying | unhealthy |
const customScenario = {
name: 'Resolver Timeout',
description: 'Resolver calls timeout while RPC works',
config: {
// Only affect resolver-related methods
partialFailureMethods: ['callResolver', 'checkCondition'],
workingMethods: ['getNetwork', 'getLatestLedger', 'getAccount'],
failureRate: 0.8,
failureTypes: ['timeout'],
durationMs: 20000,
},
expectedBehaviors: [
'Keeper should continue polling',
'Tasks with resolvers should fail gracefully',
'Tasks without resolvers should execute normally',
],
};// In chaos.test.js
test('custom resolver timeout scenario', async () => {
const harness = new ChaosTestHarness({
scenarios: [customScenario],
});
const results = await harness.runAllScenarios();
expect(results.scenarios[0].passed).toBe(true);
});Begin with basic scenarios (latency, partial failures) before complex ones.
Watch logs and metrics during tests to understand behavior.
Record observations and unexpected behaviors for follow-up.
Include chaos tests in CI/CD to catch regressions.
Use test results to teach about system resilience.
Issue: Tests timeout or hang Solution: Reduce scenario durations or check for infinite loops
Issue: No failures injected Solution: Verify fault injection is enabled and probabilities > 0
Issue: Circuit breaker doesn't trip Solution: Check failure thresholds and error classification
Issue: Health reporting incorrect Solution: Verify health check logic handles degraded states
# Enable debug logging
CHAOS_LOG_LEVEL=debug npm run chaos-test
# Run single test with verbose output
npm test -- chaos.test.js -t "should handle RPC latency spikes" --verbose
# Check mock server logs
tail -f keeper/logs/chaos-rpc.log- Extend
ChaosRpcServerwith new fault injection method - Add configuration options
- Create test scenario using the new fault
- Update documentation
- Review
src/retry.jserror classification - Add new error codes to appropriate categories
- Test classification with chaos scenarios
- Update expected behaviors
- Add new metrics to
ChaosTestHarness - Include in scenario evaluation
- Update reports to show new metrics
- Document what the metrics measure