import http from 'k6/http'; import { check, fail } from 'k6'; const baseUrl = required('BENCH_BASE_URL').replace(/\/$/, ''); const path = required('BENCH_PATH'); const method = (__ENV.BENCH_METHOD || 'GET').toUpperCase(); const rate = positiveInteger('BENCH_RATE', 100); const expectedStatus = positiveInteger('BENCH_EXPECTED_STATUS', 200); const duration = __ENV.BENCH_DURATION || '30s'; const cacheBust = (__ENV.BENCH_CACHE_BUST || 'false').toLowerCase() === 'true'; export const options = { discardResponseBodies: true, summaryTrendStats: ['avg', 'med', 'p(90)', 'p(95)', 'p(99)', 'max'], scenarios: { fairComparison: { executor: 'constant-arrival-rate', rate, timeUnit: '1s', duration, preAllocatedVUs: positiveInteger('BENCH_PRE_ALLOCATED_VUS', Math.max(20, Math.ceil(rate / 20))), maxVUs: positiveInteger('BENCH_MAX_VUS', Math.max(100, Math.ceil(rate / 5))), }, }, thresholds: { checks: ['rate>0.99'], http_req_failed: ['rate<0.01'], dropped_iterations: ['count==0'], }, }; export function setup() { const readinessPath = __ENV.BENCH_READINESS_PATH; if (!readinessPath) return; const response = http.get(`${baseUrl}${readinessPath}`, { headers: headers() }); if (response.status !== 200) fail(`readiness failed: ${response.status}`); } export default function () { const separator = path.includes('?') ? '&' : '?'; const requestPath = cacheBust ? `${path}${separator}loadProbe=${__VU}-${__ITER}` : path; const response = http.request(method, `${baseUrl}${requestPath}`, __ENV.BENCH_BODY || null, { headers: headers() }); check(response, { [`status is ${expectedStatus}`]: (value) => value.status === expectedStatus }); } function headers() { const values = { Accept: 'application/json' }; if (__ENV.BENCH_HOST_HEADER) values.Host = __ENV.BENCH_HOST_HEADER; if (__ENV.BENCH_AUTHORIZATION) values.Authorization = __ENV.BENCH_AUTHORIZATION; if (__ENV.BENCH_TENANT_HEADER) values['x-tenant-code'] = __ENV.BENCH_TENANT_HEADER; if (__ENV.BENCH_BODY) values['Content-Type'] = 'application/json'; return values; } function required(name) { const value = __ENV[name]; if (!value) throw new Error(`${name} is required`); return value; } function positiveInteger(name, fallback) { const value = Number(__ENV[name] || fallback); if (!Number.isInteger(value) || value <= 0) throw new Error(`${name} must be a positive integer`); return value; }