Files
java-testing-lab/gatling-spring-boot/k6/knee.js
T
2026-11-06 21:43:41 +05:30

50 lines
1.7 KiB
JavaScript

// k6 equivalent of KneeStepsSimulation: open model, 30 -> 240 requests/s in 8 steps,
// each held 6 s and separated by 2 s ramps. Every request is tagged with the step it was sent in.
import http from 'k6/http';
import exec from 'k6/execution';
import { check } from 'k6';
import { SharedArray } from 'k6/data';
const BASE = __ENV.APP_URL || 'http://localhost:18300';
const STEPS = 8, RATE_STEP = 30, HOLD_S = 6, RAMP_S = 2;
// the feeder: same CSV Gatling reads
const symbols = new SharedArray('symbols', () =>
open('../src/test/resources/data/symbols.csv').trim().split('\n').slice(1));
// k6 treats only these statuses as success, so a 503 counts in http_req_failed
http.setResponseCallback(http.expectedStatuses(200));
const stages = [];
for (let i = 0; i < STEPS; i++) {
if (i > 0) stages.push({ duration: `${RAMP_S}s`, target: RATE_STEP * (i + 1) });
stages.push({ duration: `${HOLD_S}s`, target: RATE_STEP * (i + 1) });
}
export const options = {
scenarios: {
knee: {
executor: 'ramping-arrival-rate', // open model: iterations start on a schedule
startRate: RATE_STEP,
timeUnit: '1s',
preAllocatedVUs: 200,
maxVUs: 1000,
stages,
},
},
};
function stepLabel() {
const elapsed = Date.now() - exec.scenario.startTime;
const slot = Math.floor(elapsed / ((HOLD_S + RAMP_S) * 1000));
const into = elapsed % ((HOLD_S + RAMP_S) * 1000);
if (into >= HOLD_S * 1000 || slot >= STEPS) return 'ramp';
return `rate ${String(RATE_STEP * (slot + 1)).padStart(3, '0')}/s`;
}
export default function () {
const symbol = symbols[Math.floor(Math.random() * symbols.length)];
const res = http.get(`${BASE}/api/quote/${symbol}`, { tags: { step: stepLabel() } });
check(res, { 'status is 200': (r) => r.status === 200 });
}