Unable to create different values in map within a repeat

448 views
Skip to first unread message

Robert Hafner

unread,
Nov 1, 2017, 12:13:18 PM11/1/17
to Gatling User Group
I'm new to gatling/scala and am running into an issue in which the following repeat section is not creating different values for the definitionProperties map in each iteration. I'm looking for an explanation as to why it doesn't work as well as an alternative way to implement this logic.

.repeat(10) {
val performanceModel : String = DefinitionUtil.getDefinitionAsString("Performance2")
val performanceDefinitionId = "WF7FF447E1-AAA5-4ECF-850F-99702FFE3042"

val headers = Map(
"Authorization" -> ("${tokenType} ${accessToken}"),
"Content-Type" -> "application/vnd.workflow.definition+json",
"Accept" -> "application/vnd.workflow.definition.summary+json"
)

var definitionId = "WF".concat(java.util.UUID.randomUUID().toString)
var name = definitionId
var comment = "Definition ".concat(definitionId)
var model = performanceModel.replace(performanceDefinitionId, definitionId).replace("Performance2", name)

var definitionProperties = Map(
"id" -> definitionId,
"name" -> name,
"comment" -> comment,
"clientRegistrationId" -> clientRegistrationId,
"model" -> model
)

exec(WorkflowAction.createDefinition(definitionProperties))
}

thanks,
Rob

Stephan D.

unread,
Nov 1, 2017, 5:20:27 PM11/1/17
to Gatling User Group
The variables are only evaluated once at the time the scenario is built. 
I think you have to set the values within a session.

Robert Hafner

unread,
Nov 2, 2017, 6:38:50 AM11/2/17
to Gatling User Group
Thanks for the response Stephan! I have another method (shown below) which is called with different values (for the name parameter) in my scenario and the variables are evaluated for each call. Any idea why these variables are evaluated each time based on the name parameter and the other variables are only evaluated once when the scenario is built.

def createTag(name : String) = {
var tagProperties: Map[String, String] = Map("name" -> name)
val body = JsonUtil.mapToJsonString(tagProperties)


val headers = Map(
"Authorization" -> ("${tokenType} ${accessToken}"),
    "Content-Type" -> "application/vnd.workflow.tag+json",
"Accept" -> "application/vnd.workflow.tag+json"
)
exec(http("Create Tag")
.post("/workflow/tags")
.headers(headers)
.body(StringBody(body)).asJSON
.check(status.in(201)))
}
 

Stephan D.

unread,
Nov 2, 2017, 8:15:49 AM11/2/17
to Gatling User Group
With the new method you are starting a new session every time you finished your "post", right? 

But with the first example you are looping within a session. To manipulate a running session you need to use the session api gatling provides. 

Maybe Stephane can verify this answer. I'm not 100% sure and pretty new to scala and gatling too ;)  

Robert Hafner

unread,
Nov 2, 2017, 8:38:39 AM11/2/17
to Gatling User Group
I'm creating my scenario using the following class. I'm not sure I understand where the session is being created. 

I believe the session is associated with each virtual user, however I'm not sure where the session begins/ends. Is the session not created until the duration block?

In the code below the call in the repeat block does not work, however, making multiple calls does. Not sure I understand why after re-reading the documentation.


class BasicWorkflowScenario(durationMinutes: Int, userFeeder: FeederBuilder[String]) extends
ScenarioCreator {
...

override def getScenario(): ScenarioBuilder = scenario(name)
.exec(LoginAction.administratorLogin)
.feed(userFeeder)
.exec(LoginAction.switchToWorkflowAdmin)
.exec(WorkflowAction.createTag("Tag1"))
.exec(WorkflowAction.createTag("Tag2"))
...
    // This results in a http status of 409 b/c it uses the same UUID value for each iteration.
.repeat(10) {
      exec(WorkflowAction.createDefinition("WF".concat(java.util.UUID.randomUUID().toString), clientRegistrationId))
    }
    // However, if I don't use repeat block, but rather make individual calls it produces unique values.
    exec(WorkflowAction.createDefinition("WF".concat(java.util.UUID.randomUUID().toString), clientRegistrationId))
    exec(WorkflowAction.createDefinition("WF".concat(java.util.UUID.randomUUID().toString), clientRegistrationId))
    ...
    .during(durationMinutes * 60) {
      // call other actions
pause(1)
    }
  }
}

Vu Nguyen

unread,
Nov 2, 2017, 4:37:54 PM11/2/17
to Gatling User Group

Robert,

I think this thread provides you some guidance

Vu
---

Robert Hafner

unread,
Nov 3, 2017, 7:36:53 AM11/3/17
to Gatling User Group
Thanks Vu. I updated the exec call to specify a session in an attempt to use a lambda. However, the code fails to compile with this change. Any idea what I'm doing wrong here?


07:25:27.269 [ERROR] i.g.c.ZincCompiler$ - C:\workspaces\viya\workflow-test-integration\src\test\scala\com\workflow\test\qa\perf\scenarios.scala:48: type mismatch;
 found   : io.gatling.core.structure.ChainBuilder
 required: io.gatling.commons.validation.Validation[io.gatling.core.session.Session]
07:25:27.269 [ERROR] i.g.c.ZincCompiler$ -       WorkflowAction.createDefinition(
07:25:27.270 [ERROR] i.g.c.ZincCompiler$ -                                      ^
07:25:27.275 [ERROR] i.g.c.ZincCompiler$ - one error found
07:25:27.276 [ERROR] i.g.c.ZincCompiler$ - Compilation crashed
sbt.compiler.CompileFailed: null
        at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:105)
        at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
        at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
...


For reference, here are the code changes I made.

BasicWorkflowScenario.scala:

scenario(name)
.exec( (session:Session) =>
WorkflowAction.createDefinition(
"WF".concat(java.util.UUID.randomUUID().toString()),
clientRegistrationId,
session
)
)


WorkflowAction.scala:

def createDefinition(definitionId: String, clientRegistrationId : String, session : Session) = {
 ...
}



Vu Nguyen

unread,
Nov 4, 2017, 12:33:37 AM11/4/17
to Gatling User Group

I think you have two options:
 
Option #1
exec { session =>
  // function to do work
  WorkflowAction.createDefinition()

  // return the original session
  session
}

Option #2
exec { session =>
  // function to do work and return updated session
  WorkflowAction.createDefinition()
}

For more information, please check following topics in documentation

- Most Gatling DSL methods takes Expression[T] parameters, which is a type alias for Session => Validation[T]. They are allowed to return a Session instead of Validation[Session] because of an implicit conversion.

- Gatling DSL exec can also be passed an Expression function.

- Session is a virtual user’s state. Session instances are immutable!
Reply all
Reply to author
Forward
0 new messages