gatling - extract cookie value string during test - scala

My tests run fine but now I need multiple sessions running at once. I've tried getting the cookie value using headerRegex("Set-Cookie", "HOME_SESSID=(.*)").saveAs("homeSessid") but when I print this out its returning a value of com.excilys.ebi.gatling.http.check.HttpMultipleCheckBuilder#6075598
I have no idea where this is coming from. My question is: what is going on?
Thanks.
edit: forgot to mention that the value its returning is not a session id and no matter what I use for the cookie name I get the same value.
edit (solution):
1) In the first .exec: .check( headerRegex("Set-Cookie", """HOME_SESSID=(.*dll/(\d+))""").saveAs("homeSessid") )
2) Then to retrieve homeSessid in later http requests I did, for example:
.post( session=>{session}.getAttribute("homeSessid").toString + "/some/relative/url" )

1) In the first .exec:
.check( headerRegex("Set-Cookie", """HOME_SESSID=(.*dll/(\d+))""").saveAs("homeSessid") )
2) Then to retrieve homeSessid in later http requests I did, for example:
.post( session=>{session}.getAttribute("homeSessid").toString + "/some/relative/url" )

Please properly read the Check documentation. Checks save data into the Session, so that's where you have to read. Here, you're just trying to print the extractor.
For example, after performing your check, you could add a exec(function), like:
.exec(session => {
println(session("homeSessid").as[String]) // Gatling 2 API
session
})

Related

Gatling session variable is returning same value in a loop

