[Help] How to poll a webservice and wait for a specific "event"

Hi,

i am evaluating gatling for our load tests and until now like it very much. thanks for the nice dsl.
but it’s a bit hard from time to time to understand whats going on under the hood especially when you
dont know scala.

but hey - i like to learn new things (:

right now i am stuck at trying to repeatedly ask a webservice and react on a specific response. in pseudo code
i want to achieve this :

waiting = true
result = “”
while (waiting)
get /service/whatever
check json result for /some/property
if found
result = /some/property
waiting = false

i tried many different things but found nothing that worked for me.

hope someone can give me a hand here.

cheers
Chris

Hi,

Here’s what to do, with Gatling 1 syntax.
https://github.com/excilys/gatling/wiki/Session#wiki-functions

https://github.com/excilys/gatling/wiki/Session#wiki-members

asLongAs(session => session.isAttributeDefined(“result”)) {
exec(http(call you webservice).check(regex or jsonPath saveAs(“result”))
.pause(probably have a pause here so that you don’t hammer your webservice, up to you)
}

Cheers,

Stéphane

Hi,

okay makes sense. i tried it but getting a NPE. here’s my code

.asLongAs(session => !session.isAttributeDefined(“passId”)) {
exec(
http(“wait for pass”)
.get("/passes/list/all/0/0")
.check(jsonPath("$.data.passes[0].id").findAll.saveAs(“passId”)))
.pause(500 milliseconds)
}

and the NPE

ERROR] [06/13/2013 23:20:27.74] [GatlingSystem-akka.actor.default-dispatcher-14] [akka://GatlingSystem/user/$d/$a] null
java.lang.NullPointerException
at com.jayway.jsonpath.internal.filter.ArrayIndexFilter.filter(ArrayIndexFilter.java:64)
at com.jayway.jsonpath.internal.filter.PathTokenFilter.filter(PathTokenFilter.java:50)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:191)
at com.excilys.ebi.gatling.core.check.extractor.jsonpath.JsonPathExtractor.extractMultiple(JsonPathExtractor.scala:65)
at com.excilys.ebi.gatling.http.check.body.HttpBodyJsonPathCheckBuilder$$anonfun$1$$anonfun$apply$2.apply(HttpBodyJsonPathCheckBuilder.scala:39)
at com.excilys.ebi.gatling.http.check.body.HttpBodyJsonPathCheckBuilder$$anonfun$1$$anonfun$apply$2.apply(HttpBodyJsonPathCheckBuilder.scala:39)
at com.excilys.ebi.gatling.core.check.MatcherCheckBuilder$$anon$2.apply(CheckBuilder.scala:109)
at com.excilys.ebi.gatling.core.check.MatcherCheckBuilder$$anon$2.apply(CheckBuilder.scala:105)
at com.excilys.ebi.gatling.core.check.Check.apply(Check.scala:65)
at com.excilys.ebi.gatling.core.check.Check$.applyChecksRec$1(Check.scala:41)
at com.excilys.ebi.gatling.core.check.Check$$anonfun$applyChecks$1.apply(Check.scala:50)
at com.excilys.ebi.gatling.core.check.Check$$anonfun$applyChecks$1.apply(Check.scala:50)
at com.excilys.ebi.gatling.core.check.CheckContext$.useCheckContext(CheckContext.scala:41)
at com.excilys.ebi.gatling.core.check.Check$.applyChecks(Check.scala:49)
at com.excilys.ebi.gatling.http.ahc.GatlingAsyncHandlerActor.checkPhasesRec$1(GatlingAsyncHandlerActor.scala:229)
at com.excilys.ebi.gatling.http.ahc.GatlingAsyncHandlerActor.com$excilys$ebi$gatling$http$ahc$GatlingAsyncHandlerActor$$processResponse(GatlingAsyncHandlerActor.scala:241)
at com.excilys.ebi.gatling.http.ahc.GatlingAsyncHandlerActor$$anonfun$receive$1.apply(GatlingAsyncHandlerActor.scala:108)
at com.excilys.ebi.gatling.http.ahc.GatlingAsyncHandlerActor$$anonfun$receive$1.apply(GatlingAsyncHandlerActor.scala:84)
at akka.actor.Actor$class.apply(Actor.scala:318)
at com.excilys.ebi.gatling.http.ahc.GatlingAsyncHandlerActor.apply(GatlingAsyncHandlerActor.scala:70)
at akka.actor.ActorCell.invoke(ActorCell.scala:626)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197)
at akka.dispatch.Mailbox.run(Mailbox.scala:179)
at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:516)
at akka.jsr166y.ForkJoinTask.doExec(ForkJoinTask.java:259)
at akka.jsr166y.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
at akka.jsr166y.ForkJoinPool.runWorker(ForkJoinPool.java:1479)
at akka.jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

the json returned from the service may have data.passes be null. can this be the source of the NPE?

thx in advance
Chris

the json returned from the service may have data.passes be null. can this
be the source of the NPE?

Looks like a Jayway's JsonPath bug to me. I would expect a null result or
an empty list, not a NPE.
We can maybe catch the NPE, but still, it would be more efficient to have
this fixed upstream.

Until then, you can try adding a first JsonPath check that would check if
the array exists.

What does you null array JSON look like, please?

Something like

{
“success”: true,
“data”: {
“user”: 3,
“own”: null,
“passes”: null,
“completed”: null
},
“version”: 1371160528774
}

You are right - if i guard the array access with a check for $.data.passes the NPE is not occuring.
Works for me but seems like this should be handled by the framework.

cheers
Chris

I absolutely agree, just that I’d like this to get fixed in the right place in the third party library, instead of downstream in Gatling: cleaner, and more efficient as you don’t get a useless Exception creation and its underlying stack copy.

I submitted a fix on the third party library: https://github.com/jayway/JsonPath/pull/24

If the PR doesn’t get merged or the release is not done quickly enough, we’ll ship a timestamped version in Gatling 1.5.2.

Sounds good.

My Scenario is running nicely but i have one minor issues with the generated report.
All request to the webservice that don’t match are reported as not ok. is there a option
to have a check not report it’s state to the report?

my current code is :

.asLongAs(session => !session.isAttributeDefined(“passId”)) {
exec(
http(“wait for pass”)
.get("/passes/list/all/0/0")
.check(jsonPath("$.data.passes"))
.check(jsonPath("$.data.passes[0].id").find.saveAs(“passId”)))
.pause(500 milliseconds)
}
.exec(
http(“pass back”)
.get("/passes/pass/back/${passId}")
.check(status.is(200)))

cheers
Chris

No.
You’ll really need the fixed JsonPath.
Note that you’ll then have to change your check.
What you currently have is jsonPath("$.data.passes[0].id").saveAs(“passId”) (no need for find, which is the default), which default to exists
What you actually need once the issue is fixed is jsonPath("$.data.passes[0].id").whatever.saveAs(“passId”) so it doesn’t fail when it doesn’t find the value and only save if it did find it.

We’ll probably release 1.5.2 on monday.

I finally decided to publish a fork in our nexus: https://github.com/excilys/gatling/issues/1223
If you’re in a hurry, you can force jsonpath’s version to 1.8.2.fix24 (for example with a dependencyManagement bloc), the fix was purely in the third party lib, not in Gatling.

Cheers,

Stéphane