PloniStacker
PloniStacker

Reputation: 666

How to create basic pagination logic in Gatling?

So I am trying to create basic pagination in Gatling but failing miserably.

My current scenario is as follows:

1) First call is always a POST request, the body includes page index 1 and page size 50

 {"pageIndex":1,"pageSize":50}

I am then receiving 50 object + the total count of objects on the environment:

"totalCount":232

Since I need to iterate through all objects on the environment, I will need to POST this call 5 time, each time with an updated pageIndex.

My current (failing) code looks like:

  def getAndPaginate(jsonBody: String) = {
    val pageSize = 50;
    var totalCount: Int = 0
    var currentPage: Int = 1
    var totalPages: Int =0
    exec(session => session.set("pageIndex", currentPage))
    exec(http("Get page")
      .post("/api")
      .body(ElFileBody("json/" + jsonBody)).asJson
          .check(jsonPath("$.result.objects[?(@.type == 'type')].id").findAll.saveAs("list")))
      .check(jsonPath("$.result.totalCount").saveAs("totalCount"))
      .exec(session => {
        totalCount = session("totalCount").as[Int]
        totalPages =  Math.ceil(totalCount/pageSize).toInt
        session})
      .asLongAs(currentPage <= totalPages)
      {
        exec(http("Get assets action list")
          .post("/api")
          .body(ElFileBody("json/" + jsonBody)).asJson
          .check(jsonPath("$.result.objects[?(@.type == 'type')].id").findAll.saveAs("list")))
        currentPage = currentPage+1
        exec(session => session.set("pageIndex", currentPage))
        pause(Config.minDelayValue seconds, Config.maxDelayValue seconds)

      }
  }

Currently the pagination values are not assign to the variables that I have created at the beginning of the function, if I create the variables at the Object level then they are assigned but in a manner which I dont understand. For example the result of Math.ceil(totalCount/pageSize).toInt is 4 while it should be 5. (It is 5 if I execute it in the immediate window.... I dont get it ). I would than expect asLongAs(currentPage <= totalPages) to repeat 5 times but it only repeats twice.

I tried to create the function in a class rather than an Object because as far as I understand there is only one Object. (To prevent multiple users accessing the same variable I also ran only one user with the same result) I am obviously missing something basic here (new to Gatling and Scala) so any help would be highly appreciated :)

Upvotes: 1

Views: 775

Answers (1)

James Warr
James Warr

Reputation: 2604

using regular scala variables to hold the values isn't going to work - the gatling DSL defines builders that are only executed once at startup, so lines like

.asLongAs(currentPage <= totalPages)

will only ever execute with the initial values.

So you just need to handle everything using session variables

def getAndPaginate(jsonBody: String) = {
  val pageSize = 50;

  exec(session => session.set("notDone", true))
  .asLongAs("${notDone}", "index") {
    exec(http("Get assets action list")
      .post("/api")
      .body(ElFileBody("json/" + jsonBody)).asJson
      .check(
        jsonPath("$.result.totalCount")
          //transform lets us take the result of a check (and an optional session) and modify it before storing - so we can use it to get store a boolean that reflects whether we're on the last page
          .transform( (totalCount, session) => ((session("index").as[Int] + 1) * pageSize) < totalCount.toInt)
          .saveAs("notDone")
      )
    )
    .pause(Config.minDelayValue seconds, Config.maxDelayValue seconds)
  }
}   

Upvotes: 3

Related Questions