الملفات
back_end_oudelaa/scripts/load-test.test.js

124 أسطر
3.3 KiB
JavaScript

const assert = require('node:assert/strict');
const { execFile } = require('node:child_process');
const { createServer } = require('node:http');
const path = require('node:path');
const { test } = require('node:test');
const { evaluatePerformanceGates, parseArgs } = require('./load-test');
const passingSummary = {
requestsPerSecond: 250.25,
successRate: 99.95,
latencyMs: { p95: 120.5, p99: 180.75 },
};
test('parseArgs reads all optional performance gates', () => {
const options = parseArgs([
'--min-success-rate',
'99.9',
'--min-rps',
'200',
'--max-p95',
'150',
'--max-p99',
'250',
]);
assert.deepEqual(options.gates, {
minSuccessRate: 99.9,
minRequestsPerSecond: 200,
maxP95Ms: 150,
maxP99Ms: 250,
});
});
test('parseArgs rejects invalid gate values', () => {
assert.throws(
() => parseArgs(['--min-success-rate', '100.1']),
/min-success-rate must be a finite number between 0 and 100/,
);
assert.throws(() => parseArgs(['--min-rps', '-1']), /min-rps must be a finite number/);
assert.throws(() => parseArgs(['--max-p95']), /--max-p95 requires a value/);
});
test('evaluatePerformanceGates passes when every threshold is satisfied', () => {
const result = evaluatePerformanceGates(passingSummary, {
minSuccessRate: 99.9,
minRequestsPerSecond: 200,
maxP95Ms: 150,
maxP99Ms: 200,
});
assert.equal(result.configured, true);
assert.equal(result.passed, true);
assert.equal(result.checks.length, 4);
assert.ok(result.checks.every((check) => check.passed));
});
test('evaluatePerformanceGates reports every failed threshold', () => {
const result = evaluatePerformanceGates(passingSummary, {
minSuccessRate: 100,
minRequestsPerSecond: 300,
maxP95Ms: 100,
maxP99Ms: 150,
});
assert.equal(result.passed, false);
assert.deepEqual(
result.checks.filter((check) => !check.passed).map((check) => check.metric),
['successRate', 'requestsPerSecond', 'latencyMs.p95', 'latencyMs.p99'],
);
});
test('load-test process exits with code 2 and a clear report when a gate fails', async () => {
const server = createServer((_request, response) => {
response.statusCode = 503;
response.end('unavailable');
});
await new Promise((resolve, reject) => {
server.once('error', reject);
server.listen(0, '127.0.0.1', resolve);
});
try {
const address = server.address();
assert.ok(address && typeof address === 'object');
const result = await runLoadTest([
'--url',
`http://127.0.0.1:${address.port}`,
'--duration',
'0.05',
'--concurrency',
'1',
'--warmup',
'0',
'--min-success-rate',
'100',
]);
assert.equal(result.exitCode, 2);
assert.match(result.stdout, /Performance gates: FAILED \(0\/1\)/);
assert.match(result.stdout, /\[FAIL\] Success rate:/);
} finally {
await new Promise((resolve, reject) => {
server.close((error) => (error ? reject(error) : resolve()));
});
}
});
function runLoadTest(args) {
const scriptPath = path.join(__dirname, 'load-test.js');
return new Promise((resolve) => {
execFile(process.execPath, [scriptPath, ...args], (error, stdout, stderr) => {
resolve({
exitCode: error && typeof error.code === 'number' ? error.code : 0,
stdout,
stderr,
});
});
});
}