Skip to content

Instantly share code, notes, and snippets.

@GlauberF
Created October 7, 2025 17:58
Show Gist options
  • Save GlauberF/10b1b55970990bb47b02f669cb440fe3 to your computer and use it in GitHub Desktop.
Save GlauberF/10b1b55970990bb47b02f669cb440fe3 to your computer and use it in GitHub Desktop.
exemplo de uso do K6
/**
*
* K6
* Documentação completa
* https://grafana.com/docs/k6/latest/
*
* Como instalar
* https://grafana.com/docs/k6/latest/set-up/install-k6/
*
**/
import http, { head } from 'k6/http';
import { check, sleep } from 'k6';
import exec from 'k6/execution';
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';
import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.2/index.js';
const baseUrl = "http://tech-lab-app:8080";
const user1Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyMUBleGFtcGxlLmNvbSJ9.5DK2w70WyEtf4HzBPXqsHfO8xoY30CG8rO0QQ5BQGZg";
const user2Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyMkBleGFtcGxlLmNvbSJ9.20lKVN-pzmT8teJwCjH07Ebm2r-tkoY5POxkioy7Ie0";
const user3Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyM0BleGFtcGxlLmNvbSJ9.pv5Y7HIqjloZtlMfVKwTMXv1IWQ7JA0Cl6iMLVmzvDQ";
const user4Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyNEBleGFtcGxlLmNvbSJ9.XWTnHFbUZtTT5azD7ByadrLs42dM4vbsrQFvVZcq6m4";
const user5Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyNUBleGFtcGxlLmNvbSJ9.G7UAkWKqtHOUxvW7zvqpMA9kjYk0uNZuEVMGkKHpBK8";
export const options = {
scenarios: {
failedAuthorization: {
executor: 'shared-iterations',
exec: 'failedAuthorization',
iterations: 1,
maxDuration: '10s'
},
successfullyAuthorization: {
executor: 'shared-iterations',
exec: 'successfullyAuthorization',
iterations: 1,
maxDuration: '10s'
},
rateLimiting1: { // Rate limit na criacao de cobranca, 20 requisicoes.
executor: 'shared-iterations',
vus: 1,
exec: 'rateLimiting',
iterations: 20,
maxDuration: '10s',
env: { REMOTE_IP: randomIp() },
},
rateLimiting2: { // Rate limit na criacao de cobranca, 20 requisicoes, com 4 usuarios (concorrencia).
executor: 'shared-iterations',
vus: 4,
exec: 'rateLimiting',
iterations: 20,
maxDuration: '10s',
env: { REMOTE_IP: randomIp(), multithreading: 'true' },
},
rateLimitingGetPayment: { // Rate limit para Busca de cobrança
executor: 'per-vu-iterations',
vus: 5,
exec: 'rateLimitingGetPayment',
iterations: 4,
maxDuration: '10s',
env: { REMOTE_IP: randomIp() },
startTime: '5s',
},
burstLimit: { // Burst de 10 requisicoes
executor: 'constant-arrival-rate',
preAllocatedVUs: 10,
rate: 10,
timeUnit: '1s',
duration: '1s',
exec: 'burst',
env: { REMOTE_IP: randomIp(), exceeded: 'false' },
},
exceedBurstLimit: { // Burst de 20 requisicoes
executor: 'constant-arrival-rate',
preAllocatedVUs: 20,
rate: 20,
timeUnit: '1s',
duration: '1s',
exec: 'burst',
env: { REMOTE_IP: randomIp(), exceeded: 'true' },
},
quota: { // Limite diário, 100 requisicoes.
executor: 'shared-iterations',
vus: 1,
exec: 'quota',
iterations: 100,
maxDuration: '2m',
env: { USER: user5Token },
},
quotaExceeded: { // Limite diario, 200 requisicoes.
executor: 'shared-iterations',
vus: 5,
exec: 'quota',
iterations: 200,
maxDuration: '2m',
env: { USER: user4Token, exceeded: 'true' },
},
idempotency: { // Idempotencia na criacao de cobranca.
executor: 'shared-iterations',
exec: 'idempotency',
iterations: 1,
maxDuration: '10s'
}
},
};
function randomIp() {
return Array(4).fill(0).map(() => Math.floor(Math.random() * 256)).join('.');
}
export function rateLimiting() {
const url = `${baseUrl}/payments`;
const headers = {
'Authorization': user1Token,
'Content-Type': 'application/json',
'remote-ip': __ENV.REMOTE_IP
};
const response = http.get(url, { headers: headers });
const limit = 10;
const expectedStatus = exec.scenario.iterationInTest < limit ? 200 : 429;
const title = `Rate Limit ${__ENV.multithreading === 'true' ? '(Multithreading) ' : ''}${__ENV.REMOTE_IP}`;
if (response.status !== expectedStatus) {
console.log(`Inconsistência no Rate Limit detectado. O status ${response.status} foi retornado na execução ${exec.scenario.iterationInTest}`);
}
check(response, {
[title]: (r) => r.status === expectedStatus
});
}
export function rateLimitingGetPayment(data) {
const title = `Rate Limit Get Payment ${__ENV.REMOTE_IP}`;
const fakePaymentId = "pay_123";
const url = `${baseUrl}/payments/${fakePaymentId}`;
const headers = {
'Authorization': user1Token,
'Content-Type': 'application/json',
'remote-ip': __ENV.REMOTE_IP
};
const response = http.get(url, { headers: headers });
const limit = 10;
const expectedStatus = exec.scenario.iterationInTest < limit ? 404 : 429;
check(response, {
[title]: (r) => r.status === expectedStatus
});
}
export function burst() {
const url = `${baseUrl}/payments`;
const headers = {
'Authorization': user1Token,
'Content-Type': 'application/json',
'remote-ip': __ENV.REMOTE_IP
};
const response = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
const limit = 10;
const expectedStatus = exec.scenario.iterationInTest < limit ? 200 : 429;
const title = `Burst ${__ENV.exceeded === 'true' ? 'Excedido' : ''} ${__ENV.REMOTE_IP}`;
check(response, {
[title]: (r) => r.status === expectedStatus
});
}
export function failedAuthorization() {
const token = "aleatorio";
const url = `${baseUrl}/payments`;
const headers = {
'Authorization': token,
'Content-Type': 'application/json',
'remote-ip': randomIp()
};
const response = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
check(response, {
"Token de autenticão incorreto": (r) => r.status === 401
});
}
export function successfullyAuthorization() {
const url = `${baseUrl}/payments`;
const headers = {
'Authorization': user3Token,
'Content-Type': 'application/json',
'remote-ip': randomIp()
};
const response = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
check(response, {
'Acesso concedido a partir de token valido': (r) => r.status === 200
});
}
export function idempotency() {
const url = `${baseUrl}/payments`;
const headers = {
'Authorization': user2Token,
'Content-Type': 'application/json',
'Idempotency-Key': uuidv4(),
'remote-ip': randomIp()
};
const response = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
const response2 = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
headers['Idempotency-Key'] = uuidv4()
const response3 = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
const anyFailed = response.status !== 200 || response2.status !== 200 || response3.status !== 200;
if (anyFailed) {
check(response, {
'Criação de cobrança com chave de idempotência duplicada': false,
'Criação de cobrança com chave de idempotência sem uso': false
})
return;
}
const paymentId1 = response.json().id;
const paymentId2 = response2.json().id;
const paymentId3 = response3.json().id;
check(response, {
'Criação de cobrança com chave de idempotência duplicada': paymentId1 === paymentId2,
'Criação de cobrança com chave de idempotência sem uso': paymentId1 !== paymentId3
});
}
export function quota() {
const url = `${baseUrl}/payments`;
const headers = {
'Authorization': __ENV.USER,
'Content-Type': 'application/json',
'Idempotency-Key': uuidv4(),
'remote-ip': randomIp()
};
const response = http.post(url, buildPaymentPayloadRequest(), { headers: headers });
const dailyLimit = 100;
const expectedStatus = exec.scenario.iterationInTest < dailyLimit ? 200 : 429;
const title = `Limite de requisições diárias ${__ENV.exceeded === 'true' ? 'Excedido' : ''}`;
check(response, {
[title]: (r) => r.status === expectedStatus
})
}
function buildPaymentPayloadRequest() {
return JSON.stringify({
"dueDate": "2024-11-09",
"value": 30.00,
"description": "Oi",
"customer": {
"name": "Joao Silva Costa",
"cpfCnpj": "39105420008"
},
"billingType": "PIX"
});
}
export function setup() {
return {paymentId: 1};
}
export function handleSummary(data) {
return {
stdout: textSummary(data, { indent: '→', enableColors: true }),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment