Hi,
I’m using the K6 scenarios to send multiple API requests that goes to 3 different pages. I want to do a load test for all 3 pages at once.
So I configured a scenario as below. and I set the authentication with in the function of the executed scenario. With this approach the authentication call is getting executed for all 3 calls separately. ( 3 times)
How can I configure a single authentication call that could be used for all the 3 scenarios? (I want to make the authentication with dynamic users, but once a token is generated that token can be shared for all 3 scenarios)
import http from 'k6/http';
import {check} from 'k6';
import generateAccessToken from '../helpers/generateAccessToken.js';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';
import {SharedArray} from "k6/data";
import { Trend } from 'k6/metrics';
const waiting_trend = new Trend('waiting_time(ms)');
const receiving_trend = new Trend('receiving_time(ms)');
const sending_trend = new Trend('sending_time(ms)');
const url = __ENV.GATEWAY_URL ? __ENV.GATEWAY_URL : 'https://gateway.stg.com';
const programPK = __ENV.PROGRAM_PK ? __ENV.PROGRAM_PK : 1;
const datafile = __ENV.DATA_FILE ? __ENV.DATA_FILE : './../data/users.csv';
const TEST_2_RUN = __ENV.TEST_2_RUN ? __ENV.TEST_2_RUN : 'smoke';
let Execution = TEST_2_RUN;
let ExecutionOptions_Scenarios;
let ExecutionOptions_Thresholds;
const ExecutionType = {
load: 'load',
smoke: 'smoke'
}
const sharedData = new SharedArray('Logins', function () {
return papaparse.parse(open(datafile), {header: true}).data;
});
const thresholdsValues = JSON.parse(open(__ENV.MY_CONFIG_FILE ? __ENV.MY_CONFIG_FILE : './../config/common_thresholds_config.json'));
switch(Execution) {
case ExecutionType.smoke:
ExecutionOptions_Scenarios = {
Profile: {
executor: 'shared-iterations',
exec: 'S01_Common_Page',
vus: 5,
iterations: 10,
maxDuration: '30s',
env: { PAGE: 'profile'}
},
Recent_Activity: {
executor: 'shared-iterations',
exec: 'S01_Common_Page',
vus: 5,
iterations: 10,
maxDuration: '30s',
env: { PAGE: 'recent_activity'}
},
Follow: {
executor: 'shared-iterations',
exec: 'S01_Common_Page',
vus: 5,
iterations: 10,
maxDuration: '30s',
env: { PAGE: 'follow'}
}
};
ExecutionOptions_Thresholds = thresholdsValues.Program.smoke_thresholds;
break;
case ExecutionType.load:
ExecutionOptions_Scenarios = {
Profile: {
executor: 'ramping-vus',
exec: 'S01_Common_Page',
stages: [
{ target: 50, duration: '2m' },
{ target: 50, duration: '10m' },
{ target: 0, duration: '1m' },
],
env: { PAGE: 'profile'}
},
Recent_Activity: {
executor: 'ramping-vus',
exec: 'S01_Common_Page',
stages: [
{ target: 50, duration: '2m' },
{ target: 50, duration: '10m' },
{ target: 0, duration: '1m' },
],
env: { PAGE: 'recent_activity'}
},
Follow: {
executor: 'ramping-vus',
exec: 'S01_Common_Page',
stages: [
{ target: 50, duration: '2m' },
{ target: 50, duration: '10m' },
{ target: 0, duration: '1m' },
],
env: { PAGE: 'follow'}
}
};
ExecutionOptions_Thresholds = thresholdsValues.Program.load_thresholds;
break;
}
export let options = {
scenarios: ExecutionOptions_Scenarios,
thresholds: ExecutionOptions_Thresholds,
hosts: thresholdsValues.DNS_Resolve,
};
// Define a Common Scenario
export function S01_Common_Page () {
let randomUser = sharedData[Math.floor(Math.random() * sharedData.length)]
const membersList = Array.from({length: 20}, () => sharedData[Math.floor(Math.random() * sharedData.length)].USERNAME );
// Profile Queries
const memberProfile_query = memberProfileQuery(randomUser.USERNAME, programPK);
const newsfeed_profile_query = newsFeedProfileQuery(10, randomUser.USERNAME);
// const members_query = membersQuery(JSON.stringify(membersList), programPK);
// Recent_Activity Queries
const memberDetails_query = memberDetailsQuery(randomUser.USERNAME, programPK);
const memberReports_query = memberReportsQuery(randomUser.USERNAME, programPK);
const memberGroups_query = memberGroupsQuery(randomUser.USERNAME, programPK);
const newsfeed_query = newsFeedQuery(7);
const members_query = membersQuery(JSON.stringify(membersList), programPK);
const activeProgramTheme_query = activeProgramThemeQuery();
const isNewsfeedAdmin_query = isNewsfeedAdminQuery();
const newsfeedConfigurationForProgram_query = newsfeedConfigurationForProgramQuery();
const viewer_query = viewerQuery();
const menus_query = menusQuery();
const newsfeedConfig_query = newsfeedConfigQuery('en-US');
const activeProgramThemeLogo_query = activeProgramThemeLogoQuery();
const GetProgramPrimaryHierarchyInfo_query = GetProgramPrimaryHierarchyInfoQuery(programPK);
// Follow Queries
const memberFollow_query = memberFollowQuery(randomUser.USERNAME, programPK,100);
const membersToFollow_query = membersToFollowQuery(randomUser.USERNAME, programPK,10);
const authToken = __ENV.AUTH_TOKEN ? __ENV.AUTH_TOKEN : generateAccessToken(randomUser.USERNAME, randomUser.PASSWORD, programPK);
if( authToken ){
if(__ENV.PAGE == 'profile'){
requestExecutor(newsfeed_profile_query, 'newsfeedProfileEvents', authToken);
requestExecutor(memberProfile_query, 'memberProfile', authToken);
requestExecutor(members_query, 'members', authToken);
}if(__ENV.PAGE == 'recent_activity'){
requestExecutor(activeProgramTheme_query, 'activeProgramTheme',authToken);
requestExecutor(isNewsfeedAdmin_query, 'isNewsfeedAdmin',authToken);
requestExecutor(newsfeedConfigurationForProgram_query, 'newsfeedConfigurationForProgram',authToken);
requestExecutor(viewer_query, 'viewer',authToken);
requestExecutor(menus_query, 'menu',authToken);
requestExecutor(newsfeedConfig_query, 'newsfeedConfig',authToken);
requestExecutor(newsfeed_query, 'newsfeedEvents_Recent',authToken);
requestExecutor(memberDetails_query, 'memberDetails',authToken);
requestExecutor(memberReports_query, 'memberReports',authToken);
requestExecutor(memberGroups_query, 'memberGroups',authToken);
requestExecutor(members_query, 'members',authToken);
requestExecutor(activeProgramThemeLogo_query, 'activeProgramThemeLogo',authToken);
requestExecutor(GetProgramPrimaryHierarchyInfo_query, 'GetProgramPrimaryHierarchyInfo',authToken);
}if(__ENV.PAGE == 'follow'){
requestExecutor(memberFollow_query, 'memberFollow', authToken);
requestExecutor(membersToFollow_query, 'membersToFollow', authToken);
requestExecutor(memberFollow_query, 'memberFollow', authToken);
}
}
}
export function requestExecutor(query, tag, authToken) {
const headers = {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + authToken
};
const res = http.post(url, JSON.stringify({query: query}), {headers: headers, tags: {query_tag: tag}});
// Additional breakdown on http_req_duration
waiting_trend.add(res.timings.waiting);
sending_trend.add(res.timings.sending);
receiving_trend.add(res.timings.receiving);
check(res, {
'Status code 200 OK ': (r)=> r.body && r.status === 200,
'Check the service is returning data': (r)=> r.body && res.headers['Content-Type'].includes('application/json') && !JSON.parse(r.body).hasOwnProperty('errors') && JSON.parse(r.body).hasOwnProperty('data'),
});
}