I have a problem statement where i need to call token api every hour to generate the token and pass it on to the next api , As token expires every hour
I saw many solutions on community but none of them are helping .
Some solutions i tried doing :
Using elapsed time …but when i use this concept in default function …then also after every hour token api will be called not once but equal to the number of virtual users am running . And i want to call token api once and want all vusers to use that generated token .
I thought of storing the token value in csv file and read it dynamically every hour . But seems like even papa parse works on static files [ open the file once and read the data ]
setup function only runs once during the tenure of test duration so cant use it .
Not sure how i can achieve this . Please suggest on how we can do this .
Hi, not an elegant (more like very ugly) but working solution that we used is such case.
It is a combination of the approach you mention as solution #1 + some additional logic.
So, there is no way to manage the flow you have in mind with just k6. (or at least we haven’t found such).
Considering this, we created a simple service that calls for new token once the previous expires and exposes only one GET endpoint that returns this token.
So now our k6 script is calling this helper service once an hour to get fresh token. But although each VU is going to make such call, but real call for new token is made only once when the first VU reaches out for new token. After that call, the same token is returned by helper service to all subsequent calls.
This solution obviously has a lot of downsides (starting from the need to build and spin new service), but it worked for us.
Thanks @hbadger for the reply . If it worked its not ugly . Either way i see no other solution apart from the one you proposed . Waiting to hear from others …any other ideas if we can achieve this . In jmeter it was possible using different thread groups , not sure if we can introduce such functionality in k6 as well or any such thing like setting a global variable value dynamically and fetching from there .
Hi @Shabd Instead of developing a service for this purpose as @hbadger proposes, you can also consider using redis store the token. You can then create a separate function in k6 that refresh this token periodically.
Discussing this further with the k6 oss team, what we recommend is usually asking “How will this actually work?”. What we are usually trying to achieve with load testing is doing what users will do:
- If the users login independently, it would be ok to have VUs each use their own token and refresh it once it expired. If the login API cannot handle that load with the test, something to fix as this might be a real scenario?
- Or are all your users sharing the same token until it expires? If so, how do they refresh it, do you have a centralized service?
- Also, users not always stay on the site for hours. If that is your case, rotating users and logging in and out will be replicating the behavior.
If you can further describe the scenario, providing more context, we might be able to help further. From what we understand at this point, “doing what the users will do” if they need to re-login would allow you to implement a realistic-enough test.
Thanks @eyeveebe for the reply and apology for late reply . I agree with the above points but some time tokens are generated by third party/out of box api and they may not provide that much scalability in lower environment …in those cases we focus mainly on the performance of our services and try not to test there services more because there could be rate limit set in lower environment because of cost and all .
Hi @eyeveebe, I agree that most seed data shared across an entire load test might not need to be changed, but I feel that the auth token is a special case that needs to be handled so I would like to add a vote for the k6 ability to share a single mutable variable for this purpose. This has been possible in JMeter for years: setting a (global) property then assigning to a variable, with the ability to update/replace the property when needed. While a separate token per VU is the primary use case, many microservice environments will have service-to-service communication in the backend where no user is involved. We refer to them as backchannel tokens. One example may be: an end user interacts with “service 1” to POST some new data entity. After “service 1” adds the data entity, under the covers an async transaction is sent to “service 2” to create an email message from a template. After that email message is created, “service 2” queues up a transaction to “service 3” to send that email message out then update the email message as delivered. Here, “service 2” and “service 3” are more generic foundational services and they need to be independently load tested using their specific endpoints. The token between “service 1” and “service 2” and between “service 2” and “service 3” are client_credentials grant type and a single token can serve the purpose for testing 2 and 3. But, these tokens have very short expirations. Even our regular user tokens (i.e. “service 1”) have a 5 minute expiration. In the UI, as long as they remain active a refresh token is generated under the covers, but to load test “service 1” directly, those token(s) need to be regenerated. For load testing an already performant microservice in isolation, I would prefer to not have to be dependent on the capability of the auth service to handle periodic large spikes of token requests.
Hi @pablochacin do you happen to know if the “xk6-kv” extension is an alternative to Redis or some other separate data store such as SQLite3? I tried using our established Redis environment but could not connect and AFAIK this is related to our Redis being a cluster and using TLS.
“xk6-kv” - A k6 extension to share key-value data between VUs.