EL JSON bodies sequentially from file, one session variable needs to be calculated on the fly, howto?

Hi,

I have been experimenting with Gatling for the past two weeks and I am really impressed with it’s capabilities. The main bulk of my scenario’s involves sending a sequential set of JSON bodies, at a steady rate and interval.
The bodies themselves need to be captured from real world tests, as there are too many variants.

These bodies contain a userid, sessionid and an overload of timestamps. A scenario will exists out of multiple of these bodies, sequentially sent, with 10 to 20 seconds between each one.
For each userid/sessionid combination ALL the JSON bodies need to be sent. The timestamps are important, so they need to be in line with the scenario starttime.

The approach I used was:

  • parse the logfiles obtained from world traces, and only retain the JSON bodies in minified form, each body is exactly one line
  • replace the userid and session by placeholders of the form and
  • replace the timestamp by placeholders of the form <TREF+offset> where TREF is the lowest timestamp in milliseconds in all JSON bodies.
  • → this is then stored in a scenario file (JSON bodies, each new line being a new message to be sent, with placeholders)
  • Load the file into each session and replace the parameters per session

I was however wondering if it would be possible to load these files through a feeder of some sort, have them executed within the same session for a userid and to use session variables in the template.
Including the “calculated” session variables for all those timestamps. <TREF+10> needs to calculated to System.currentTimeMillis+10. There are roughly 20 timestamps per JSON body.
One of the longer scenario’s has 19 JSON bodies to be sent.

The code how I achieved this is given below. Keep in mind, I have no Scala knowledge, so I had to go blind and chose whatever worked, even if I knew it would not be ideal.

class Test extends Simulation {
object Test {
val test = exec(session => {
var tRef: Long = System.currentTimeMillis
var sid: String = java.util.UUID.randomUUID.toString
var uid: String = session.userId

val source = scala.io.Source.fromFile(“test.scn”)
val msgs = ArrayBufferString
for (json ← source.getLines) ( msgs += “”"<TREF+(\d+)>""".r.replaceAllIn(json.replaceAll("",sid).replaceAll("",uid),m => (m.group(1).toLong+tRef).toString))
source.close()

session.set(“sid”,sid)
.set(“uid”,uid)
.set(“msgs”, msgs)
.set(“seq”,1)

})
.foreach("${msgs}",“msg”) {
exec(http(“Test - ${uid} - ${sid}”)
.post("/report/${uid}/${sid}/${seq}")
.queryParam(“ReportType”,“Generic”)
.body(StringBody("${msg}")).asJSON.check(status.is(200)))
.exec(session => {
var sequence=session(“seq”).as[Int]+1
session.set(“seq”,sequence)})
.pause(10)
}

}

val sentHeaders = Map(“Cache-Control” → “no-cache”, “Pragma” → “no-cache”, “User-Agent” → “Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0”, “DNT” → “1”, “Accept-Language” → “en-US,en;q=0.5”, “Accept-Encoding” → “gzip, deflate”)
val httpConf = http
.baseURL(“http://localhost:8080/api”)
.header(HttpHeaderNames.ContentType, HttpHeaderValues.ApplicationJson)
.header(HttpHeaderNames.Accept, HttpHeaderValues.ApplicationJson)
.headers(sentHeaders)

val scn = scenario(“Test”).repeat(3,“scnCtr”){exec(Test.test)}

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

Hi,

Stéphane,

Thanks for the elaborate reply. I was already trying to use EL syntax, but somehow it was not detecting the placeholders. I had a similar issue today when trying to make the pause time configurable.I had created a session variable on scenario definition, and then trying to use it with “${delay}” or “”"${delay}""", but to no avail. Is there some guide on where you can use EL syntax, and where it won’t work?

I am also assuming that using ELFileBody would remove the need for using the non-shared data approach? Is it then still possible to send the JSON bodies from the ELFileBody one at a time in a loop?
Seems I need to learn a lot on the go, and it doesn’t help that my brain is cluttered with Perl, Python, Ruby, … :slight_smile:

Anyway, I will start experimenting again middle of next week with the pointers you have given me.

Leaves me to give you a big thanks for the effort to answer so many questions on this group, and for making such a powerfull tool! The potentiel is near endless and it features more than enough to do complex realistic load simulation on solutions.
I cannot even imagine where you would still take it from here, although I would really be looking forward to a distributed/clustered solution. (i.e. through registration on a JMS bus or MQTT broker or something)

Kind regards, David

P.S.: if you would happen to be on Devoxx Antwerp next week, please drop me a message

Thanks for the elaborate reply. I was already trying to use EL syntax, but
somehow it was not detecting the placeholders. I had a similar issue today
when trying to make the pause time configurable.
I had created a session variable on scenario definition, and then trying
to use it with "${delay}" or """${delay}""", but to no avail. Is there some
guide on where you can use EL syntax, and where it won't work?

See warning here: http://gatling.io/docs/2.0.2/session/expression_el.html

I am also assuming that using ELFileBody would remove the need for using
the non-shared data approach? Is it then still possible to send the JSON
bodies from the ELFileBody one at a time in a loop?

ELFileBody is just a way to have EL based templates. It has nothing to do
with with way data was originally injected in the sessions.

Seems I need to learn a lot on the go, and it doesn't help that my brain
is cluttered with Perl, Python, Ruby, ... :slight_smile:

Things usually start to makes sense once you really what functions are: a
piece of code that you can pass around so it can be executed elsewhere.
Basic strategy pattern.

Anyway, I will start experimenting again middle of next week with the
pointers you have given me.

Leaves me to give you a big thanks for the effort to answer so many
questions on this group, and for making such a powerfull tool! The
potentiel is near endless and it features more than enough to do complex
realistic load simulation on solutions.

Thanks for your kind words :slight_smile:

I cannot even imagine where you would still take it from here, although I
would really be looking forward to a distributed/clustered solution. (i.e.
through registration on a JMS bus or MQTT broker or something)

I have some ideas, but nothing planned atm.

Kind regards, David

P.S.: if you would happen to be on Devoxx Antwerp next week, please drop
me a message

Sadly no. But if you happen to be on Paris some day, feel free to drop me
one :slight_smile: