Correlation Of dynamic value in Gatling - scala

I'm trying to correlate or create a "Check" in Gatling load tool, but not sure how to do it. I Went through the advanced tutorial doc from official Gatling website but couldn't exactly find much on correlation of the dynamic value.
Below is the peice of code from my script
.feed(feeder)
.exec(http("EnterDetails")
.post("/events/review.action")
.headers(headers_6)
.formParam("userInfo.spgEmail", "")
.formParam("userInfo.title", "")
.formParam("userInfo.firstName", "${FirstName}")
.formParam("userInfo.lastName", "${LastName}")
.formParam("userInfo.address1", "Open")
.formParam("userInfo.address2", "")
.formParam("userInfo.city", "${City}")
.formParam("userInfo.state", "NYY")
.formParam("userInfo.country", "US")
.formParam("userInfo.zipCode", "10016")
.formParam("userInfo.primaryNoInfo.optedIn", "false")
.formParam("userInfo.phoneTwoInfo.optedIn", "false")
.formParam("userInfo.phoneThreeInfo.optedIn", "false")
.formParam("userInfo.primaryNoInfo.validInd", "Y")
.formParam("userInfo.phoneTwoInfo.validInd", "")
.formParam("userInfo.phoneThreeInfo.validInd", "")
.formParam("userInfo.phoneUseType1", "0")
.formParam("userInfo.primaryNoInfo.phoneNumber", "9876543211")
.formParam("userInfo.primaryNoInfo.extension", "")
.formParam("userInfo.country1", "US%28%2B1%29")
.formParam("__checkbox_userInfo.primaryNoInfo.oneTimeOptInPresent", "true")
.formParam("userInfo.phoneUseType2", "-1")
.formParam("userInfo.phoneTwoInfo.phoneNumber", "")
.formParam("userInfo.phoneTwoInfo.extension", "")
.formParam("userInfo.country2", "US%28%2B1%29")
.formParam("__checkbox_userInfo.phoneTwoInfo.oneTimeOptInPresent", "true")
.formParam("userInfo.phoneUseType3", "-1")
.formParam("userInfo.phoneThreeInfo.phoneNumber", "")
.formParam("userInfo.phoneThreeInfo.extension", "")
.formParam("userInfo.country3", "US%28%2B1%29")
.formParam("__checkbox_userInfo.phoneThreeInfo.oneTimeOptInPresent", "true")
.formParam("userInfo.email", "")
.formParam("userInfo.retypeEmail", "")
.formParam("userInfo.nonCCPayment", "true")
.formParam("userInfo.SPGNumber", "")
.formParam("userInfo.arrivalCarrier", "")
.formParam("userInfo.transportationNumber", "")
.formParam("userInfo.transportationArrTime", "")
.formParam("userInfo.hotelArrivalTime", "")
.formParam("userInfo.hotelDepartureTime", "")
.formParam("userInfo.SRequest", "")
.formParam("userInfo.IAgree", "true")
.formParam("__checkbox_userInfo.IAgree", "true")
.formParam("method%3Aexecute", "Review+Your+Reservation+"))
.pause(2)
.exec(http("ReviewREservation")
.get(uri3 + "/s01000706679492?AQB=1&ndh=1&pf=1&t=21%2F3%2F2016%2012%3A45%3A54%204%200&D=D%3D&fid=31A8BC73D5B8ACEB-2B64CD0ACE185774&ce=UTF-8&pageName=Review%20Reservation&g=https%3A%2F%2Fstg.starwoodmeeting.com%2Fevents%2Freview.action&r=https%3A%2F%2Fstg.starwoodmeeting.com%2Fevents%2Fselectcreate%21execute.action%3FselRoom%3D1&cc=USD&ch=StarGroups&server=StarGroups&c2=SOCIAL&c3=1603295001&c4=271&c5=SI&c6=YES&c8=en&s=1600x838&c=24&j=1.6&v=N&k=Y&bw=1042&bh=733&AQE=1")
.headers(headers_3))
.pause(7)
.exec(http("request_13")
.post("/events/confirm.action")
.headers(headers_6)
.formParam("method%3Aexecute", "Complete+Your+Reservation"))
.pause(4)
.exec(http("CompleteReservation")
.get(uri3 + "/s03623649917832?AQB=1&ndh=1&pf=1&t=21%2F3%2F2016%2012%3A46%3A5%204%200&D=D%3D&fid=31A8BC73D5B8ACEB-2B64CD0ACE185774&ce=UTF-8&pageName=Reservation%20Confirmation&g=https%3A%2F%2Fstg.starwoodmeeting.com%2Fevents%2Fconfirm.action&r=https%3A%2F%2Fstg.starwoodmeeting.com%2Fevents%2Freview.action&cc=CAD&purchaseID=20160421_734091125&ch=StarGroups&server=StarGroups&events=purchase&products=%3B271%3B1%3B100.00&c2=SOCIAL&c3=1603295001&c4=271&v4=20160421_734091125&c5=SI&c6=YES&c8=en&s=1600x838&c=24&j=1.6&v=N&k=Y&bw=1042&bh=733&AQE=1")
.headers(headers_3))
setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
In The above code I have a dynamic Purchase ID in
.exec(http("CompleteReservation")
which gets generated from the server and needs to be correlated.
From The Gatling Documentation, I understand( correct me if I'm wrong) that we need the inspect element code to get the CSS path.(Shown Here).
Inspect Element
Please let me know how do we correlate .TIA.

In Gatling you have to use checks to extract a value from response. Take a look in documentation.
You can choose to use regex or xpath to extract value in tag. But in your case I'd recommend to use simple regex because IMO in your example response there are not tags or IDs where you can easily hook with xpath. I mean the way that the xpath expression will still remain simple and understandable. Next thing is to extract value into session and afterwards to use it.
Following is the example scenario extracting query path of URI from response received from example.com which is afterwards printed in console:
val scn = scenario("Checks")
.exec(
http("root")
.get("/")
.check(
// Extracting URI query path from response body via regexp and storing into session
regex("""www\.iana\.org/([a-z/]*)""").find.saveAs("queryPath")
)
)
// Printing the value from session
// Important thing to note is how you can access stored value from session
.exec { session =>
println(" QUERY PATH --> " + session("queryPath").as[String])
session
}
In your case your last part could look something like this:
.exec(http("CompleteReservation")
.get(uri3 + "/s03623649917832?AQB=1&ndh=1&pf=1&t=21%2F3%2F2016%2012%3A46%3A5%204%200&D=D%3D&fid=31A8BC73D5B8ACEB-2B64CD0ACE185774&ce=UTF-8&pageName=Reservation%20Confirmation&g=https%3A%2F%2Fstg.starwoodmeeting.com%2Fevents%2Fconfirm.action&r=https%3A%2F%2Fstg.starwoodmeeting.com%2Fevents%2Freview.action&cc=CAD&purchaseID=20160421_734091125&ch=StarGroups&server=StarGroups&events=purchase&products=%3B271%3B1%3B100.00&c2=SOCIAL&c3=1603295001&c4=271&v4=20160421_734091125&c5=SI&c6=YES&c8=en&s=1600x838&c=24&j=1.6&v=N&k=Y&bw=1042&bh=733&AQE=1")
.headers(headers_3))
.check(
regex("""Your confirmation number is (\d+)""") // Regular expression with group which represents confirmation number.
.find
.saveAs("confirmationNumber") // Now the extracted regexp group is stored in session under "confirmationNumber" as name.
)
// Missing, check, transformation or use of value from session
I don't know your usage of extracted value thus it's missing in snippet above . But I hope that you will already have an idea how to handle responses and how to use the extracted values next.
I hope that it helps.

Related

Feeder value not updated in gatling test

I am new to scala and gatling . I am trying to fetch values from feeder and post zip file to service . but ${extensionId} is not been updated with fetched value instead it remain as ${extensionId} . Could some one please help me know If I miss some thing here .
def installExtension() =
exec(http("template - Install Extension")
.post(url + "/v1/extensions")
.basicAuth("jack", "password")
.headers(namespaceHeader)
// using testUtils to get InputStream conte
.body(InputStreamBody(TestUtils.toStream(hashMap.get("${extensionId}").getOrElse(null))))
.check(status.is( 201)))
class extmgrSimulations extends Simulation {
val extensionIds = csv(s"${Configuration.dataDirectory}/extensionId.csv").circular
val extMgrScenerio = scenario("extensionMgr - Scenario")
.during(Configuration.duration) {
exitBlockOnFail(
group("load-test") {
exec(
pace(Configuration.paceFrom, Configuration.paceTo),
feed(extensionIds),feed(extensionIds)
randomSwitch(
50.00 -> group("Install and delete") {
exec(
extmgrChain.installExtension(),
extmgrChain.deleteExtension(),
)
},
50.00 -> extmgrChain.listExtension()
)
)
}
)
}
That can't work. Gatling EL (the ${} syntax in strings) doesn't magically work anywhere. This is explained in the documentation.
Warning
This Expression Language only works on String values being passed to Gatling DSL methods. Such Strings are parsed only once, when the Gatling simulation is being instantiated.
For example queryParam("latitude", session => "${latitude}") wouldn’t work because the parameter is not a String, but a function that returns a String.
Also, queryParam("latitude", "${latitude}".toInt) wouldn’t because the toInt would happen before passing the parameter to the queryParam method.
The solution here would be to pass a function:
session => session("latitude").validate[Int].

Gatling: check binary response not empty

I'm doing some tests with Gatling using Scala. I'm trying to check whether a response body that is returned is not empty.
I'm doing it like this:
def getImages: ChainBuilder = feed(credentials)
.exec(http("Get Image")
.get(GET_MY_URI)
.queryParam("guid", "${branch}")
.queryParam("t", "0.458654")
.check(status.is(200))
.check(bodyString.transform(_.size > 1).is(true)))
But it's not working. I get:
java.nio.charset.MalformedInputException: Input length = 1
Does somebody know how to achieve what I'm trying?
Replace
.check(bodyString.transform(_.size > 1).is(true)))
with
.check(bodyBytes.exists)
All the DSL is explained here: https://gatling.io/docs/current/cheat-sheet/

JsonPath check hashMap values are present using Gatling?

I want to compare some <key,values> in the jsonPath passed as HashMap<String,String>() data. How can we achieve it in gatling check ?
val hashMap = new HashMap[String,String]()
hashMap.put("foo", "bar")
OR can I simply check something like this ?
for (String key <- keyValue){
.check(jsonPath("$." + key.(is(hashMap.get(key)))))
}
OR
.check(jsonPath.containsAll(hashMap.keySet), jsonPath.containsAll(hashMap.valueSet))
Or can I use hamcrest or some other to compare this HashMap with JsonPath.
.exec(http("my testl").post("/some_url").headers(common_header).body(bodyPayLoad).
asJSON.check(status.is(200)).check(jsonPath("$",Matchers.hasItems(hashMap)).saveAs("response"))).exec(session => {
val responseValue = session.get("response").asOption[String]
println(testCase + " REST API Response :" + responseValue)
session
}).pause(10)
How can I achive it?

Parse Json array response in scala\Play

There is a web service returning array of something
{"apps": [{"name": "one"}, {"name": "two"}]}
In my code I want to iterate every name
val request = WS.url(s"http://localhost:9000/getData")
val json = request.get.map { response =>
(response.json \ "apps" \\ "name")
}
json.foreach(println)
However all my attempts return single record
// Expect
one
two
// Actual
ListBuffer("one", "two")
First of all, the neat solution here would be:
val request = WS.url(s"http://localhost:9000/getData")
request.get.map { response =>
val names = (response.json \ "apps" \\ "name")
names.foreach(println)
}
Secondly, if you don't want to get confused about the types, you should change your naming standards. For a Future object, you may start with the prefix future, for an Option, it could start with maybe, etc. If you do so, the problem in your example will be more obvious:
val request = WS.url(s"http://localhost:9000/getData")
val futureJson = request.get.map { response =>
(response.json \ "apps" \\ "name")
}
futureJson.foreach(println) // you call foreach for a Future, not for a List
Thirdly, why would Future trait have a method called foreach? I think that's confusing for beginners and even mid-level developers. We know from other languages that, foreach means iterate over a list of objects. In Scala, it is considered part of "Monadic operations" which is still a gray area for me :), but the comment for Future.foreach in Scala source is this:
/** Asynchronously processes the value in the future once the value becomes available.
*
* Will not be called if the future fails.
*/
def foreach[U]
Your value of json is actually a Future[Seq[JsValue]], so when you foreach over the future you get the entire list back. You would need an additional foreach to iterate over the list of values.

Saving session attribute in a list

I would like to save a session attribute in a list in my gatling simulation. What am trying to do is to get all the values of my JSON who are defined in a CV file and write it in a file. In my example below "test" is always equal to the value of the first jsonPath.
Here what I am doing:
val scn1 = scenario("[SCENARIO] GET")
.repeat(Nbproduct-1, "counter") (
feed(csv(CSV).circular)
.exec(http("get JSON")
.get(url_1")
.check(jsonPath("""$.${meta_ref}""").find.saveAs("test")))
.pause(1)
.exec(session => {
writer.write("\""+session("meta_cts").as[String]+"\":\"" + session("test").as[String]+"\",\n")
session
}
)
I also tried this but it get the value of the counter...
.check(jsonPath("""$.${meta_ref}""").find.saveAs("""jdd_value("${counter}")""")))
Thanks for the help!
Feeders are shared datasources, so first user will pop the first record, second user the second record, etc...
Then, it's not possible to define checks at runtime (depending on some entries in a file). All DSL components are builders that are only resolved once when the Simulation is loaded.