Best way to manipulate elements in foreach

I want to be able to use .split() on the current element in a foreach for a scenario. Is that possible? For example, I have the following code:

You can’t use Gatling EL and Scala code together!

http((“task”).validate[String].map(.split("""","""")(1)))

Thank you! That worked.

I wanted to know why it worked though. What does the _(“task”) part do? Also why do I need to use .map()?

Sorry, I’m still learning Scala.

Underscore is a Scala shortcut for a closure.
An expended version would be :
http(session => session(“task”).validate[String].map(_.split("""","""")(1)))

Then, session(“task”).validate[String*]* produce a Validation[String]. So, to transform it, you can use .map() function on it.

clearer ?

Oh, that makes a lot more sense than what I was thinking.

Sorry about that. Thank you for taking the time to make that clear.

No prob.

Sure (sorry, I should have explained better, this will be detailed properly in Gatling 2 documentation).

  1. Gatling EL syntax is very limited, you have to stick to the documentation. You can’t mix it with Scala code. What happens is that Gatling DSL methods actually expects functions. The reason you can pass Strings instead is that there’s an implicit conversion that parses the String and turn it into a function that manipulates the Session.

  2. Regarding what I wrote:
    Please have a look at Gatling 2 Session and Validation APIs:
    https://github.com/excilys/gatling/wiki/Gatling-2#wiki-validation

The expected function signature is Session => Validation[String] (input is Session, output is Validation[String]), so:

session: Session => session(“task”).validate[String].map(task => task.split(""""""")(1)))

session(“task”).validate[String] returns a Validation[String] Validation is a container (monad) and with map, you can create a new container of the same type, but with a new content, that’s obtained here by splitting the string.

This function can be written more shortly.

Get it?

Thank you for that explanation.

So, does that mean I can’t declare var’s or val’s inside of the .foreach()?

I’ve been trying to do that because I’m curious if it would work. It would make a lot of things simpler. If not, I’ll figure out another way to get what I need.

Oh, looks like I can create a var of the current task with no split or anything done to it. But I am not sure how to save the manipulated form. So I guess I didn’t understand this as well as I thought.

I have tried .validate[String], .map(_.split()), and using the _(“doc”). They all produce errors. The follow is the only way that doesn’t produce errors right away, but after trying to run the scenario it stops with the error that the array index is out of bounds:

.foreach("${tasks}", “task”) {
var taskType = “${task}”.split(""",""")(0)
val taskID = “${task}”.split(""",""")(1)
val taskName = “${task}”.split(""",""")(2)
val taskPacketStep = “${task}”.split(""",""")(4)
val taskParallelID = “${task}”.split(""",""")(7)

exec(http(“request_21”)
.get("/" + site + “/main/portal/lists/listDetail.cfm?var1=${taskType}&var2=${taskID}&var3=${taskName}&var4=${taskPacketStep}&var5=&var6=1&var7=module:docs&var8=${taskParallelID}”)
.check(status.is(200)))
}

First, once again, “${task}”.split(""",""") just means “try to split the “${task}” String”. There’s no magic that would make it work the way you’d like.

Then, foreach content is only evaluated once, when building the scenario. That’s the parameters of DSL methods, like request(DYNAMIC_HERE).get(DYNAMIC_HERE) that gets evaluated every time.

Hmm… So is there any way for each user to have different GET actions based on an array of values that I get from doing the SaveAs() in the session?

The way our system works is we have some links in the page that brings up different task actions for each user via JavaScript. I can catch the task JavaScript (which holds IDs, task names, and other task info) with the SaveAs().

Each link (task) on the page has an href with all the task info in a JavaScript function. So it is saved into an array of strings. This is for each user. They all have different tasks, with different IDs, names, etc…

I’m trying to cut up those strings and then do a http(get()) with them. But I’m doing a .foreach() and want each individual task in the array split into its separate parts (ID, task name, packet name, etc…) so that they are in that get request each. All of them would get their own request.

Would doing some type of .repeat() work better to do this? Hopefully I’m making sense.

Hmm... So is there any way for each user to have different GET actions
based on an array of values that I get from doing the SaveAs() in the
session?

Yep, many ways:

The way our system works is we have some links in the page that brings up
different task actions for each user via JavaScript. I can catch the task
JavaScript (which holds IDs, task names, and other task info) with the
SaveAs().

Each link (task) on the page has an href with all the task info in a
JavaScript function. So it is saved into an array of strings. This is for
each user. They all have different tasks, with different IDs, names, etc...

I'm trying to cut up those strings and then do a http(get()) with them.
But I'm doing a .foreach() and want each individual task in the array split
into its separate parts (ID, task name, packet name, etc..) so that they
are in that get request each. All of them would get their own request.

cut up = probably add a exec(function), like:

exec(session =>
    session("array").validate[String].map { array
        val parts = array.split(", ") // or a regex, or whatever you like
        session.setAll("ID" -> parts(0), "taskName" -> part(1),
"packerName" -> part(2)) // store the parts
    }
)

Would doing some type of .repeat() work better to do this? Hopefully I'm
making sense.

No, I think foreach is the way to go:

   - first multiple results (.findAll)
   - loop on those with foreach
   - on each iteration, split current element and store the parts

Success!!! Thank you. Exactly what I needed! I didn’t realize I would need another .exec(session)…

I’ve been toying around with it for a while now and have come up with some pretty interesting scripts because of this.

Thank you so much. I believe that’s all of my major issues you’ve solved.

–Matt Royer

Glad to hear!

Hopefully we’ll write a comprehensive documentation so that people will waste less time with trials and errors…