import assert from 'node:assert/strict'; import { performance } from 'node:perf_hooks'; import { setTimeout as sleep } from 'node:timers/promises'; export const durationMs = 15 * 60 * 1000; export const paceMs = 500; export function summarize(rows) { const values = rows.filter(row => !row.error && row.status === 200).map(row => row.ms).sort((a, b) => a - b); const percentile = p => values.length ? values[Math.ceil(values.length * p) - 1] : null; return { attempts: rows.length, failures: rows.filter(row => row.error || row.status !== 200).length, p50Ms: percentile(.5), p95Ms: percentile(.95), p99Ms: percentile(.99), maxMs: values.at(-1) ?? null }; } export async function waitUntil(target) { while (performance.now() < target) await sleep(Math.min(1000, target - performance.now())); } export function assertMembership(actual, expected) { assert.equal(actual.length, 250); assert.equal(new Set(actual).size, 250); assert.deepEqual([...actual].sort((a, b) => a - b), [...expected].sort((a, b) => a - b)); } if (process.argv.includes('--self-test')) { assert.equal(durationMs, 900000); assert.equal(paceMs, 500); assert.deepEqual(summarize([]), { attempts: 0, failures: 0, p50Ms: null, p95Ms: null, p99Ms: null, maxMs: null }); const rows = Array.from({ length: 100 }, (_, i) => ({ ms: i + 1, status: 200 })); assert.deepEqual(summarize([...rows, { ms: 999, status: 500 }, { ms: 999, error: 'timeout' }]), { attempts: 102, failures: 2, p50Ms: 50, p95Ms: 95, p99Ms: 99, maxMs: 100 }); const ids = Array.from({ length: 250 }, (_, i) => i + 1); assertMembership(ids.toReversed(), ids); assert.throws(() => assertMembership([...ids.slice(0, 249), 1], ids)); assert.throws(() => assertMembership([...ids.slice(0, 249), 999], ids)); assert.throws(() => assertMembership(ids.slice(1), ids)); console.log('performance metrics self-check passed'); }