veza/loadtests/backend/marketplace.js
senke fef7e7fc7c feat(loadtests): audit 3.2 — tests de charge k6 complets
- loadtests: centraliser scripts (backend, stream, chat)
- backend: health, auth, tracks, uploads, playlists, marketplace
- stream: http health, healthz, readyz
- chat: WebSocket load (register -> login -> chat token -> WS)
- ci: workflow nightly load-test-nightly.yml
- docs: README loadtests
- make: load-test-smoke, load-test-backend, load-test-all
- fix: veza-backend-api Makefile load-test (scripts/load_test_uploads.js -> loadtests)
2026-02-15 15:22:48 +01:00

89 lines
2.7 KiB
JavaScript

/**
* Load test: GET marketplace/products, GET marketplace/orders
* Usage: k6 run loadtests/backend/marketplace.js
*/
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
import { randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
const errorRate = new Rate('errors');
const API_ORIGIN = __ENV.API_ORIGIN || __ENV.BASE_URL || 'http://localhost:8080';
const TEST_EMAIL_PREFIX = __ENV.TEST_EMAIL_PREFIX || 'user+market';
const TEST_EMAIL_DOMAIN = __ENV.TEST_EMAIL_DOMAIN || 'example.com';
const TEST_PASSWORD_PREFIX = __ENV.TEST_PASSWORD_PREFIX || 'V3za!market-';
function generateTestUser() {
const rand = randomString(8);
const pwd = `${TEST_PASSWORD_PREFIX}${rand}`;
return {
email: `${TEST_EMAIL_PREFIX}${rand}@${TEST_EMAIL_DOMAIN}`,
password: pwd,
password_confirmation: pwd,
username: `mk${rand}`,
};
}
export const options = {
scenarios: {
marketplace: {
executor: 'ramping-vus',
stages: [
{ duration: '30s', target: 5 },
{ duration: '1m', target: 5 },
{ duration: '30s', target: 0 },
],
},
},
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'],
errors: ['rate<0.1'],
},
};
export function setup() {
const users = [];
const baseURL = `${API_ORIGIN}/api/v1/auth`;
for (let i = 0; i < 10; i++) {
const user = generateTestUser();
const registerRes = http.post(`${baseURL}/register`, JSON.stringify(user), {
headers: { 'Content-Type': 'application/json' },
});
if (registerRes.status === 201) {
const loginRes = http.post(`${baseURL}/login`, JSON.stringify({ email: user.email, password: user.password }), {
headers: { 'Content-Type': 'application/json' },
});
if (loginRes.status === 200) {
try {
const body = JSON.parse(loginRes.body);
const token = body.data?.token?.access_token;
if (token) users.push({ ...user, token });
} catch (e) {}
}
}
}
return { users };
}
export default function (data) {
const { users } = data;
const baseURL = `${API_ORIGIN}/api/v1/marketplace`;
const productsRes = http.get(`${baseURL}/products`);
const productsOk = check(productsRes, {
'products returns 200': (r) => r.status === 200,
});
errorRate.add(!productsOk);
sleep(0.5);
if (users.length > 0 && Math.random() < 0.5) {
const user = users[Math.floor(Math.random() * users.length)];
const ordersRes = http.get(`${baseURL}/orders`, {
headers: { Authorization: `Bearer ${user.token}` },
});
check(ordersRes, {
'orders returns 200 or 401': (r) => r.status === 200 || r.status === 401,
});
}
sleep(1);
}