K6 - iterate over array, but not for each VU

Viewed 1540

I am working on a script to test my infra using k6.

I would like each VU be assigned to a previous known id obtained from an existing array and that VU execute the instructions from the default function only once at the time the VU is created.

How to iterate over this array, get the id and use it for each VU created by the script?

The initial idea is bellow, but I am sure it is not correct.

export let options = {
    stages: [
        { duration: '10s', target: 1 },
        { duration: '10s', target: 10 },
    ],
};

const ids = [
    {'id':1, 'name':'name1'},
    {'id':3, 'name':'name3'},
    {'id':4, 'name':'name4'},
    {'id':18, 'name':'name18'}];

export default function () {
    for(var i=0; i<ids.length; i++) {
        var user = ids[i];
        //do something with user.id
    }
}

According to K6 manual, each VU will execute everything is inside the default function, but it would make all VU's execute the for loop and it is not the behavior I want.

I want the VU execute what is inside the for, but using a different id for each new VU. Something like bellow:

export default function () {
    var user = ids[i];
    //do something with user.id
}
2 Answers

From k6 version 0.34 ,there is a solution for this issue.

import exec from "k6/execution";
import { SharedArray } from "k6/data";
import http from "k6/http";


const data = new SharedArray("my dataset", function(){
    const ids = [
        {'id':1, 'name':'name1'},
        {'id':3, 'name':'name3'},
        {'id':4, 'name':'name4'},
        {'id':18, 'name':'name18'}
    ];
    return ids;
})

export const options = {
  scenarios :{
    "use-all-the-data": {
      executor: "shared-iterations",
      vus: data.length,
      iterations: data.length,
      maxDuration: "30s"
    }
  }
}

export default function() {
  // this is unique even in the cloud
  var item = data[exec.scenario.iterationInTest];
  http.post("https://httpbin.test.k6.io/anything?endpoint=amazing", item)
  console.log(JSON.stringify(item))
}

I end up solving this specific scenario using a combination of... scenarios :-) and the global variable __VU.

At the scenario configuration, I said that each VU would iterate only 1 time during all the test and I would launch as much VU's as I had in the ids array. This way, each VU would use one of the ids and run the default function only 1 time.

Because __VU starts from 1, I had also to use __VU-1 to correctly index the array.

const ids = [
    {'id':1, 'name':'name1'},
    {'id':3, 'name':'name3'},
    {'id':4, 'name':'name4'},
    {'id':18, 'name':'name18'}];

export let options = {
    scenarios: {
        stress_test: {
            executor: 'per-vu-iterations',
            vus: ids.length,
            iterations: 1
        }
    }
};

export default function () {
    var user = ids[__VU-1];
    //do something with user.id
}
Related