Sorry, let me try to explain better.
Currently, we are using JMeter to perform our performance tests, and we are migrating this architecture to use K6.
We have a .jmx file containing a Thread Group with a fixed number of Threads (80), and below it, some Throughput Controllers with configuration for percentage execution relative to the Thread Group.
Within each Throughput Controller, we have a request that will be executed at a certain percentage relative to the Thread Group, and each request uses a .csv data file as input. With each execution of this request, it will use the next line of the CSV data.
To replicate this architecture in K6, we are creating a class for each request with its information, similar to the one below:
import { check } from 'k6';
import http from 'k6/http';
import Utils from "../../utils/utils.js";
export default class req_test_extrac_01 {
constructor() {
this.params = Utils.baseHeaders();
}
exec() {
let bodyData = `
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://test.com.br">
<soapenv:Header/>
<soapenv:Body>
<aut:req_test_extrac>
<aut:dataRefer>06/09/2023</aut:dataRefer>
</aut:req_test_extrac>
</soapenv:Body>
</soapenv:Envelope>`;
let response = http.post(`${Utils.getServerAPI()}${Utils.getPathCC()}`, bodyData, this.params)
check(response, { 'status was 200': (r) => r.status == 200 });
}
}
With this class created, we use a FullLoad.test.js file to control all executions following the pattern below:
First, we define the execution percentage of each request relative to the total:
let groups = [
{ name: 'req_test_extrac_01', target: 0.10269602 },
{ name: 'req_test_extrac_02', target: 0.5 },
{ name: 'req_test_extrac_03', target: 0.5 },
{ name: 'req_test_extrac_04', target: 0.02613226 },
{ name: 'req_test_extrac_05', target: 0.005804558 },
{ name: 'req_test_extrac_06', target: 0.31 },
{ name: 'req_test_extrac_07', target: 0.5 },
{ name: 'req_test_extrac_08', target: 0.5 },
];
Then, we resize them so that the sum of all targets equals 1:
const totalTarget = groups.reduce((acc, group) => acc + group.target, 0);
groups.forEach(group => {
group.target /= totalTarget;
});
We create a function to initialize instances of all request classes:
function createGroupInstance(groupName) {
switch (groupName) {
case 'req_test_extrac_01':
return new req_test_extrac_01();
case 'req_test_extrac_02':
return new req_test_extrac_02();
case 'req_test_extrac_03':
return new req_test_extrac_03();
case 'req_test_extrac_04':
return new req_test_extrac_04();
case 'req_test_extrac_05':
return new req_test_extrac_05();
case 'req_test_extrac_06':
return new req_test_extrac_06();
case 'req_test_extrac_07':
return new req_test_extrac_07();
case 'req_test_extrac_08':
return new req_test_extrac_08();
default:
return null;
}
}
We create the execution option using shared iterations with vus = 10 and unlimited duration (The idea is for our tests to run with unlimited iterations for a certain period of time):
export let options = {
scenarios: {
contacts: {
executor: 'shared-iterations',
vus: 10,
iterations: 999999999999999,
maxDuration: '10m',
}
}
};
Finally, we use the default function to execute the exec() method of each class according to its execution percentage relative to the total VUs:
export default function() {
let random = Math.random();
let selectedGroup = null;
// Capture the group to be executed
for (const groupInfo of groups) {
if (random <= groupInfo.target) {
selectedGroup = groupInfo.name;
break;
} else {
random -= groupInfo.target;
}
}
// Create an instance of the group to be executed
const groupInstance = createGroupInstance(selectedGroup);
if (groupInstance) {
group(groupInstance.name, () => {
groupInstance.exec();
});
}
}
Now, consider that we have one .csv file for each request (req_test_extrac_01, req_test_extrac_02, req_test_extrac_03, etc.). When we attempt to read this .csv file using SharedArray and pass this information to each request, we don’t have the information about which index of each request K6 is currently at so that we can read the corresponding line from the .csv file.
I’ve tried to use the exec.scenario.iterationInTest, but it returns the total iteration counter and I need a way to count each class.exec() run.