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))
}