Hi,
I am trying my hand with Gatling and getting “String index out of range: -1” on the last request (highlighted in Blue below). The request body for this request has to be formatted dynamically based on the response from the previous request (number of fields varies every time). So, I am using .formParamMap(paramMap) and paramMap is built before the request that is failing is sent (in bold below). Am I missing something here?
Gatling Scala script:
class PlanitChallengeSimulation extends Simulation {
val httpProtocol = http
.baseUrl(“http://test.url.com”)
.inferHtmlResources()
.userAgentHeader(“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36”)
val headers_0 = Map(
“Accept” → “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”,
“Accept-Encoding” → “gzip, deflate”,
“Accept-Language” → “en-US,en;q=0.9”,
“Proxy-Connection” → “keep-alive”,
“Upgrade-Insecure-Requests” → “1”)
val headers_1 = Map(
“Accept” → “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”,
“Accept-Encoding” → “gzip, deflate”,
“Accept-Language” → “en-US,en;q=0.9”,
“Origin” → “http://challenge.planittesting.com”,
“Proxy-Connection” → “keep-alive”,
“Upgrade-Insecure-Requests” → “1”)
val headers_4 = Map(
“Accept” → “application/json, text/javascript, /; q=0.01”,
“Accept-Encoding” → “gzip, deflate”,
“Accept-Language” → “en-US,en;q=0.9”,
“Proxy-Connection” → “keep-alive”,
“X-Requested-With” → “XMLHttpRequest”)
val headers_7 = Map(
“Client-Request-Id” → “{B8BF2DB6-E7C9-4D5E-A3B9-BEB14F5FD0A9}”,
“Content-Type” → “text/xml”,
“Pragma” → “no-cache”,
“Proxy-Connection” → “Keep-Alive”,
“User-Agent” → “Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.11929; Pro)”)
val uri2 = “http://autodiscover.planittesting.com/autodiscover/autodiscover.xml”
var paramMap = Map.empty[String,String] // Define param map
val scn = scenario(“PlanitChallengeSimulation”)
.exec(http(“request_0”)
.get("/")
.headers(headers_0)
.check(regex(“VIEWSTATE” value="(.?)"").find.saveAs(“cVIEWSTATE”)))
.pause(3)
.exec(http(“request_1”)
.post("/challenge1.php")
.headers(headers_1)
.formParam("__EVENTTARGET", “”)
.formParam("__EVENTARGUMENT", “”)
.formParam("__VIEWSTATE", “${cVIEWSTATE}”)
.check(regex(“name=”(.?)">[\n\r\t ].glyphicon-ok").find.saveAs(“cCHLG1”))
.check(regex(“name=”(.?)">[\n\r\t ].glyphicon-remove").findAll.saveAs(“cCHLG1S”))
.check(regex("tick at the end: [\n\r\t ](.)[\n\r\t ]").find.saveAs(“cVALUE1”))
.check(regex(“Challenge”)))
.pause(3)
.exec(http(“request_2”)
.post("/challenge2.php")
.headers(headers_1)
.formParam(“EPwcsaQq2e”, “”)
.formParam(“qKg0uqsl63”, “”)
.formParam("${cCHLG1}", “${cVALUE1}”)
.formParam(“53rRq7OF0d”, “”)
.check(regex(“input.name="(.?)”").findAll.saveAs(“cCHLG2S”))
.check(regex("class=“glyphicon (.?)"").findAll.saveAs(“cGLYPHS”))
.check(regex("tick at the end:[\n\r\t ](.*)”).find.saveAs(“cVALUE2”))
.check(regex(“Challenge”)))
.exec(session => {
val chlg2s = session(“cCHLG2S”).as[List[String]]
val glyphs = session(“cGLYPHS”).as[List[String]]
var chlg2: String = “NOT FOUND”
glyphs.indices.foreach { i =>
if (glyphs(i) == “glyphicon-ok”) {
chlg2 = chlg2s(i).toString
}
}
session.set(“cCHLG2”, chlg2)
})
//.exec { session => println(session(“cCHLG2”).as[String]); session}
.pause(3)
.exec(http(“request_3”)
.post("/challenge3.php")
.headers(headers_1)
.formParam(“MP4pIbAtZm”, “”)
.formParam(“qBx2IxEwQk”, “”)
.formParam("${cCHLG2}", “${cVALUE2}”)
.formParam(“VOV5EhHJpK”, “”)
.formParam(“FV6lAdeYK2”, “”)
.formParam(“eawSZdQg5J”, “”)
.formParam(“MTVUO3PukB”, “”)
.formParam(“526EcNJR5X”, “”)
.formParam(“2Ymp9rAV2Q”, “”)
.formParam(“Zxi42xGv12”, “”)
.formParam(“aQ9UrWOVKw”, “”)
.formParam(“uBcpwGR2BZ”, “”)
.check(regex(“Challenge”)))
.pause(3)
.exec(http(“request_4”)
.get("/assets/js/challenge3.js.php")
.headers(headers_4)
.check(regex("&requestid=(.?)&").find.saveAs(“cREQID1”)))
.pause(3)
.exec(http(“request_4a”)
.get("/challenge3_driver.php?type=session&requestid=${cREQID1}&ts=")
.headers(headers_4)
.check(regex("“pSession”:"(.?)",").find.saveAs(“cPSESSION”))
.check(regex("“requestid”:"(.*?)",").find.saveAs(“cREQID2”)))
//.check(bodyString.saveAs(“responseBody”)))
.pause(3)
.exec(http(“request_5”)
.get("/challenge3_driver.php?type=input&session=${cPSESSION}&requestid=${cREQID2}&ts=")
.headers(headers_4)
.check(regex("“value”:"(.?)",").find.saveAs(“cVALUE3”))
.check(regex("“input”:"(.?)",").find.saveAs(“cCHLG3”)))
//.exec { session => println(session(“cCHLG3”).as[String]); session}
//.exec { session => println(session(“cVALUE3”).as[String]); session}
.pause(3)
.exec(http(“request_6”)
.post("/challenge4.php")
.headers(headers_1)
.formParam("${cCHLG3}", “${cVALUE3}”)
//.check(bodyString.saveAs(“responseBody”))
.check(regex(“input.name="(.?)”").findAll.saveAs(“cCHLG4S”))
.check(regex(“div id=“numbers”.[\r\n\t ](.?)[\r\n\t ]<”).find.transform(.split(" ").toList.map(.toInt).sortWith(<)).saveAs(“cNUMS”))
.check(regex(“Challenge 4”)))
.exec { session => println(session(“cCHLG4S”).as[String]); session}
.exec { session => println(session(“cNUMS”).as[String]); session}
//.exec { session => println(session(“responseBody”).as[String]); session}
.exec(session => {
val chlg4s = session(“cCHLG4S”).as[List[String]]
val iNumList = session(“cNUMS”).as[List[Int]]
session.set(“cNUMLIST”, iNumList) // Save int numList to session
for (i ← 0 until iNumList.length) {
println(s"$i is ${chlg4s(i)} ${iNumList(i)}")
paramMap += (chlg4s(i) → iNumList(i).toString) // Add field name and value to params map
}
session
})
//.exec { session => println(session); session}
.pause(3)
.exec(session => {
println(s"paramMap = $paramMap.as[Map[String,String]]}")
println(s"headers_1 = $headers_1.as[Map[String,String]]}")
session
})
.exec(http(“request_7”)
.post("/challenge5.php")
.headers(headers_1)
.formParamMap(paramMap)
.check(bodyString.saveAs(“responseBody”)))
.exec { session => println(session(“responseBody”).as[String]); session}
.exec { session => println(session); session}
setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}
Stack trace:
14:41:27.542 [INFO ] i.g.h.e.GatlingHttpListener - Request ‘request_7’ failed for user 1
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.AbstractStringBuilder.setLength(Unknown Source)
at java.lang.StringBuilder.setLength(Unknown Source)
at io.gatling.http.client.body.form.FormUrlEncodedRequestBody.encode(FormUrlEncodedRequestBody.java:57)
at io.gatling.http.client.body.form.FormUrlEncodedRequestBody.build(FormUrlEncodedRequestBody.java:45)
at io.gatling.http.client.impl.request.WritableRequestBuilder.buildRequestWithBody(WritableRequestBuilder.java:68)
at io.gatling.http.client.impl.request.WritableRequestBuilder.buildRequest(WritableRequestBuilder.java:118)
at io.gatling.http.client.impl.HttpAppHandler.write(HttpAppHandler.java:105)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:716)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:708)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:791)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:701)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:696)
at io.netty.channel.DefaultChannelPipeline.write(DefaultChannelPipeline.java:1022)
at io.netty.channel.AbstractChannel.write(AbstractChannel.java:283)
at io.gatling.http.client.impl.DefaultHttpClient.sendTxWithChannel(DefaultHttpClient.java:438)
at io.gatling.http.client.impl.DefaultHttpClient.sendTx(DefaultHttpClient.java:356)
at io.gatling.http.client.impl.DefaultHttpClient.lambda$sendRequest$0(DefaultHttpClient.java:265)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:510)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:518)
at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Unknown Source)
14:41:27.545 [INFO ] i.g.h.e.r.DefaultStatsProcessor - Request ‘request_7’ failed for user 1: j.l.StringIndexOutOfBoundsException: String index out of range: -1
14:41:27.546 [TRACE] i.g.h.e.r.DefaultStatsProcessor -