Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PERMITE TESTAR CARGA COM K6 #17

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
.DEFAULT_GOAL := help

CONFIG_PATH ?= ./local/config.yaml

PLANS_ENDPOINT ?= `yq .subscriptions.plans_endpoint $(CONFIG_PATH)`
USERS_ENDPOINT ?= `yq .subscriptions.users_endpoint $(CONFIG_PATH)`
SUBSCRIPTIONS_ENDPOINT ?= `yq .payments.subscriptions_endpoint $(CONFIG_PATH)`
PAYMENTS_ENDPOINT ?= `yq .server.endpoint.http $(CONFIG_PATH)`

CMD_K6_RUN ?= K6_WEB_DASHBOARD=true k6 run -e PLANS_ENDPOINT=$(PLANS_ENDPOINT) -e USERS_ENDPOINT=$(USERS_ENDPOINT) -e SUBSCRIPTIONS_ENDPOINT=$(SUBSCRIPTIONS_ENDPOINT) -e PAYMENTS_ENDPOINT=$(PAYMENTS_ENDPOINT) ./tests/k6/k6s.js

.PHONY: help
help:
@echo Para construir o projeto, execute:
Expand Down Expand Up @@ -42,6 +51,12 @@ build-subscriptions:
build-plans:
@goreleaser build -f=.goreleaser.yaml --snapshot --clean --single-target --id plans

.PHONY: test-load
test-load:
@echo Run K6 to test services
@echo "$(CMD_K6_RUN)"
$(CMD_K6_RUN)

.PHONY: install-tools
install-tools:
@go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
Expand Down
42 changes: 42 additions & 0 deletions tests/k6/k6s.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Testes básicos acessando rotas dos serviços
// VU = virtual user
import { testAddUsers} from "./svc-users.js";
import { testAddPlans} from "./svc-plans.js";
import { testAddSubscriptions} from "./svc-subscriptions.js";
import { testMakePayments} from "./svc-payments.js";

// https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/
export const options = {
// Key configurations for spike in this section
// stages: [
// // A list of VU { target: ..., duration: ... } objects that specify the target number of VUs to ramp up or down to for a specific period.
// { duration: '2m', target: 20 },
// { duration: '1m', target: 1 },
// { duration: '2m', target: 20 },
// ],
// noConnectionReuse: true,
insecureSkipTLSVerify: true,
userAgent: 'k6-otel/1.0',

httpDebug: '',

summaryTimeUnit: 's',

iterations: 200,
duration: '1m',
};

// Global variables should be initialized.

export default function() {

testAddUsers(20);

testAddPlans(20);

testAddSubscriptions(20);

testMakePayments(10);
}


84 changes: 84 additions & 0 deletions tests/k6/svc-payments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import http from "k6/http";
import { group, check } from "k6";
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.6.0/index.js';
import { listSubscriptions } from "./svc-subscriptions.js";

const SVC_PATH = "/payments";
const BASE_URL = `${__ENV.PAYMENTS_ENDPOINT}`;

const getURL = () => {
return fixEndpoint(BASE_URL, SVC_PATH);
}

function fixEndpoint(endpoint, suffixPath) {
if (!endpoint.startsWith("http")) {
if (endpoint.startsWith(":")) {
return `http://localhost${endpoint}${!endpoint.endsWith(suffixPath) ? suffixPath : ""}`;
} else {
return `http://localhost:8080/${endpoint}${!endpoint.endsWith(suffixPath) ? suffixPath : ""}`;
}
}
return endpoint;
}

const listPayments = () => {
const res = http.get(getURL(), { headers: { "Content-Type": "application/json", "Accept": "application/json" } });
return res;
};

const paymentStatus = () => Math.random() < 0.5 ? "SUCCESS" : "FAILED";

const generatePayment = (subscriptionId, amount) => ({
id: uuidv4(),
subscription_id: subscriptionId,
amount,
status: paymentStatus(),
});

const makePayment = (subscriptionId, amount) => {
const payload = JSON.stringify(generatePayment(subscriptionId, amount));
const res = http.post(getURL(), payload, { headers: { "Content-Type": "application/json" } });
return res;
};

export function testListPayments() {
group("list payments", () => {
const res = listPayments();
check(res, { "Successful listing": (r) => r.status === 200 });
});
}

export function testMakePayments(qty) {
group("make payments", () => {
for (let i = 0; i < qty; i++) {
const response = listSubscriptions();
if (response.status !== 200) {
console.error("Failed to list subscriptions:", response.error_code);
continue;
}

try {
const subscriptions = response.json();
const randomSubscription = subscriptions[Math.floor(Math.random() * subscriptions.length)];
const subscriptionId = randomSubscription.id;

const amount = Math.floor(Math.random() * 10);

const paymentResponse = makePayment(subscriptionId, amount);

check(paymentResponse, { // Corrected status code check (201)
"Payment created": (r) => r.status === 201,
});

if (paymentResponse.status !== 201) {
console.error("Failed to make a payment:", paymentResponse.error_code); // Include error for failed payment creation
}

} catch (error) {
console.error("Error processing subscriptions:", error);
}
}
});
}


