/** * Compare k6 summary JSON against baseline thresholds. * Usage: node compare.mjs * Exit 1 if p95 latency degrades by > 20% from baseline. */ import { readFileSync } from 'fs'; const baselineThresholds = { http_req_duration_p95: 500, // ms http_req_duration_p99: 1000, // ms http_req_failed_rate: 0.01, // 1% }; const summaryPath = process.argv[2]; if (!summaryPath) { console.error('Usage: node compare.mjs '); process.exit(1); } try { const summary = JSON.parse(readFileSync(summaryPath, 'utf8')); const metrics = summary.metrics || {}; let failed = false; const p95 = metrics.http_req_duration?.values?.['p(95)']; if (p95 && p95 > baselineThresholds.http_req_duration_p95) { console.error(`FAIL: p95 latency ${p95.toFixed(0)}ms > baseline ${baselineThresholds.http_req_duration_p95}ms`); failed = true; } const p99 = metrics.http_req_duration?.values?.['p(99)']; if (p99 && p99 > baselineThresholds.http_req_duration_p99) { console.error(`FAIL: p99 latency ${p99.toFixed(0)}ms > baseline ${baselineThresholds.http_req_duration_p99}ms`); failed = true; } const failRate = metrics.http_req_failed?.values?.rate; if (failRate && failRate > baselineThresholds.http_req_failed_rate) { console.error(`FAIL: error rate ${(failRate * 100).toFixed(2)}% > baseline ${baselineThresholds.http_req_failed_rate * 100}%`); failed = true; } if (failed) { process.exit(1); } console.log('PASS: All performance metrics within baseline thresholds'); } catch (e) { console.error('Failed to parse summary:', e.message); process.exit(1); }