0
votes

I want to performance test a recommender system. It is important that the sequence of each product request for the same customer_id is respected as it influences the CPU load of the system under test.

How should I approach this? (This is what I have so far the exec does not work in the foreach)


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


class MySimulation extends Simulation {
  val baseUrl = "http://127.0.0.1:8080"  // http://127.0.0.1:8080/recommend/144/9200000033418652/
  val contentType = "application/json"
  var realtime_feeder = Array(
    Map("product_ids" -> List("9200000118431183", "9200000118431213", "9200000089631081"), "customer_id" -> "1"),
    Map("product_ids" -> List("9200000121305523"), "customer_id" -> "2"),
    Map("product_ids" -> List("9200000118431349", "9200000089631025"), "customer_id" -> "3"),
  )

  val httpConfiguration = http.baseUrl(baseUrl)
    .acceptHeader(contentType)
    .contentTypeHeader(contentType)
    .shareConnections
    .warmUp(baseUrl)

  val productRequest = http("Recommend ${customer_id} ${product_id}")
    .get("/recommend/${customer_id}/${product_id}")

  val scn = scenario("scenario")
    .feed(realtime_feeder)
    .foreach(session => {
      val product_ids = session("product_ids").as[List[String]]
      val customer_id = session("customer_id").as[String]
      for (product_id <- product_ids){
        exec(productRequest, customer_id, product_id)
      }
    },
    )

  setUp(
    scn.inject(
      atOnceUsers(2)
    ).protocols(httpConfiguration))

}
2

2 Answers

1
votes

Read the documentation first. You have serious misunderstanding of Gatling's programming model.

For knowing what to put into foreach, read Expression and EL.


foreach requires an Expression[Seq[Any]] and you can create one with the expression language (EL). by writing "${product_ids}". This will fetch the session attribute product_ids from the virtual users' session.

foreach("${product_ids}", "product_id") {
  // Write your actions that use `product_id`.
  // E.g. use EL to create a JSON
}

BTW, kudos to you for knowing how dynamic payloads are important to making a load test realistic.

1
votes

Thanks George Leung for his suggestions. Here is my working end result.

import io.gatling.core.Predef.{exec, _}
import io.gatling.http.Predef._

import scala.concurrent.duration._


class MySimilation extends Simulation {
  val baseUrl = "http://127.0.0.1:8080" // http://127.0.0.1:8080/recommend/144/9200000033418652/
  val contentType = "application/json"
  var realtime_feeder = Array(
    Map("product_ids" -> List("9200000118431183", "9200000118431213", "9200000089631081"), "customer_id" -> "1"),
    Map("product_ids" -> List("9200000121305523"), "customer_id" -> "2"),
    Map("product_ids" -> List("9200000118431349", "9200000089631025"), "customer_id" -> "3"),
  ).random

  val httpConfiguration = http.baseUrl(baseUrl)
    .acceptHeader(contentType)
    .contentTypeHeader(contentType)
    .shareConnections
    .warmUp(baseUrl)

  val productRequest = http("/recommend/${customer_id}/${product_id}/")
    .get("/recommend/${customer_id}/${product_id}/")

  val scn = scenario("scenario")
    .feed(realtime_feeder)
    .foreach("${product_ids}", "product_id") {
      exec(productRequest).pause(1 seconds, 2 seconds)
    }

  setUp(
    scn.inject(
      nothingFor(5.seconds),
      constantUsersPerSec(5) during (1 minutes)
    ).protocols(httpConfiguration))
}