I'm having the below code, here the variable "${Cookie}" is always returning the same value (first one). The second API is being called with same ${Cookie} value in all iterations. How to set the session variable for each iteration?
val loginScenario = scenario("SignIn")
.repeat(100) {
feed(csv(dataPath + "user_list_2.csv").circular)
.exec(
http("Sign In")
.post("/members/sign_in")
.queryParam("user[email]", "${email}")
.queryParam("user[password]", "${password}")
.check(status.is(200))
.check(header("Set-Cookie").saveAs("Cookie"))
)
.exec(
http("Current user Info")
.get("/users/current_user_info")
.header("cookie", "${Cookie}")
.check(status.is(200))
)
}
Gatling comes with Cookie support enabled, so unless you're explicitly flushing the CookieJar on each iteration:
"Sign In" request will send a cookie after the first iteration, probably making it noop
The .check(header("Set-Cookie").saveAs("Cookie") is pretty useless, Gatling will handle cookies for you
Don't design your test this way, it's very wrong. Don't recycle virtual users or you will recycle connections and SSL Sessions and get better numbers than you should.
Just inject new users.

Gatlin test with multiple urls

I am using Gatling to measure the performance of a delete API. The url for the delete looks like
https://endpoint.com/rest/<id>/delete
So I basically want to invoke the delete API with different ID's. My scenario looks something like this:
val scenario =
exec(
http("${scenario}")
.post(getUrl())
.headers(getHeaders())
.body(StringBody(body))
.check(status.is(200))
)
.exec(session => {
val response = session("responsePayload").as[String]
logger.info(response)
session;
})
the getUrl() methods returns the endpoint with a unique id each time it's called. However I see that the method gets called only once & the url returned for the first time is being used in all subsequent calls.
What would be the best way to solve my use-case ?
You need to pass a function instead of a hardcoded value so your method is evaluated on each invocation:
.post(session => getUrl())

Gatling / Scala remove Vector from string value in POST request

I'm trying to send a POST request within a Gatling test.
2 values have to be sent, the first one is extracted from my page content, the second one is hardcoded.
My issue is that when i extract a value from my page content, i end up with a string submitted in my POST request but polluted with the "Vector()" wrapper.
Here is my scenario and how my variable is extracted:
val dossier = exec(http("Content creation - Extract vars")
.get("/node/add/dossier")
.check(css("""input[name="form_token"]""", "value").findAll.saveAs("form_token_node"))
.headers(headers_0))
.pause(2)
.exec(http("Content creation")
.post("/node/add/dossier")
.headers(headers_1)
.formParam("form_token", "${form_build_id_node}")
.formParam("form_id", "node_dossier_form")
.check(status.is(303))
)
And here is how the data look like when they are sent in the POST request:
form_token: Vector(HciBSyvuZ14NIj9HHuebgHYc06gL62B0iKAQ-E-KhvA)
form_id: node_dossier_form
As you can the the form_token variable should not look like this at all, it's breaking the form submission for a unvalid reason.
So my question is, how do i get ride of the Vector() part of the string?
And the answer is use ${form_build_id_node(0)} instead of ${form_build_id_node} to access to the value. Thanks to sschaef.
Here the issue is at saving the attribute.
you have used .findAll.saveAs - Which will save as list taking all the occurrences
If you want to pass only the first occurrences, then it should be
.check(css("""input[name="form_token"]""","value").saveAs("form_token_node"))
instead of
.check(css("""input[name="form_token"]""","value").findAll.saveAs("form_token_node"))
if your going to use foreach or repeat to get more values then you can .findAll.saveAs list and create a logic to iterate the session attribute
${form_build_id_node(i)} in your scenario

Scala/Gatling: How do I append to an array within a foreach?

I'm uber new with Scala/Gatling, so I apologize in advance if this question is dumb.
Writing gatling tests, and I've got a foreach that iterates through a list of items, makes a request to a URL, and verifies the response.
Now, I'd like to take an element from each response and create an array of them in the session for future use.
Here's some code:
foreach("collection","currentItem"){
exec(
http(requestName)
.post([redacted])
.param([redacted])
.check(
regex(""""error":\s*"([^"]*)"""").find.notExists
)
.check(
regex(""""id":\s*"([^"]*)"""").findAll.saveAs([HERE'S WHERE I'M STUCK])
)
)
}
I don't want to just use saveAs("someString"), or it'll be overwritten with every iteration of the foreach. What I need is all of the ids from each response to be appended to an array that I can then throw into the session.
I've been googling all morning, but every other search takes me to a github page that says "the documentation has been moved", and then provides a link to nowhere. I also didn't see any relevant stackoverflow posts.
Anyone have any ideas?
You can't do that directly in the check. You have to add an extra exec step after your request, but inside the loop that would fetch from the Session the previously stored accumulator and what was saved by the check in the current iteration, and push the result back into the Session.

Gatling-tool Extracting cookie data

I'm currently writing a test simulation with gatling and I've hit a brick wall. One of my post requests has an odd requirement. the request is:
.post("/checkout/cart/add/product/form_key/")
This post request wont complete with appending the form key on the end of the URL, the form key is stored in a cookie called: CACHED_FRONT_FORM_KEY
I need a way to grab the value in that cookie from the gatling cookiejar and to be used in the post request as follows:
.post("/checkout/cart/add/product/form_key/${FORM_KEY}")
I have done some googling and found a similar request:
https://groups.google.com/forum/#!topic/gatling/gXosGVnUuZA
But I'm unsure of how to implement this into a simulation file, I'm currently using gatling 1.4.3. Any assistance would be most appreciated.
Using the Gatling 2 API, you can access cookies as follows:
.exec( session => {
import io.gatling.http.cookie._
import org.asynchttpclient.uri._
import io.netty.handler.codec.http.cookie.ClientCookieDecoder.LAX.decode
val cookies = session("gatling.http.cookies").as[CookieJar].get(Uri.create("https://www.someSite.com"))
// for (ck <- cookies ) {
// val cc = decode(ck.toString())
// println(s"${cc.name} === ${cc.value}");
// }
val ck = cookies.filter( cookie => decode(cookie.toString()).name == "CookieName")
println(decode(ck.toString()).value)
session
})
Uncomment the iterator to view all the cookies in the current session
You can use a regexHeader check on the Set-Cookie reponse header in order to capture the cookie value.
Don't have enough rep to comment, so I'll add another answer.
For this Magento scenario I needed the form key, but using headerRegex("Set-Cookie","CACHED_FRONT_FORM_KEY=(.*)").saveAs("formkey") would return a value like
1Nt86VNYoPP5WUtt; path=/; domain=example.com
By using the following regex, I was able to extract just the 1Nt86VNYoPP5WUtt value
headerRegex("Set-Cookie","CACHED_FRONT_FORM_KEY=([^;]+)").saveAs("formkey")
I then used it in my HTTP Post like
http("add_to_cart")
.post("/checkout/cart/add/product/12345")
.formParam("form_key", "${formkey}")
Using the HTTP Helper getCookieValue is another way to grab cookie data:
// add cookie to the session as CACHED_FRONT_FORM_KEY
.exec(getCookieValue(CookieKey("CACHED_FRONT_FORM_KEY")))
.exec { session =>
println(session("CACHED_FRONT_FORM_KEY").as[String]) // `.as[]` unwraps the value from the session object
session
}
.post("/checkout/cart/add/product/form_key/${CACHED_FRONT_FORM_KEY}")
Sources
Gatling HTTP Helpers
Gatling Debugging