UNPKG

chaos-injector

Version:

Chaos engineering middleware for testing API resilience

115 lines (101 loc) 3.41 kB
// ChaosInjector/middlewareWrapper.js // Import middleware functions directly const randomFailure = require('./middlewares/randomFailure'); const responseDelay = require('./middlewares/responseDelay'); const emptyResponse = require('./middlewares/emptyResponse'); const timeout = require('./middlewares/timeout'); // Import timeout // Define predefined chaos profiles const chaosProfiles = { 'flakyNetwork': { delayRange: [300, 1500], failureRate: 0.25, errorTypes: ['503', '504'] }, 'overloadedServer': { delayRange: [1200, 4000], failureRate: 0.6, errorTypes: ['500', '502', '503'] }, 'gremlinAttack': { failureRate: 0.4, errorTypes: ['400', '401', '403', '404', '500'], emptyType: 'empty_object' }, 'intermittentEmpty': { failureRate: 0.8, emptyType: 'empty' }, 'timeoutScenario': { failureRate: 0.95, simulateTimeout: true }, 'latencySpike': { delayRange: [2000, 8000], failureRate: 0.0 }, 'errorStorm': { failureRate: 0.7, errorTypes: ['500', '502', '503', '504'] }, 'emptyTrap': { failureRate: 0.6, emptyType: 'empty_object' } }; function withChaos(profileName, userConfig = {}) { let profileConfig = {}; if (typeof profileName === 'string' && chaosProfiles[profileName]) { profileConfig = chaosProfiles[profileName]; } else { userConfig = profileName || {}; // If profileName is not a string, assume it's the userConfig } // Merge profile config with user config, giving user config priority const config = { ...profileConfig, ...userConfig }; return (req, res, next) => { const { failureRate, delayRange, errorTypes, emptyType, simulateTimeout } = config || {}; // 1. Timeout Simulation if (simulateTimeout && Math.random() < failureRate) { console.log('Simulating timeout...'); return; // Stop further middleware execution } // 2. Delayed Response with Intermittent Failures if (delayRange && failureRate && errorTypes && errorTypes.length > 0) { const delayOptions = { delayRange: delayRange }; const failureOptions = { failureRate: failureRate, errorTypes: errorTypes }; return responseDelay(delayOptions)(req, res, () => { if (Math.random() < failureRate) { return randomFailure(failureOptions)(req, res, next); // randomFailure handles next() } else { next(); // Proceed to the route handler } }); } // 3. Random Failure if (failureRate && errorTypes && errorTypes.length > 0) { const failureOptions = { failureRate: failureRate, errorTypes: errorTypes }; return randomFailure(failureOptions)(req, res, next); // randomFailure handles next() } // 4. Empty Response if (emptyType && Math.random() < failureRate) { return emptyResponse({ type: emptyType })(req, res, next); // emptyResponse handles next() } // 5. Response Delay if (delayRange) { const delayOptions = { delayRange: delayRange }; return responseDelay(delayOptions)(req, res, next); // responseDelay handles next() } // 6. If no chaos is injected, proceed to the route handler next(); }; } module.exports = withChaos;