#!/usr/bin/env node const base = (process.argv[2] || process.env.ALT_URL || 'http://127.0.0.1:3000').replace(/\/$/,''); const video = process.env.VIDEO_ID || 'dQw4w9WgXcQ'; const generation = process.env.MEDIA_GEN || '1'; const query = process.env.SEARCH_QUERY || 'worship'; const seconds = Number(process.env.BENCH_SECONDS || 3); const scenarios = [ ['version','/api/version',false], ['static-css','/styles.css',false], ['cached-search',`/api/search?q=${encodeURIComponent(query)}`,false], ['cached-range',`/api/media/${encodeURIComponent(video)}?g=${encodeURIComponent(generation)}`,true], ]; const percentile = (values,p) => values.length ? values[Math.min(values.length-1,Math.ceil(values.length*p)-1)] : 0; async function run(path, range, concurrency) { const latencies=[]; let bytes=0, count=0, failures=0; const until=Date.now()+seconds*1000; await Promise.all(Array.from({length:concurrency},async()=>{ while(Date.now()a-b); return {endpoint:path,concurrency,seconds,requests:count,requestsPerSecond:+(count/seconds).toFixed(2),bytes,latencyMs:{p50:+percentile(latencies,.5).toFixed(2),p95:+percentile(latencies,.95).toFixed(2)},failures}; } for(const [name,path,range] of scenarios) for(const concurrency of [1,10,50,200]) { try { console.log(JSON.stringify({name,...await run(path,range,concurrency)})); } catch(e) { console.error(JSON.stringify({name,path,concurrency,error:String(e)})); process.exitCode=1; } }