Gatling/Scala is unable to find JSON retrieved session key

I am very new to Gatling and being half made to use it I need to write automation scripts with it. I have no prior experience with it in any way.

When I am trying to run multiple scenarios I retrieve a “session_key” as part of a JSON response after a login. I tried to follow guides from the internet, saved this value but when I attempt to use it further in my second scenario the Expression Language can’t find it.

I have verified my JSONPath expression for it and it seems to be correct.

{"result":1,"resultType":"ack","output":{"session_key":"a value for the session key goes here"},"errorMessage":false,"errorCode":false,"additional":{"locationtabs":["tab 1","tab 2","tab 3"]}}

I have also listed my code below but replaced usage data with mock data for my question.

package basic

import com.excilys.ebi.gatling.core.Predef._
import com.excilys.ebi.gatling.http.Predef._
import com.excilys.ebi.gatling.jdbc.Predef._
import com.excilys.ebi.gatling.http.Headers.Names._
import com.jayway.jsonpath._
import akka.util.duration._
import bootstrap._

class GetLocations extends Simulation
{

    val httpConf = httpConfig
        .baseURL("https://myURL")
        .acceptCharsetHeader("ISO-8859-1,utf-8;q=0.7,*;q=0.7")
        .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
        .acceptEncodingHeader("gzip, deflate")
        .acceptLanguageHeader("fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3")
        .disableFollowRedirect

    val scn = scenario("Login Test")
        .exec(
            http("requestLogin")
            .post("/restapi/login")
            .param("username", "a username")
            .param("password", "a password")
            .param("client_uid", "testUid")
            .check(jsonPath("$.result").is("1"))
            .check(jsonPath("$.output.session_key").findAll.saveAs("session_key"))

        ).pause(15)

    val getLocations = scenario("Get Locations")
        .exec(
            http("getLocations")
            .post("/restapi/get_employee_favouritelocations")
            .param("client_uid","testUid")
            .param("clientType","automatedTest")
            .param("session_key","${session_key}")
            .check(jsonPath("$.result").is("1"))
        )

    setUp(scn.users(50).ramp(50).protocolConfig(httpConf),
          getLocations.users(50).ramp(50).protocolConfig(httpConf)
        )

}

Any help you can provide is appreciated as this has been giving me headaches for a week and unfortunately only i am available to work with this currently.

You don’t get it right!

Here, you have 2 different scenarios, each running 50 users: the first 50 ones save session_key into THEIR session and the 50 others try to find it in THEIR own, and of course it doesn’t exist.

I don’t understand what you’re trying to simulate.

In short, I did not get this right in the beginning. I am moving slowly onto the right track, doing two chain .exec calls for each step (rolled two scenarios into one).

However it seems that even in the case of one scenario the Session Key is either not saved or when i reuse it the variable is not correct.

The simulation basically does as follows:

  1. Login
  2. If the login is a success then verify if the user has any locations (GetLocations step).

Below you will see the updated code.

package basic

import com.excilys.ebi.gatling.core.Predef._
import com.excilys.ebi.gatling.http.Predef._
import com.excilys.ebi.gatling.jdbc.Predef._
import com.excilys.ebi.gatling.http.Headers.Names._
import com.jayway.jsonpath._
import akka.util.duration._
import bootstrap._

class GetLocations extends Simulation
{

val httpConf = httpConfig
.baseURL(“https://URL”)
.acceptCharsetHeader(“ISO-8859-1,utf-8;q=0.7,;q=0.7")
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,
/*;q=0.8”)
.acceptEncodingHeader(“gzip, deflate”)
.acceptLanguageHeader(“fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3”)
.disableFollowRedirect

val scn = scenario(“GetLocations”)
.exec(
http(“requestLogin”)
.post("/restapi/login")
.param(“username”, “user”)
.param(“password”, “pwd”)
.param(“client_uid”, “testUid”)
.check(jsonPath("$.result").is(“1”), jsonPath("$.output.session_key").findAll.saveAs(“session_key”))

).pause(15)

.exec(
http(“getLocations”)
.post("/restapi/get_employee_favouritelocations")
.param(“client_uid”,“testUid”)
.param(“clientType”,“automatedTest”)
.param(“session_key”,"${session_key}")
.check(jsonPath("$.result").is(“1”))
)

setUp(scn.users(50).ramp(50).protocolConfig(httpConf))

}

Thank you,
Bogdan

Are you sure you want to use findAll?
findAll will save a Seq (like a java Java), so as you then pass it to param, it get serialized as a String, which is probably not what you want.

I’m almost sure you shouldn’t be using findAll (I don’t expect a session_key to be multivalued). If so, remove it.

I suppose a find() call would find a single value?

Sorry for the double reply. my JSON response is as follows:

{“result”:1,“resultType”:“ack”,“output”:{“session_key”:“session_key_whatever_it_is”},“errorMessage”:false,“errorCode”:false,“additional”:{“locationtabs”:[“closest”,“favourites”]}}

Hope it will help more, perhaps i got my jsonpath notation wrong.

Bogdan

I suppose a find() call would find a single value?

http://gatling.io/docs/2.0.0-RC3/http/http_check.html?highlight=check#extracting

Did you actually tried to use find?

Then, you really should upgrade to Gatling 2 current release candidates. Gatling 1 will ne longer be maintained.

I already have Gatling 2.0. I downloaded a release candidate.

The sample you provided in your first post was for Gatling 1, hence my suggestion.

Maybe I am not getting it: tried to use ‘find’. I have tried without as well. Perhaps I am just not getting it.

My scenario code is as follows:

val scn = scenario(“GetLocations”)
.exec(
http(“requestLogin”)
.post("/restapi/login")
.param(“username”, “username”)
.param(“password”, “pwd”)
.param(“client_uid”, “testUid”)
.check(jsonPath("$.result").is(“1”), jsonPath("$.output.session_key").find.saveAs(“session_key”))

).pause(15)

.exec(
http(“getLocations”)
.post("/restapi/get_employee_favouritelocations")
.param(“client_uid”,“testUid”)
.param(“clientType”,“automatedTest”)
.param(“session_key”,"${session_key}")
.check(jsonPath("$.result").is(“1”))
)

Perhaps I am calling the ‘saveAs’ wrong. I am unsure how to deal with it at this point. As mentioned this is the first time I used Gatling so everything is very confusing. I am simply trying to follow the documentation.

Which release candidate do you use exactly?
What’s your problem exactly, now?

I have several comments:

  • Having a webservice named “getLocations” that has to be used with POST (instead of GET) doesn’t look very restful to me. Are you sure of this?
  • If you’re really doing a POST, are you sure your service implementation doesn’t expect some special headers, such as Content-Type: “application/x-www-form-urlencoded”?

Stephane,

The Webservice in question uses post. I did not develop it I simply have to test it.

My problem is I simply want to extract the value of the session_key out of the JSON response and reuse it in the next step of the test. It functions as follows:

  1. User logs in, gets a session key
  2. Locations are retrieved using that session key to access further calls as the user needs.
  3. Locations are returned. If the user has any locations, the “result” will be 1. If none it will be 0.

That is what I am trying to get to. Checking if the result is 1 is easy. Saving the session_key seems the hard part for me.

Bogdan

PS: Thanks again for your patience.

Saving the session_key seems the hard part for me.

What’s your problem exactly?
Your simulation looks fine to me.

The problem was solved. The pause of 15 seconds between the calls caused all the trouble. Thank you Stephane!

Funny explanation. Glad you found it! :slight_smile: