Search code examples
web-servicessoappollinggatling

Gatling: polling a webservice, and failing the scenario on incorrect response-messages


Hard to write a good title for this question. I am developing a performance test in Gatling for a SOAP Webservice. I'm not very experienced with Gatling so I'm learning things as I go, but this conundrum has me entirely stumped.

One of the scenarios I am implementing a test for is an order-process consisting of several unique consecutive calls to the webservice, one of which is a polling call that returns the current status of the ordering process. Simplified, this call gets a SOAP Response with a status that can be of three types:

  • PROCESSING - Signifying the order is still processing.
  • ORDER_OK - Order completed without errors.
  • EVERYTHING_ELSE - A group of varying error-statuses and other results.

What I want to do, is have Gatling continuously poll the webservice until the processing-status changes - and then check that the status says it completed successfully. Polling continuously is easily implemented, but performing the check after it completes is turning out to be a far greater challenge than it has any business being.

So far, this is what I've done to solve the polling:

exec { session => session.set("status", "PROCESSING") }
.asLongAs(session => session("status").as[String].equals("PROCESSING")) {
  exec(http("Poll order")
    .post("/MyWebService")
    .body(ELFileBody("bodies/ws/pollOrder.xml"))
    .check(
      status.is(200),
      regex("soapFault").notExists,
      regex("pollResponse").exists,
      xpath("//*[local-name(.)='result']").exists.saveAs("status")
    )
  ).exitHereIfFailed.pause(5 seconds)
}

This snip appears to be performing the polling correctly, it continues to poll until the orderStatus changes from processing to something else. I need to check the status to see if it changed to the response I am interested in however, because I don't know what it is, and only one of the many results it can be should cause the scenario to continue for that user.

A potential fix would be to add more checks in that call that go something like this:

.check(regex("EVERYTHING_ELSE_XYZ")).notExists

The service can return a LOT of different "not a happy day" messages however and I'm only really interested in the two other ones, so it would be preferable for me to be able to do a check only for the two valid happy-day responses. Checking if one exact thing exists seems far more sensible than checking that dozens of things don't.

What I thought I would be able to do was performing a check on the status variable in the users session when the step exits the asLongAs-loop, and continue/exit the scenario for that user. As it's a session-variable I could probably do this in the next step of the total scenario and break the run for that user there, but that would also mean the error is reported in the wrong place, and the next calls fault-% would be polluted by errors from the previous call.

Using pseudocode, being able to do something like this immediately after it exits the asLongAs loop would have been perfect:

if (session("status").as[String].equals("ORDER_OK")) ? continueTheScenario : failTheScenario

but I've not been able to do anything similar to that inside a gatling-chain. It's almost starting to appear impossible to do something like that, but can anyone see a solution to this that I'm not seeing?


Solution

  • Instead of "exists", use "in" to check that the result is one of the 2 valid values.