Решение по TD-STYLE-ANALYZERS: LF — инструменты проекта (Python/Node) пишут LF, CRLF-.sh не работают на Linux CI (sh scripts/ci.sh), большинство файлов уже были LF. Добавлен .gitattributes (* text=auto eol=lf, бинарные исключения), .editorconfig переведён на lf, 1029 файлов конвертированы, git add --renormalize. Из индекса убраны закравшиеся archive/**/__pycache__/*.pyc.
57 lines
2.1 KiB
JavaScript
57 lines
2.1 KiB
JavaScript
// Нагрузочный смоук-тест API Deal на k6 (этап 12, пакет C) — альтернатива
|
|
// scripts/loadtest/api-loadtest.sh, если в системе есть k6.
|
|
//
|
|
// Логин — в setup() (один раз), затем виртуальные пользователи в цикле читают
|
|
// GET /api/containers и GET /api/cards. Пороги (thresholds) проваливают прогон
|
|
// при доле ошибок > 1% или p95 > 500 мс.
|
|
//
|
|
// Запуск (API dev на :5080):
|
|
// k6 run scripts/loadtest/deal-loadtest.js
|
|
// BASE_URL=http://localhost:5080 VUS=10 DURATION=30s k6 run scripts/loadtest/deal-loadtest.js
|
|
//
|
|
// Переменные окружения: BASE_URL, LOGIN, PASSWORD, VUS, DURATION.
|
|
// Внимание: в PROD включён rate-limit (api — 600/мин на тенанта) — гоняйте на dev.
|
|
|
|
import http from 'k6/http';
|
|
import { check, sleep } from 'k6';
|
|
|
|
const BASE_URL = __ENV.BASE_URL || 'http://localhost:5080';
|
|
const LOGIN = __ENV.LOGIN || 'admin';
|
|
const PASSWORD = __ENV.PASSWORD || 'admin';
|
|
|
|
export const options = {
|
|
vus: __ENV.VUS ? Number(__ENV.VUS) : 5,
|
|
duration: __ENV.DURATION || '20s',
|
|
thresholds: {
|
|
http_req_failed: ['rate<0.01'],
|
|
http_req_duration: ['p(95)<500'],
|
|
},
|
|
};
|
|
|
|
export function setup() {
|
|
const res = http.post(
|
|
`${BASE_URL}/api/auth/login`,
|
|
JSON.stringify({ login: LOGIN, password: PASSWORD }),
|
|
{ headers: { 'Content-Type': 'application/json' } }
|
|
);
|
|
if (res.status !== 200) {
|
|
throw new Error(`login failed: HTTP ${res.status} — ${res.body}`);
|
|
}
|
|
const cookies = res.cookies['deal_session'];
|
|
const session = cookies && cookies.length ? cookies[0].value : '';
|
|
if (!session) {
|
|
throw new Error('login succeeded but deal_session cookie is missing');
|
|
}
|
|
return { session };
|
|
}
|
|
|
|
export default function (data) {
|
|
const params = { headers: { Cookie: `deal_session=${data.session}` } };
|
|
const paths = ['/api/containers', '/api/cards'];
|
|
for (const path of paths) {
|
|
const res = http.get(`${BASE_URL}${path}`, params);
|
|
check(res, { [`${path} → 200`]: (r) => r.status === 200 });
|
|
}
|
|
sleep(0.2);
|
|
}
|