test(charge): mesure l'API sous charge avec k6
Aucun garde-fou de performance n'existait, et le dépôt ne chiffrait aucun temps de réponse. tests/load, quatre scénarios : - smoke : une minute sur chaque route de lecture, joué à chaque PR ; - charge : 50 utilisateurs, 40 sur le tableau de bord au rythme de son rafraîchissement, 10 qui explorent les sites ; - stress : débit croissant jusqu'à la rupture, arrêt au-delà de 10 % d'erreurs ; - limitation-debit : par le proxy, vérifie que nginx répond 429 et jamais 5xx. Seuils : p95 < 500 ms et p99 < 1 s sur les lectures, moins de 1 % d'échecs. k6 tourne en service Compose (profil load) sur le réseau du projet : il vise backend:8000 et mesure l'API plutôt que la limite de 20 req/s par adresse de nginx. Chaque tir écrit un rapport HTML, une synthèse Markdown et le JSON brut dans tests/load/results. make load-smoke, load-test, load-stress et load-limits ; le job E2E enchaîne le smoke et le test de limitation après Playwright. Closes #47
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
// Monte le débit jusqu'à la rupture pour situer la limite de l'API. S'arrête de lui-même au-delà
|
||||
// de 10 % d'erreurs : le but est de trouver le point de rupture, pas de s'y maintenir.
|
||||
import { auHasard, consulterSite, lire, preparer } from './lib/api.js';
|
||||
import { STATISTIQUES } from './lib/config.js';
|
||||
import { rapport } from './lib/rapport.js';
|
||||
|
||||
export const options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
scenarios: {
|
||||
stress: {
|
||||
executor: 'ramping-arrival-rate',
|
||||
startRate: 5,
|
||||
timeUnit: '1s',
|
||||
preAllocatedVUs: 50,
|
||||
maxVUs: 400,
|
||||
stages: [
|
||||
{ duration: '2m', target: 25 },
|
||||
{ duration: '2m', target: 50 },
|
||||
{ duration: '2m', target: 100 },
|
||||
{ duration: '2m', target: 200 },
|
||||
{ duration: '1m', target: 0 },
|
||||
],
|
||||
},
|
||||
},
|
||||
thresholds: {
|
||||
http_req_failed: [{ threshold: 'rate<0.10', abortOnFail: true, delayAbortEval: '30s' }],
|
||||
'http_req_duration{type:lecture}': ['p(95)<2000'],
|
||||
},
|
||||
summaryTrendStats: STATISTIQUES,
|
||||
};
|
||||
|
||||
export const setup = preparer;
|
||||
|
||||
export default function (data) {
|
||||
if (Math.random() < 0.6) {
|
||||
lire('/stats/summary', 'stats_summary', data.jeton);
|
||||
} else {
|
||||
consulterSite(auHasard(data.sites), data.jeton);
|
||||
}
|
||||
}
|
||||
|
||||
export function handleSummary(data) {
|
||||
return rapport('stress', data);
|
||||
}
|
||||
Reference in New Issue
Block a user