Reputation: 849
I have two scenarios in my script. I want to pass value of "CreateId" to 2nd scenario. I have saved "CreateId" in 1st scenario.
Error says:
No attribute named 'CreateId' is defined
jsonPath($.id).find(0).exists, found nothing
Scenario - 1
val create = scenario("Create")
.exec(http("post_request_create")
.post("/api/asdf")
.headers(headers_10)
.body(StringBody(session =>s"""{"name": "${randomName()}"}""")).asJSON
.check(jsonPath("$.id")
.saveAs("CreateId"))
)
Scenario - 2
val addTerm = scenario("Add Term")
.repeat (repeatCount){
exec(http("Add")
// NOT WORKING
//.post("""/api/asdfg/${CreateId}/terms""")
// NOT WORKING
.post(session => "/api/asdfg/" + session.get("CreateId").asOption[String] + "/terms")
.headers(headers_10)
.body(StringBody(session =>s"""{...somedata...}"""))
)
}
val scn = List(create.inject(atOnceUsers(1)),addTerm.inject(nothingFor(10 seconds), atOnceUsers(userCount)))
setUp(scn).protocols(httpProtocol)
Upvotes: 4
Views: 10480
Reputation: 2545
I have general solution which can easy to use. There is several steps how to do it.
Create methods which get all session variable from one scenario and another method which set this variables:
import scala.collection.concurrent.{Map => ConcurrentMap}
def passAnotherSession(implicit transferVariable: ConcurrentMap[String, Any]): Expression[Session] =
(currentSession: Session) => {
currentSession.setAll(transferVariable)
}
def saveSessionToVariable(implicit transferVariable: ConcurrentMap[String, Any]): Expression[Session] =
(currentSession: Session) => {
val systemKeys = List("gatling.http.ssl.sslContexts", "gatling.http.cache.contentCache", "gatling.http.cache.dns")
transferVariable ++= currentSession.removeAll(systemKeys: _*).attributes
currentSession
}
I defined methods above in my abstract base class which is inherited in all simulations/scenario classes.
Then in my simulations/scenario class I defined mutable map (via implicit) for store session variable:
import scala.collection.concurrent.{Map => ConcurrentMap}
implicit val setUpSession: ConcurrentMap[String, Any] = new TrieMap()
Now let's start using the methods. Below is an example of a scenario that gets the desired variable:
val setUpScenario = scenario(...)
.exec(...) // some action with save desired variable
.exec(saveSessionToVariable) // this save all session variables to above defined implicit map
And this is already a scenario that needs a variable:
val mainScenario = scenario(...)
.exec(passAnotherSession) // get variable from setUpScenario
.exec(...)
Upvotes: 0
Reputation: 21
Slight modification of @Peter's answer in Java. For some reason the direct modification of the session doesn't work in Java:
.exec(_.set("CreateId", CreateId)) // Set it here
The value set in the session is discarded after leaving the lambda function. I solved this by wrapping the value with a feeder:
Iterator<Map<String, Object>> createIdFeeder =
Stream.generate((Supplier<Map<String, Object>>) () ->
Collections.singletonMap("CreateId”, CreateId)
).iterator();
and adding it to the "Add Term" scenario:
ScenarioBuilder addTerm = scenario("Add Term”)
.feed(createIdFeeder) // Set it here
.repeat (repeatCount){
Upvotes: 0
Reputation: 1
I also got the same issue for token where I need to generate the one token from auth services and need to pass to other API. I followed below steps. Hope this will resolve your problem.
val create = scenario("Create")
.exec(http("post_request_create")
.post("/api/asdf")
.headers(headers_10)
.body(StringBody(session =>s"""{"name": "${randomName()}"}""")).asJSON
.check(jsonPath("$.id")
.saveAs("CreateId"))
)
then I created
val createId = exec(session => session.set("createdId", createdId));
Let's say create
is in different Test object. so created object in calling class.
val test = new Test()
val addTerm = test.createId
.exec(_.set("CreateId", CreateId)) // Set it here
.repeat (repeatCount){
exec(http("Add")
.post("""/api/asdfg/${CreateId}/terms""")
.headers(headers_10)
.body(StringBody(session =>s"""{...somedata...}"""))
)
}
val addTermScn = scenario("Add Term ").exec(addTerm)
val testScn = scenario("create").excec(test.create)
setUp(
testScn.inject(atOnceUsers(1)),
addTermScn.inject(nothingFor(5),rampUsers(vUsers) during (rampUp seconds)),
//orderLookup.inject(nothingFor(5),rampUsers(vUsers) during (rampUp seconds))
).throttle(
reachRps(tps) in (rampUp second),
holdFor(duration minutes)
).protocols(httpProtocol)
Upvotes: 0
Reputation: 849
Tried with below code and it worked. Hope it helps others.
var CreateId = ""
Scenario - 1
val create = scenario("Create")
.exec(http("post_request_create")
.post("/api/asdf")
.headers(headers_10)
.body(StringBody(session =>s"""{"name": "${randomName()}"}""")).asJSON
.check(jsonPath("$.id")
.saveAs("CreateId"))
)
.exec(session => {
CreateId = session("CreateId").as[String].trim
println("%%%%%%%%%%% ID =====>>>>>>>>>> " + CreateId)
session}
)
Scenario - 2
val addTerm = scenario("Add Term")
.exec(_.set("CreateId", CreateId)) // Set it here
.repeat (repeatCount){
exec(http("Add")
.post("""/api/asdfg/${CreateId}/terms""")
.headers(headers_10)
.body(StringBody(session =>s"""{...somedata...}"""))
)
}
val scn = List(create.inject(atOnceUsers(1)),addTerm.inject(nothingFor(10 seconds), atOnceUsers(userCount)))
setUp(scn).protocols(httpProtocol)
Upvotes: 8