Gatling reads the scenario at the start of the simulation and then executes it several times with the same configuration/values.
How is it possible, for example, to execute each request with the following value "RANDOM-VALUE", always with a new random value?
val postRandomValue = scenario("Post Random Value")
.exec(
http("POST ShipmentList")
.post("http://localhost:8080/endpoint") // Local
.headers(Headers.header)
.body(StringBody("myRandomValue: RANDOM-VALUE")))
Feeders will help here
val postRandomValue = scenario("Post Random Value")
.feed(Iterator.continually(Map(
"RANDOM_VALUE" -> java.util.UUID.randomUUID.toString
)))
.exec(
http("POST ShipmentList")
.post("http://localhost:8080/endpoint") // Local
.headers(Headers.header)
.body(StringBody("myRandomValue: ${RANDOM_VALUE}")))
Related
In Gatling, I am using feeders to pass the values of the coordinates in a request, below is the code. I want on each repeat a new value from the feeder to be picked up. I am get the following error --
/mapping/v2/: Failed to build request: No attribute named 'map 30 (100.0%) x' is defined
Could someone please advice how this can be achieved. thanks.
val mapfeeder = csv(fileName = "data/cordinates.csv").circular
object PDP {
val pdp = group("ABC_01_DetailsPage") {
exec(http("PropertyDetailsPage")
.get("/abc/property/detail.html?propertyId=12345&index=0&q=${address_json6}&qt=address&_qt=address&offset=1&sort=address&limit=20&view=property&mode=&radius=1.0Km&landuse=All")
.check(substring("Change in Median Price")))
}
.pause(duration = 1)
.feed(mapfeeder) //this works but only take the fist value and repeats it 30 times
.group("ABC_02_DetailsPage_MAP") {
repeat(30) {
feed(mapfeeder) // this one fails with the error mentioned in the post
exec(http("/mapping")
.get(uri22 + "?mapTypeId=1006&x=${mapx}&y=${mapy}&z=19&access_token=${maptoken}"))
}
val scn = scenario("RecordedSimulation")
.feed(SearchFeeder)
.exec(Homepage.homepage, Login.login, SearchLink.search, SearchEntry.searchentry, PDP.pdp, Logout.logout)
setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
You're missing a dot to attach your feed and the following exec, so only the result of the last instruction (the exec) is passed to the repeat method.
It should be:
repeat(30) {
feed(mapfeeder)
.exec(
http("/mapping") // <== HERE, DOT WAS MISSING
.get(uri22 + "?mapTypeId=1006&x=${mapx}&y=${mapy}&z=19&access_token=${maptoken}")
)
}
I am using Gatling to test a system which expects 2 sequential Post requests say, R1 and R2. These Post requests have different Json request bodies but one common key "ID". So one user should execute R1-R2 in order and a new random ID should be generated per user. This ID generated in R1 should be passed to R2 and hence added as the value of the ID key in its request bodies.
The random ID is generated inside a feeder at the R1 request:
val R1Id = Iterator.continually(Map("randId1" -> R1_requestBody.replace("0000000000", randomTokenGenerator.generateTokenID())))
val r1 =
scenario("R1Scenarios").feed(R1Id)
.exec(http("POST R1")
.....
.body(StringBody(session => """${randId1}""")).asJSON
Now, in R2, I want to feed want had been ID value had been generated inside the feeder of R1.
val R2Id = Iterator.continually(Map("randId2" -> R2_requestBody.replace("0000000000", ***Token generated in the first request***)))
val R2= {
scenario("R2 Scenarios")
.exec(R1.r1)
//calls the first scenario as R2 should be executed after R1
.feed(R2Id )
.exec(http("POST R2")
....
.body(StringBody(session => """${randId2}""")).asJSON
Finally executing the simulation:
val jsonScenario = R2.r2.inject(constantUsersPerSec(2) during (1 second))
setUp(jsonScenario)
.protocols(httpConf)
Instead of generating whole body in feeder you can generate only that random id, lets call it userToken:
val tokenFeeder = Iterator.continually(Map(
"userToken" -> randomTokenGenerator.generateTokenID()
))
and replace it while building request body:
.body(
StringBody(session => R1_requestBody.replace(
"0000000000",
session("userToken").as[String]
))
).asJSON
Or even cleaner and better - use fact that Gatling replaces every string containing placeholder like ${sessionAttributeName} with that session attribute string value and instead of using "0000000000" in your body template use ${userToken} placeholder fe:
val bodyTemplate ="""{
|"userName": "John Doe",
|"userToken": "${userToken}"
|}""".stripMargin
and then just use that template for body and Gatling expression language will do the magic:
.body(StringBody(bodyTemplate)).asJSON
I'm trying to get gatling to create random data per POST request. I've followed a few posts on stackoverflow and other places. I came up with this scenario -
def randomUuid = UUID.randomUUID().toString
val feeder = Iterator.continually(Map("user" -> randomUuid))
def createPostRequest = {
http("createuser")
.post("http://jsonplaceholder.typicode.com/posts")
.body(StringBody("${user}"))
.check(status.is(201))
}
val scn = scenario("some load test")
.feed(feeder)
.forever(exec(createPostRequest))
setUp(scn.inject(atOnceUsers(1)))
.maxDuration(20 minutes)
However, when I run this code it just calls my feeder once to create a single UUID and just re-uses the same UUID throughout the load test.
I created the code above after following this thread. I'm using gatling 2.2.5. Here's my sbt config -
import sbt._
object Dependencies {
private val gatlingHighcharts = "io.gatling.highcharts" % "gatling-
charts-highcharts" % "2.2.5" % "test"
private val gatlingTest = "io.gatling" % "gatling-test-framework" % gatlingHighcharts.revision % "test"
val gatlingDependencies = Seq(gatlingHighcharts, gatlingTest)
}
As you don't call feed inside a loop, typically your forever one, you will indeed only generate one single value per virtual user.
If what you want is to have unique values per loop iteration, move the feed call inside the loop.
in your setUp, you're only creating one user - so your scenario is only getting executed once, meaning that 'feed' only occurs once before you start looping over your request.
change your scenario to be
val scn = scenario("some load test")
.feed(feeder)
.exec(createPostRequest)
and make your setUp (replacing 100 with whatever number of users you want)
setUp(scn.inject(atOnceUsers(100)))
I'm current creating some Gatling simulation to test a REST API. I don't really understand Scala.
I've created a scenario with several exec and pause;
object MyScenario {
val ccData = ssv("cardcode_fr.csv").random
val nameData = ssv("name.csv").random
val mobileData = ssv("mobile.csv").random
val emailData = ssv("email.csv").random
val itemData = ssv("item_fr.csv").random
val scn = scenario("My use case")
.feed(ccData)
.feed(nameData)
.feed(mobileData)
.feed(emailData)
.feed(itemData)
.exec(
http("GetCustomer")
.get("/rest/customers/${CardCode}")
.headers(Headers.headers)
.check(
status.is(200)
)
)
.pause(3, 5)
.exec(
http("GetOffers")
.get("/rest/offers")
.queryParam("customercode", "${CardCode}")
.headers(Headers.headers)
.check(
status.is(200)
)
)
}
And I've a simple Simulation :
class MySimulation extends Simulation {
setUp(MyScenario.scn
.inject(
constantUsersPerSec (1 ) during (1)))
.protocols(EsbHttpProtocol.httpProtocol)
.assertions(
global.successfulRequests.percent.is(100))
}
The application I'm trying to simulate is a multilocation mobile App, so I've prepared a set of samples data for each Locale (US, FR, IT...)
My REST API handles all the locales, therefore I want to make the simulation concurrently execute several instances of MyScenario, each with a different locale sample, to simulate the global load.
Is it possible to execute my simulation without having to create/duplicate the scenario and change the val ccData = ssv("cardcode_fr.csv").random for each one?
Also, each locale has its own load, how can I create a simulation that takes a single scenario and executes it several times concurrently with a different load and feeders?
Thanks in advance.
From what you've said, I think this may be a good approach:
Start by grouping your data in such a way that you can look up each item you want to send based on the current locale. For this, I would recommend using a Map that matches a locale string (such as "FR") to the item that matches that locale for the field you're looking to fill in. Then, at the start of each iteration of the scenario, you just pick which locale you want to use for the current iteration from a list. It would look something like this:
val locales = List("US", "FR", "IT")
val names = Map( "US" -> "John", "FR" -> "Pierre", "IT" -> "Guillame")
object MyScenario {
//These two lines pick a random locale from your list
val random_index = rand.nextInt(locales.length);
val currentLocale = locales(random_index);
//This line gets the name
val name = names(currentLocale)
//Do the rest of your logic here
}
This is a very simplified example - you'll have to figure out how you actually want to retrieve the data from files and put it into a Map structure, as I assume you don't want to hard code every item for every field into your code.
I would like to save a session attribute in a list in my gatling simulation. What am trying to do is to get all the values of my JSON who are defined in a CV file and write it in a file. In my example below "test" is always equal to the value of the first jsonPath.
Here what I am doing:
val scn1 = scenario("[SCENARIO] GET")
.repeat(Nbproduct-1, "counter") (
feed(csv(CSV).circular)
.exec(http("get JSON")
.get(url_1")
.check(jsonPath("""$.${meta_ref}""").find.saveAs("test")))
.pause(1)
.exec(session => {
writer.write("\""+session("meta_cts").as[String]+"\":\"" + session("test").as[String]+"\",\n")
session
}
)
I also tried this but it get the value of the counter...
.check(jsonPath("""$.${meta_ref}""").find.saveAs("""jdd_value("${counter}")""")))
Thanks for the help!
Feeders are shared datasources, so first user will pop the first record, second user the second record, etc...
Then, it's not possible to define checks at runtime (depending on some entries in a file). All DSL components are builders that are only resolved once when the Simulation is loaded.