2

I am trying to setup a run in K6 with staged setup and rundown. I am trying to find out how to setup K6 so that it will start a new iteration of the run once the stages are complete. Do I simply include iterations in the stage block, or is there something else I need to do?

Steven Brooks
  • 31
  • 1
  • 2
  • 4
    Hi Steven, you'll need to be a lot clearer and more precise in your problem statement. Your question as it stands is vague and you haven't explained what you've tried or what the issue you've encountered is. Please read https://stackoverflow.com/help/how-to-ask for more information on how to structure a question so it will get answered. – Richard Matheson Jan 08 '19 at 17:23

1 Answers1

1

What you basically want is a given set of stages to repeat over prolonged period of time.

There are two solutions:

  1. Just run the script in a loop in a bash/cmd/shell script - will have some pauses in between runs as k6 will need to initialize again. Additionally you will have multiple outputs but this might not be bad, see below

  2. Have stages that are as many as you need. You can do it by hand or just script it inside the test script:

import http from "k6/http";
import { check, sleep } from "k6";

let stages = [// total 30 seconds
        // Ramp-up from 1 to 5 VUs in 10s
        { duration: "10s", target: 5 },

        // Stay at rest on 5 VUs for 5s
        { duration: "5s" },

        // Ramp-down from 5 to 0 in 15s
        { duration: "15s", target: 0}
    ];

let final_stages = [];

// 30 seconds by 120 seconds is 3600 seconds or 1 hour
for (let i =0 ;i < 120; i++) {
    final_stages = final_stages.concat(stages)
}

export let options = {
    stages: final_stages,
    discardResponseBodies: true
};

export function setup() {
    console.log(JSON.stringify(options.stages));
}
export default function(testStart) {
        // normal execution
        let res = http.get("http://httpbin.org/");
        check(res, { "status is 200": (r) => r.status === 200 });
}

I highly advise running k6 with --no-summary and maybe even --no-thresholds or just not using thresholds if the time it will be ran for will be great as you are probably going to run out memory just collecting data inside k6. This means that you probably should use some storage for the metrics like influxdb or even Load Impact's Insights. This of course might not be true in your case - you will have to check :).

Answer as I understood the question previously: "I want to have stages and then I want to do some concrete amount of iterations of the script instead of for a given duration as will happen with another stage"

The simple answer is no.

If you have stages, iterations and duration for a test are mutually exclusive - only one of them will be taken into account. Look at the end for possible work around.

Long answer:

If I understand correctly what you want is to have a bunch of stages and then after all the stages have ran to have a few VUS which do a given number of iterations. This is currently not supported and is interesting to us (the k6 team) why you would need this.

Workaround(s): Currently I can think of two workarounds - both hacky:

  1. If you don't need anything from the test in the later iterations make two tests and make a bash/shell/cmd script to run them one after the other. This will have some pause in between the test runs and you will have two outputs but will definitely be easier.
  2. Make another stage after all the stages have finished with long enough duration to run all the iterations. Have a variable that you record the beginning of the whole test - preferably in the setup and then calculate when you reach the last stage. Run as many iterations as you want and then sleep for the remaining of the test.

It's important to note that at this point there is no way to communicate between VUs, so you will have to decide that when you have 10 VUs each will do 5 to get 50 iterations and maybe one VU will finish much faster or later or something like that.

import http from "k6/http";
import { check, sleep } from "k6";

export let options = {
    stages: [
        // Ramp-up from 1 to 5 VUs in 10s
        { duration: "10s", target: 5 },

        // Stay at rest on 5 VUs for 5s
        { duration: "5s" },

        // run for some amount of time after that
        { duration: "15s"}
    ],
    discardResponseBodies: true
};
export function setup() {
    return Date.now();
}

let iter = 5; // how many iteration per VU should be done in the iterations part
export default function(testStart) {
    // 15ms is the amount of time for the pre iterations phase
    if (Date.now() - testStart > 15 * 1000) {
        // "iterations part"
        if (iter == 0) { // we have ran out of iterations to do
            sleep(15000) // sleep for the duration of the phase
        }
        iter = iter - 1;
        // debug log
        console.log(__VU, __ITER, iter);

        // the actual part you want  to do
        let res = http.get("http://httpbin.org/");
        check(res, { "status is 200": (r) => r.status === 200 });

    } else {
        // normal execution
        let res = http.get("http://httpbin.org/");
        check(res, { "status is 200": (r) => r.status === 200 });
    }
}
 
This obviously needs to be tailored to your case and won't be exact, but once again it's much more interesting what you want to do with it and why.

Sidenote:

During the discussion of the arrival rate based execution this has been discussed and the current plan is this to be supported but this work is probably at least a month a way from alpha/beta capability as there is a lot of internal refactoring needed for supporting everything we want to add along with it. You should probably write an issue with your use case as to be taken into consideration in the future.

  • 1
    I was trying to do something similar to what you describe. I am trying to stress test an environment and want to be able to run a full run (ramp up, hold, and ramp down stages), wait for x amount of time, and rerun the whole thing again (and have this cycle run for a set amount of time or iterations). The number of VUs is not really what is important, but the ability to have it run overnight, for example, is what I was trying to do. I hope that clears it up some. – Steven Brooks Jan 09 '19 at 16:40
  • Could you edit your question to better explain it as you did in this comment – Михаил Стойков Jan 10 '19 at 08:51