http request not executing

Hi,

The http request in the following Gatling script snippet is not executing. I’m sure it is because of something I don’t understand about how Gatling DSL interacts with Scala.

Sorry in advance for not code formatting this. I can’t see how to format something as code.

foreach(components, “component”) {
exec(session => {
val component = session(“component”).as[ITestComponent]
exec(
http(s"Upload Component ${component.getId}")
.post(s"/component/$repoId/$assetId/${component.getId}/${component.getResourceVersionId}")
.bodyPart(RawFileBodyPart(“resource”, component.getContent.getAbsolutePath()).contentType(component.getMediaType()).fileName(component.getContent.getName())).asMultipartForm
)
session
})
}

Remove the exec which is inside the exec session and then try.

foreach(components, “component”) {
exec(session => {
val component = session(“component”).as[ITestComponent]

http(s"Upload Component ${component.getId}")
.post(s"/component/$repoId/$assetId/${component.getId}/${component.getResourceVersionId}")
.bodyPart(RawFileBodyPart(“resource”, component.getContent.getAbsolutePath()).contentType(component.getMediaType()).fileName(component.getContent.getName())).asMultipartForm

session
})
}

Hi,

This cannot work, please read the documentation: https://gatling.io/docs/gatling/reference/current/general/scenario/#exec

Gatling DSL components are immutable ActionBuilder(s) that have to be chained altogether and are only built once on startup. The result is a workflow chain of Action(s). These builders don’t do anything by themselves, they don’t trigger any side effect, they are just definitions. As a result, creating such DSL components at runtime in functions is completely meaningless. If you want conditional paths in your execution flow, use the proper DSL components (doIf, randomSwitch, etc)

exec { session =>
  if (someSessionBasedCondition(session)) {
    // just create a builder that is immediately discarded, hence doesn't do anything
    // you should be using a doIf here
    http("Get Homepage").get("[http://github.com/gatling/gatling](http://github.com/gatling/gatling)")
  }
  session
}

You should do something like:

foreach(components, “component”) {
exec(
http { session =>
val component = session(“component”).as[ITestComponent]

s"Upload Component ${component.getId}"
}.post { session =>
val component = session(“component”).as[ITestComponent]
s"/component/$repoId/$assetId/${component.getId}/${component.getResourceVersionId}"
}
.bodyPart(RawFileBodyPart(“resource”, session => {
val component = session(“component”).as[ITestComponent]
component.getContent.getAbsolutePath()).contentType(component.getMediaType()).fileName(component.getContent.getName())).asMultipartForm
}
)
}

Yes, this is pretty complicated. The reason it looks so over bloated is because you’re trying to use a Java POJO (hidden behind an interface), instead of using Scala case classes.
If you were to use a Scala case class, you could use Gatling Expression Language (it doesn’t support accessing POJOs by reflection atm) and do something like this:

foreach(components, “component”) {
exec(
http(“Upload Component ${component.id}”)
.post(s"/component/$repoId/$assetId/$${component.id}/$${component.resourceVersionId}")
.bodyPart(
RawFileBodyPart(“resource”, “${component.content.absolutePath}”)
.contentType("${component.content.mediaType}")
.fileName("${component.content.name}")
).asMultipartForm
)
}

Thank you Stephane! That helps a lot. We have a pretty sophisticated Java testing framework that generates complex random resources that our clients send to our HTTP APIs. We didn’t want to rewrite that in Scala. I’ll stick with your first suggestion.

I have read the documentation. I’m a new comer to Gatling and the concepts are sinking in slowly. More sample code snippets would help.

Thanks,
Michael-