// Нагрузка парами «маскирование → демаскирование», как её подаёт проверяющая // система. Одна итерация — два запроса, поэтому rate задаётся вдвое меньше // целевого RPS. // k6 run -e RPS=1000 loadtest.js import http from 'k6/http'; import { check } from 'k6'; const URL = __ENV.URL || 'http://localhost:8080/process'; // Второй узел для обратного шага: так проверяется худший случай на кластере — // демаскирование всегда попадает не на тот узел, который маскировал. const URL_BACK = __ENV.URL_BACK || URL; const TARGET_RPS = Number(__ENV.RPS || 1000); const HEADERS = { headers: { 'Content-Type': 'application/json' } }; const PAYLOADS = [ 'Клиент Иванов Иван Иванович, паспорт 4509 123456 выдан ОУФМС России по г. Москве, дата рождения 12.05.1985', 'Заявление от И.И. Петрова, ИНН 770301234550, адрес: 125009, г. Москва, ул. Тверская, д. 7, кв. 15', 'Карта 4111 1111 1111 1111, держатель IVAN PETROV, CVV 123, пин-код 4321', 'Свяжитесь: ivan.petrov@mail.ru или +7 (916) 123-45-67, гражданство РФ', 'Загранпаспорт 75 1234567, водительское удостоверение 9902 123456, СНИЛС 112-233-445 95', 'Напиши стихотворение в духе Александра Пушкина про осень', ]; export const options = { scenarios: { pairs: { executor: 'constant-arrival-rate', rate: TARGET_RPS / 2, timeUnit: '1s', duration: __ENV.DURATION || '30s', preAllocatedVUs: 300, maxVUs: 2000, }, }, thresholds: { http_req_duration: ['p(95)<1000'], http_req_failed: ['rate<0.01'], checks: ['rate>0.99'], }, }; export default function () { const id = `${__VU}-${__ITER}`; const original = PAYLOADS[__ITER % PAYLOADS.length]; const masked = http.post(URL, JSON.stringify({ payload: original, payload_id: id }), HEADERS); check(masked, { 'маскирование 200': (r) => r.status === 200 }); if (masked.status !== 200) { return; } const restored = http.post(URL_BACK, JSON.stringify({ payload: masked.json('result'), payload_id: id }), HEADERS); check(restored, { 'демаскирование 200': (r) => r.status === 200, 'исходный текст восстановлен': (r) => r.json('result') === original, }); }