Unique login for each virtual User

Hi @Harshsahay

I created an example that I hope can help. Based on our public test API that accepts bearer tokens.

import http from 'k6/http';
import exec from 'k6/execution';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';

const sharedData = new SharedArray("Shared Logins", function () {
    let data = papaparse.parse(open('test-users.csv'), { header: true }).data;
    return data;
});

let vuToken;
let request_headers;

export const options = {
    vus: 2,
    iterations: 10,
};

/**
 * Gets user token from username and password
 * @function
 * @param  {string} username - Username
 * @param  {string} password - Password
 */
export function getToken(username, password) {
    let data = {
        username: username,
        password: password,
    };
    const response = http.post('https://test-api.k6.io/auth/token/login/', JSON.stringify(data), {
        headers: { 'Content-Type': 'application/json' },
    });
    return response.json('access');
}

export default function () {

    if (vuToken === undefined) {
        vuToken = getToken(sharedData[exec.vu.idInTest - 1].username, sharedData[exec.vu.idInTest - 1].password)
        request_headers = {
            'content-type': "application/json",
            'Authorization': `Bearer ${vuToken}`
        };
    }

    // create a crocodrile
    const croc = {
        name: 'My Croc',
        sex: 'F',
        date_of_birth: '2019-01-01',
    };
    console.log("request_headers: ", request_headers);
    let response = http.post('https://test-api.k6.io/my/crocodiles/', JSON.stringify(croc), { headers: request_headers });
    check(response, {
        'is status 201': (r) => r.status === 201,
    });
    // get private crocrodile list
    response = http.get('https://test-api.k6.io/my/crocodiles/', { headers: request_headers });
    console.log('My Crocodiles: ', response.json());
}

This with a file test-users.csv which contains a couple of users:

username,password
user1@example.com,superCroc2021
user2@example.com,superCroc2019

Would result in:

running (00m04.4s), 0/2 VUs, 10 complete and 0 interrupted iterations
default ✓ [======================================] 2 VUs  00m04.4s/10m0s  10/10 shared iters

     ✓ is status 201

     checks.........................: 100.00% ✓ 10       ✗ 0  
     data_received..................: 26 kB   5.9 kB/s
     data_sent......................: 9.6 kB  2.2 kB/s
     http_req_blocked...............: avg=19.19ms  min=4µs      med=8.5µs    max=212.24ms p(90)=14.9µs   p(95)=199.48ms
     http_req_connecting............: avg=9.31ms   min=0s       med=0s       max=102.52ms p(90)=0s       p(95)=97.31ms 
     http_req_duration..............: avg=374.8ms  min=115.44ms med=126.95ms max=2.92s    p(90)=150.16ms p(95)=2.67s   
       { expected_response:true }...: avg=374.8ms  min=115.44ms med=126.95ms max=2.92s    p(90)=150.16ms p(95)=2.67s   
     http_req_failed................: 0.00%   ✓ 0        ✗ 22 
     http_req_receiving.............: avg=147.18µs min=65µs     med=146µs    max=282µs    p(90)=211.6µs  p(95)=256.79µs
     http_req_sending...............: avg=48.13µs  min=26µs     med=45.5µs   max=96µs     p(90)=71.7µs   p(95)=74.84µs 
     http_req_tls_handshaking.......: avg=9.77ms   min=0s       med=0s       max=108.68ms p(90)=0s       p(95)=101.02ms
     http_req_waiting...............: avg=374.61ms min=115.21ms med=126.79ms max=2.92s    p(90)=149.93ms p(95)=2.67s   
     http_reqs......................: 22      4.99944/s
     iteration_duration.............: avg=868.36ms min=240.94ms med=249.92ms max=3.39s    p(90)=3.29s    p(95)=3.34s   
     iterations.....................: 10      2.272473/s
     vus............................: 2       min=2      max=2
     vus_max........................: 2       min=2      max=2

Each VU will create their token on the first iteration and reuse it. That should work if the tokens do not expire during the test.

You cannot create a token in the setup() function. As per k6 lifecycle, the setup is called only once. Thus cannot contain code that should be executed per VU.

I hope this helps. Thanks for your patience.

Cheers!