How to pass session values to a method feed() in gatling correctly

Viewed 1833

I have the following problem. When I try to execute the simulation, I get this error:

Generating reports...
Exception in thread "main" java.lang.UnsupportedOperationException: There were no requests sent during the simulation, reports won't be generated
    at io.gatling.charts.report.ReportsGenerator.generateFor(ReportsGenerator.scala:49)
    at io.gatling.app.RunResultProcessor.generateReports(RunResultProcessor.scala:62)
    at io.gatling.app.RunResultProcessor.processRunResult(RunResultProcessor.scala:40)
    at io.gatling.app.Gatling$.start(Gatling.scala:88)
    at io.gatling.app.Gatling$.fromMap(Gatling.scala:41)
    at Engine$.delayedEndpoint$Engine$1(Engine.scala:11)
    at Engine$delayedInit$body.apply(Engine.scala:4)
    at scala.Function0.apply$mcV$sp(Function0.scala:39)
    at scala.Function0.apply$mcV$sp$(Function0.scala:39)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
    at scala.App.$anonfun$main$1$adapted(App.scala:80)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.App.main(App.scala:80)
    at scala.App.main$(App.scala:78)
    at Engine$.main(Engine.scala:4)
    at Engine.main(Engine.scala)

Process finished with exit code 1

Below is my code:

package simulations

import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation
import io.gatling.http.Predef._

class Load extends Simulation{

  val httpProtocol = http
    .baseUrl("http://localhost:8080/app/")
    .header("Accept", "application/json")

  val scn = scenario("Scenario").exec(SimpleExample.simple)

    setUp(
      scn.inject(atOnceUsers(3)).protocols(httpProtocol)
    )
}


package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._    
import scala.util.Random

object SimpleExample {

  var simple =
    exec(session => session
      .set("rndmSTR", randomString())
      .set("rndmINT", randomInt())
    ).
      exec(
        session => {
          exec(feed(Iterator.continually(Map(
            "game_ID" -> session("rndmINT").as[String].toInt,
            "game_Name" -> session("rndmSTR").as[String]
          ))))
            .exec(
              http("Post New Game")
                .post("videogames/")
                .body(ElFileBody("bodies/newtemplate.json")).asJson
            )
          session
        }
      )

  private def randomString() = {
    new Random().alphanumeric.filter(_.isLetter).take(5).mkString.toLowerCase
  }    
  private def randomInt() = {
    new Random().nextInt(100000)
  }

}

This is my .json:

{
  "id": "${game_ID}",
  "name": "${game_Name}",
  "releaseDate": "2020-08-11",
  "reviewScore": 99,
  "category": "Driving",
  "rating": "Mature"
}

I know that i can use the feed() method as follows:

package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._    
import scala.util.Random    

object NextSimpleExample {

  var rndName: String = null
  var rndID: String = null    
  var feeder = Iterator.continually(Map(
    "game_ID" -> rndID.toInt,
    "game_Name" -> rndName
  ))    

  var simple =
    exec(session => session
      .set("rndmSTR", randomString())
      .set("rndmINT", randomInt())
    ).
      exec(
        session => {
          rndID = session("rndmINT").as[String]
          rndName = session("rndmSTR").as[String]
          session
        }
      )
      .exec(feed(feeder)
        .exec(
          http("Post New Game")
            .post("videogames/")
            .body(ElFileBody("bodies/newtemplate.json")).asJson)
      )

  private def randomString() = {
    new Random().alphanumeric.filter(_.isLetter).take(5).mkString.toLowerCase
  }    
  private def randomInt() = {
    new Random().nextInt(100000)
  }

}

but in this case, all virtual users will get similar values...

Also, i want to use generated for each virtual user values in next steps. For example, insert generated id & name in another .json file for another body in post or put request. Please, help to resolve this problem.

1 Answers

The gatling DSL defines builders that are created once, so any kind of reference code like

exec(session => session
  .set("rndmSTR", randomString())
  .set("rndmINT", randomInt())
)

will result in the same values for all users.

Your second example is really a convoluted way of restating the first by way of transferring to plain scala variables - you're still only ever running your 'random' functions once.

But you were close - if you move your random functions into the feeder definition, it will work because the functions will be evaluated each time .feed gets called.

var feeder = Iterator.continually(Map(
  "game_ID" -> randomString(),
  "game_Name" -> randomInt()
))    

So you don't need the session functions at all

Related