Changes values on feeder during execution

Hello everyone. How are you?

I implemented on Scala the token generation during execution in Scala.

However, now I have to use multiple users from a feeder and I need to update their token every 400 seconds. I use the variable “BEARER” inside the array. Maybe there is a better way to approach this problem but I’m a little lost. Because setting BEARER during the execution will update only one token and not the other ones.

Here’s the code:

import io.gatling.core.Predef._
import io.gatling.core.structure.{ChainBuilder, ScenarioBuilder}
import io.gatling.http.Predef._

import java.time.LocalDateTime
import scala.concurrent.duration._


class APP_TEST extends Simulation {

  // ------------- VARIABLES ------------- //
  val APIM: String = "testkey"
  val locale: String = "es-co"
  val country: String = "co"

  // -------------Token introspection------------ //
  var token: String = new OIDCAuthentication().getAccessToken()
  var token1: String = new OIDCAuthentication().getAccessToken()
  var token2: String = new OIDCAuthentication().getAccessToken()
  var token3: String = new OIDCAuthentication().getAccessToken()
  var token4: String = new OIDCAuthentication().getAccessToken()

  var testing = Array(
    Map("BEARER" -> token, "cardID" -> "213123", "sub" -> "123456"),
    Map("BEARER" -> token1, "cardID" -> "2112310352", "sub" -> "1234567"),
    Map("BEARER" -> token2, "cardID" -> "12313312", "sub" -> "12345678"),
    Map("BEARER" -> token3, "cardID" -> "1231312", "sub" -> "123456789"),
    Map("BEARER" -> token4, "cardID" -> "123123", "sub" -> "12345678910")
  ).random


  // ------------- TEST CONFIG ------------- //
  val refreshTokenEverySeconds = 400
  var tokenRefreshContinue = true
  var tokenRefreshInstant: LocalDateTime = LocalDateTime.now()

  /////////////////////////////////////////////////////////////// HEADERS ////////////////////////////////////////////////////////
  val httpProtocol = http
    .baseUrl("https://test.com/app")
    .inferHtmlResources()
    .acceptHeader("*/*")
    .acceptEncodingHeader("gzip, deflate")
    .userAgentHeader(
      "Mozilla/5.0 (Linux; Android 13; SM-S901B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36"
    )
    .shareConnections

  val header_Stores: Map[String, String] = Map(
    "APIKEY" -> APIM)

  val header: Map[String, String] = Map(
    "Authorization" -> "#{BEARER}",
    "APIKEY" -> APIM,
    "sub" -> "#{sub}")

  val headerCategories: Map[String, String] = Map(
    "Authorization" -> "#{BEARER}",
    "APIKEY" -> APIM)

  val heade2_2: Map[String, String] = Map(
    "Authorization" -> "#{BEARER}",
    "sub" -> "#{sub}")
  
 
  // ChainBuilder for creating a new Token
  val GeneratenewToken: ChainBuilder =
    exec { session =>
      val token = new OIDCAuthentication().getAccessToken()
      val newToken1 = new OIDCAuthentication().getAccessToken()
      val newToken2 = new OIDCAuthentication().getAccessToken()
      val newToken3 = new OIDCAuthentication().getAccessToken()
      val newToken4 = new OIDCAuthentication().getAccessToken()


      println(s"GeneratedToken 1: $newToken")
      println(s"GeneratedToken 2: $newToken1")
      println(s"GeneratedToken 3: $newToken2")
      println(s"GeneratedToken 4: $newToken3")
      println(s"GeneratedToken 5: $newToken4")

      session
        .set(testing.map("BEARER"), newToken)
        .set(token1, newToken1)
        .set(token2, newToken2)
        .set(token3, newToken3)
        .set(token4, newToken4)

      session
    }

  // Now inserting the ChainBuilder into the the Scenario Builder
  val scnStartTokenSession: ScenarioBuilder = scenario("GET_MY_TOKEN")
    .exec(GeneratenewToken)

  // Refreshing Token during session
  val scnRefreshToken: ScenarioBuilder = scenario("REFRESH_TOKEN")
    .asLongAs(session => tokenRefreshContinue.equals(true)) {
      pause(3.seconds)
        .doIf(session =>
          tokenRefreshInstant
            .plusSeconds(refreshTokenEverySeconds)
            .isBefore(LocalDateTime.now())
        ) {
          exec(session => {
            tokenRefreshInstant = LocalDateTime.now()
            session
          })
            .exec(GeneratenewToken)
        }
    }

  // Scenario for aborting the token
  val scnTokenAbort: ScenarioBuilder = scenario("TOKEN_ABORT")
    .exec { session => {
      tokenRefreshContinue = false;
      session
    }
    }


  // ***************************************
  // ***  Scenario with Normal Requests  ***
  // ***************************************

  val scn: ScenarioBuilder = scenario("APP_TEST")
  .feed(testing)

 ... my requests


  setUp(
    scnStartTokenSession
      .inject(atOnceUsers(1))
      .andThen(
        scnRefreshToken.inject(atOnceUsers(1)),
        // --------------------------------
        scn
          .inject(rampConcurrentUsers(0).to(500).during(1750), constantConcurrentUsers(500).during(50)
          )
          // --------------------------------
          .andThen(scnTokenAbort.inject(atOnceUsers(1)))
      )
  ).protocols(httpProtocol)

}

It’s unclear how many tokens you want. @GeMi 's sample is about using one single token shared for all the virtual users.
If you want one token per virtual user, it’s way better to include the token fetching and refreshing inside your scenario.

I don’t get why you’re trying to have 5 tokens for hundreds of virtual users.

Hello @slandelle

I use only 5 tokens because we’re limited on the amount of users.
I can use only one for all the calls but I’ll get an error message saying that I’ve reached the limit of 5 calls/s with the same token.
So using 5 different tokens would do the job.

But hey also expires after 600 seconds, so I’m in a pickle right now hahaha

Hi @boxfreeman,

Weird use case, but let it be!

So, if I rephrase it with my words, instead of generating a token every period, you want to generate n tokens.
For every calls, there is no connection between the virtual user and the token (the token is not a credentials for you server under load, only a credentials for the proxy).

So, instead of generating a token, you will generate/refresh an array of n token.
each time you want to make a request, you get the next token in a small array (wrapping to the first after the last).

From your code, I see you are almost there.
Either you can generate your n token at the same time, or have a virtual user per token with a personal counter.
I think that only one user, generating your fix amount of tokens will be easier (look after repeat with the named counter), you will be able to update the counterth element of your array.

Does that help?

Cheers!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.