56 changes: 56 additions & 0 deletions tests/k6/svc-plans.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import http from "k6/http";
import { group, check } from "k6";
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.6.0/index.js';

const BASE_URL = `${__ENV.PLANS_ENDPOINT}`;

const getURL = () => BASE_URL;

export const listPlans = () => {
const req = http.get(getURL(), {headers: {"Content-Type": "application/json", "Accept": "application/json"}});
return req;
}

export function testListPlans() {
group("list plans", () => {
let req = listPlans();
check(req, { "Successful listing.": (r) => r.status === 200 });
});
}

export const generatePlan = () => {
const randomU = Math.floor(Math.random() * 101);

const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const randomLetters = letters[Math.floor(Math.random() * 26)] + letters[Math.floor(Math.random() * 26)];

const obj = {
id: uuidv4(),
name: randomLetters + randomU,
price: randomU * randomU ,
description: "Plan"
};

return obj
};

function addPlan() {
const req = http.post(getURL(), JSON.stringify(generatePlan()), {headers: {"Content-Type": "application/json", "Accept": "application/json"}});
return req;
}

export function testAddPlan() {
group("add plan", () => {
let req = addPlan();
check(req, { "Plan created.": (r) => r.status === 200 });// bug: service should return 201
});
}

export function testAddPlans(qty){
group("add " + qty + " plans", () => {
for (let index = 0; index < qty; index++) {
let req = addPlan();
check(req, { "Plan created.": (r) => r.status === 200 }); // bug: service return should 201
}
});
}
83 changes: 83 additions & 0 deletions tests/k6/svc-subscriptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import http from "k6/http";
import { group, check } from "k6";
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.6.0/index.js';
import { listUsers } from "./svc-users.js";
import { listPlans } from "./svc-plans.js";

const BASE_URL = `${__ENV.SUBSCRIPTIONS_ENDPOINT}`;

const getURL = () => BASE_URL;

export const listSubscriptions = () => {
const req = http.get(getURL(), {headers: {"Content-Type": "application/json", "Accept": "application/json"}});
return req;
}

export function testListSubscriptions() {
group("list subscriptions", () => {
let req = listSubscriptions();
check(req, { "Successful listing.": (r) => r.status === 200 });
});
}

const generateSubscription = (userId, planId) => {
const obj = {
id: uuidv4(),
user_id: userId,
plan_id: planId
};
return obj
};

const addSubscription = (userId, planId) => {
const req = http.post(getURL(), JSON.stringify(generateSubscription(userId, planId)), {headers: {"Content-Type": "application/json", "Accept": "application/json"}});
return req;
}

export function testAddSubscription(userId, planId) {
group("add Subscription", (userId, planId) => {
let req = addSubscription(userId, planId);
check(req, { "Successful listing.": (r) => r.status === 201 });
});
}

export function testAddSubscriptions(qty){
group("add " + qty + " subscriptions", () => {
for (let i = 0; i < qty; i++) {

const usersResponse = listUsers()
if (usersResponse.status !== 200) {
console.error("Failed to list users:", usersResponse.error_code);
continue;
}

try {
const users = usersResponse.json();
const randomUser = users[Math.floor(Math.random() * users.length)];
const userId = randomUser.id;

const plansResponse = listPlans()
if (plansResponse.status !== 200) {
console.error("Failed to list plans:", plansResponse.error_code);
continue;
}
const plans = plansResponse.json();
const randomPlan = plans[Math.floor(Math.random() * plans.length)];
const planId = randomPlan.id;

const response = addSubscription(userId, planId);
check(response, {
"Subscription created.": (r) => r.status === 200, // bug: service return should 201
});

if (response.status !== 200) {
console.error("Failed to add a subscription:", response.error_code);
}

} catch (error) {
console.error("Error processing subscriptions:", error);
}
}
});
}

51 changes: 51 additions & 0 deletions tests/k6/svc-users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import http from "k6/http";
import { group, check } from "k6";
// import { faker } from "https://esm.sh/@faker-js/[email protected]"
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.6.0/index.js';

const BASE_URL = `${__ENV.USERS_ENDPOINT}`;

const getURL = () => BASE_URL;

export const listUsers = () => {
const req = http.get(getURL(), {headers: {"Content-Type": "application/json", "Accept": "application/json"}});
return req;
}

const generateUser = () => {
const obj = {
id: uuidv4(),
name: "teste" + uuidv4(), //faker.person.firstName(),
email: "teste" + uuidv4() + "@test.com" //faker.internet.email()
};
return obj
};

const addUser = () => {
const req = http.post(getURL(), JSON.stringify(generateUser()), {headers: {"Content-Type": "application/json", "Accept": "application/json"}});
return req;
}

export function testListUsers() {
group("list users", () => {
const req = listUsers();
check(req, { "Successful listing.": (r) => r.status === 200 });
});
}

export function testAddUser() {
group("add user", () => {
let req = addUser();
check(req, { "User created.": (r) => r.status === 200 }); // bug: service return should 201
});
}

export function testAddUsers(qty){
group("add " + qty + " users", () => {
for (let index = 0; index < qty; index++) {
let req = addUser();
check(req, { "User created.": (r) => r.status === 200 }); // bug: service return should 201
}
});
};