Cycling the VUs during the test

Hi,

I’d like to test the performance of the system under the load from different users during a long period of time. For example, I’d like to run a test for 10 hours and the test should use 1k users. The catch is that I’d like the users to be different and rotate each 30 minute or so. So, 1k users spawn, do their thing for 30 minutes, then they start despawning and another 1k spawns to run for the next 30 minutes.

What I could do is use stages, something like this:

-s 10s:100, 1800s:100, 10s:0, 10s:100, 1800s:100, 10s:0... //repeating for the desired number of batches

My question is, is there any way to elegantly setup the test with the desired properties or is the repeating stages configuration the best possible way?

The scenario also looks a bit similar to this one: https://k6.io/docs/using-k6/scenarios/advanced-examples/#using-multiple-scenarios

However, in my case I don’t have multiple different scenarios, but rather N copies of the same scenario.

Hi @vlad_stryapko,

k6 will reuse VUs and there isn’t really any way to tell k6 to not use some VUs and spawn new ones without playing heavily with sleep and preallocatedVUs + maxVUs in an arrival rate executor - which both will be very fragile and a waste of a lot of resources.

The question I guess is how to reset something on the VUs every 30 minutes I would expect that what you want is to close all old connections and clear cookies?
The clearing of the cookies will be fairly straightforward just use the API to get the default cookie jar and for the URLs you are hitting set all cookies to an empty value … It will probably be a good idea for us to have some method to clear all cookies. Alternatively, you can use a custom jar that you remake every 30 minutes.

Unfortunately, closing connections isn’t really supported unless we are talking of closing all of them between iterations or on each request, this one I think doesn’t work very well with http2.

But maybe that is sufficient for you? Can you elaborate on why you want completely new VU and what do you think that will change.

Yep, exactly.

Here’s the basic workflow of my VU:

  1. Generate a UUID
  2. Send an HTTP request to auth with a generated UUID
  3. Receive an auth token
  4. Open a websocket connection using the token
  5. Send messages in a loop

Now, what I’d like is to periodically repeat this flow. For example, instead of 1 VU running it for 60 minutes, I’d like this VU to run the flow for 15 minutes, then close the socket connection, clear cookies and other state, and repeat the auth process. I don’t need a new VU per se, it’s fine if the VU is the same, but I need to make sure the previous state is absolutely cleared, so that this VU looks as a new user, essentially.

Can you elaborate on why you want completely new VU and what do you think that will change.

Yeah, so, as I mentioned before, I don’t necessarily need a new k6 VU. If it’s possible to completely reset the state of the existing VU and make it repeat the flow, it’s absolutely fine for my scenario.

Given your workflow I would say that you just need to create a cookie jar and provide it to both the HTTP and the ws requests and then when you want to reset it to just create a new cookiejar.
This will:

  1. reset the cookies every time
  2. websocket connections can’t be reused as they start as HTTP ones and then get “upgraded”
  3. because of the above + the fact that you will be in a connection for quite a while the connection for the auth token would either be closed by that time or would’ve been used to do the ws one and not being able to be reused.

Sample code

  var jar = new http.CookieJar();
  // generate UUID
  http.get(url, {jar: jar}) // use the jar
  ws.connect(url, {jar:jar}, function (socket){
   // your ws code
  });

This will only work with k6 v0.35.0+ as we just added support for cookie jars in websockets. If you have to use an older one you can just get the auth token out of the jar and send it as a normal header I guess.

Hope this helps

Thanks, looks OK.

The only question I have is how to determine when to make VU close the current WS connection and repeat the flow. I suppose I have to manually track the time elapsed using some kind of timer and force the VU to start from scratch when the timer fires. Does that make sense?

k6/ws has timers and timeouts and in case you can’t/don’t want to use them you can also just use Date.now() and check that some time since the last time has elapsed :man_shrugging:

Sounds good, I think I’ll go that route then. Thanks.