Files
Stend_mont/scripts/load/k6_100_users_2_services.js

117 lines
3.3 KiB
JavaScript

import http from 'k6/http';
import { check, fail, sleep } from 'k6';
import exec from 'k6/execution';
const BASE_URL = (__ENV.BASE_URL || 'https://127.0.0.1:2288').replace(/\/$/, '');
const HOST_HEADER = (__ENV.HOST_HEADER || 'stend.4mont.ru').trim();
const SERVICE_A = __ENV.SERVICE_A || 'termidesk';
const SERVICE_B = __ENV.SERVICE_B || 'vmmanager';
const CLOSE_SESSION = (__ENV.CLOSE_SESSION || '1') !== '0';
const REQ_TIMEOUT = __ENV.REQ_TIMEOUT || '20s';
const users = (__ENV.USERS_CSV || '')
.split(';')
.map((v) => v.trim())
.filter(Boolean)
.map((pair) => {
const i = pair.indexOf(':');
return i > 0 ? { username: pair.slice(0, i), password: pair.slice(i + 1) } : null;
})
.filter(Boolean);
export const options = {
scenarios: {
burst_100_users: {
executor: 'per-vu-iterations',
vus: 100,
iterations: 1,
maxDuration: '3m',
},
},
insecureSkipTLSVerify: true,
thresholds: {
http_req_failed: ['rate<0.2'],
},
};
function hdr(extra = {}) {
return HOST_HEADER ? { ...extra, Host: HOST_HEADER } : extra;
}
function getCreds() {
if (users.length < 100) fail(`Need at least 100 users in USERS_CSV, got ${users.length}`);
const idx = (exec.vu.idInTest || 1) - 1;
return users[idx % users.length];
}
function login(username, password) {
const jar = http.cookieJar();
jar.clear(BASE_URL);
const landing = http.get(`${BASE_URL}/`, {
redirects: 0,
timeout: REQ_TIMEOUT,
headers: hdr(),
tags: { name: 'GET /' },
});
const csrfFromCookie = (jar.cookiesForURL(BASE_URL).csrf_token || [])[0] || '';
const csrf = csrfFromCookie || ((landing.cookies.csrf_token || [])[0] || {}).value || '';
if (!csrf) fail(`No CSRF for ${username}`);
const payload = [
`username=${encodeURIComponent(username)}`,
`password=${encodeURIComponent(password)}`,
`csrf_token=${encodeURIComponent(csrf)}`,
].join('&');
const loginRes = http.post(`${BASE_URL}/login`, payload, {
redirects: 0,
timeout: REQ_TIMEOUT,
headers: hdr({ 'Content-Type': 'application/x-www-form-urlencoded' }),
tags: { name: 'POST /login' },
});
const ok = check(loginRes, { 'login status 303': (r) => r.status === 303 });
if (!ok) fail(`Login failed ${username}, status=${loginRes.status}`);
}
function openService(slug) {
const res = http.get(`${BASE_URL}/go/${slug}`, {
redirects: 0,
timeout: REQ_TIMEOUT,
headers: hdr(),
tags: { name: 'GET /go/:slug' },
});
const ok = check(res, { [`open ${slug} -> 303`]: (r) => r.status === 303 });
const location = res.headers.Location || '';
const m = location.match(/\/s\/([0-9a-fA-F-]{36})\//);
return { ok, status: res.status, sessionId: m ? m[1] : '', location };
}
function closeSession(sessionId) {
if (!sessionId || !CLOSE_SESSION) return;
http.post(`${BASE_URL}/api/sessions/${sessionId}/close`, null, {
redirects: 0,
timeout: REQ_TIMEOUT,
headers: hdr(),
tags: { name: 'POST /api/sessions/:id/close' },
});
}
export default function () {
const { username, password } = getCreds();
login(username, password);
const a = openService(SERVICE_A);
sleep(0.1);
const b = openService(SERVICE_B);
closeSession(a.sessionId);
closeSession(b.sessionId);
if (!a.ok || !b.ok) {
fail(`open failed user=${username} a=${a.status} b=${b.status}`);
}
}