How to distribute VU's across different scenarios with k6

Here’s a very crude example of how something like this can be implemented in a few lines of JS:

import { sleep } from 'k6';

function weightedSwitch(weightedFuncs) {
    var funcIntervals = new Array(weightedFuncs.length)

    var weightSum = 0;
    for (var i = 0; i < weightedFuncs.length; i++) {
        funcIntervals[i] = {
            start: weightSum,
            end: weightSum + weightedFuncs[i][0],
            func: weightedFuncs[i][1],
        }
        weightSum += weightedFuncs[i][0];
    }

    if (Math.abs(weightSum - 1) > 0.0001) {
        throw new Error('the sum of function weights should be 1 (100%), but is ' + weightSum);
    }

    return function (val) {
        var guess, min = 0, max = funcIntervals.length - 1;;
        while (min <= max) {
            guess = Math.floor((max + min) / 2);

            if (val >= funcIntervals[guess].end) {
                min = guess + 1;
            } else if (val < funcIntervals[guess].start) {
                max = guess - 1;
            } else {
                return funcIntervals[guess].func;
            }
        }
    }
}

export let options = {
    duration: '1m',
    vus: 2,
};

var getFunction = weightedSwitch([
    [0.1, () => "scenario 0 (10%)"],
    [0.1, () => "scenario 1 (10%)"],
    [0.21, () => "scenario 2 (21%)"],
    [0.39, () => "scenario 3 (39%)"],
    [0.199, () => "scenario 4 (19.9%)"],
    [0.001, () => "scenario 5 (0.1%)"],
])


export default function () {
    var rand = Math.random();
    var f = getFunction(rand);
    console.log(`VU ${__VU}, iter ${__ITER}, rand ${rand.toFixed(4)} executed ${f()}`);
    sleep(1);
}

I don’t make any guarantees that I don’t have an off-by-one error in the binary search code or something like that, I haven’t tested this code much, but it seems to work well enough…

When you run it, it should print something like this:

INFO[0000] VU 2, iter 0, rand 0.3661 executed scenario 2 (21%)  source=console
INFO[0000] VU 1, iter 0, rand 0.4241 executed scenario 3 (39%)  source=console
INFO[0001] VU 2, iter 1, rand 0.3712 executed scenario 2 (21%)  source=console
INFO[0001] VU 1, iter 1, rand 0.1931 executed scenario 1 (10%)  source=console
INFO[0002] VU 1, iter 2, rand 0.3077 executed scenario 2 (21%)  source=console
INFO[0002] VU 2, iter 2, rand 0.7144 executed scenario 3 (39%)  source=console
INFO[0003] VU 1, iter 3, rand 0.6757 executed scenario 3 (39%)  source=console
INFO[0003] VU 2, iter 3, rand 0.1091 executed scenario 1 (10%)  source=console
INFO[0004] VU 1, iter 4, rand 0.9282 executed scenario 4 (19.9%)  source=console
INFO[0004] VU 2, iter 4, rand 0.5826 executed scenario 3 (39%)  source=console
INFO[0005] VU 2, iter 5, rand 0.3474 executed scenario 2 (21%)  source=console
INFO[0005] VU 1, iter 5, rand 0.7628 executed scenario 3 (39%)  source=console
INFO[0006] VU 2, iter 6, rand 0.9356 executed scenario 4 (19.9%)  source=console
INFO[0006] VU 1, iter 6, rand 0.0033 executed scenario 0 (10%)  source=console
...
1 Like