Transferring Session Variables to Other Files

Ok,

I think I’m overthinking something here. I’ve done lots of research and came across ways to utilize session variables in other sessions on the same script. I have utilized session variables by using the “session => sessionVariable” method, and calling session variables with ${variable} method, but I’ve still not been able to transfer the value of a session variable to a global variable. This is important for me because I am trying to make our test more modular by creating a main file for the test and scenario setup, but separate files for the functions or processes we plan to test.

So for example, my main test is set up somewhat like this:

package computerdatabase

import io.gatling.core.Predef._
import io.gatling.core.feeder._
import io.gatling.core.session._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.http.response.ResponseWrapper
import io.gatling.http.response.StringResponseBody
import scala.concurrent.duration._
import scala.util.parsing.json._
import scala.util.Random
import addons._
import modules._

class MutableTest extends Simulation {

val login = Login.login
val sessionToken = Login.accessToken

val t_iterations = Integer.getInteger(“iterations”, 1).toInt
val t_concurrency = Integer.getInteger(“concurrency”, 1).toInt
val t_rampUp = Integer.getInteger(“ramp-up”, 10).toInt

val httpConf = http
.baseURL(“https://funwebaddress.com”)
.headers(Map(“Content-Type” → “application/json,text/html,application/xhtml+xml,application/xml”, “charset” → “UTF-8”))
.doNotTrackHeader(“1”)
.acceptLanguageHeader(“en-US,en;q=0.5”)
.acceptEncodingHeader(“gzip, deflate”)
.userAgentHeader(“Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0”)

val scn = scenario(“Test”)
.repeat(t_iterations){
exec(login)
}

setUp(scn.inject(rampUsers(t_concurrency) over (t_rampUp)))
.protocols(httpConf)

}

The first modular file is coded as followed:

package computerdatabase.modules

import io.gatling.core.Predef._
import io.gatling.core.feeder._
import io.gatling.core.session._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.commons.validation._
import io.gatling.http.response.ResponseWrapper
import io.gatling.http.response.StringResponseBody
import scala.concurrent.duration._
import scala.util.parsing.json._
import scala.util.Random
import java.util.Calendar
import java.math.BigInteger
import java.security.SecureRandom
import java.text.SimpleDateFormat
import java.text.DateFormat
import java.nio.ByteBuffer
import org.apache.commons.codec.binary.Base64
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher
import org.bouncycastle.crypto.modes.CBCBlockCipher
import org.bouncycastle.crypto.engines.RijndaelEngine
import org.bouncycastle.crypto.paddings.PKCS7Padding
import org.bouncycastle.crypto.params._
import org.bouncycastle.crypto._

object Login {

val user = “username”

val password = “associatedPassword”

val variable1 = “value1”
val variable2 = “value2”
val variable3 = “value3”
var token = “”

val jsonrequest = “”"{“variable1”:"""" + variable1 + “”"",
“variable2”:"""" + variable2 + “”"",
“user”:"""" + user + “”"",
“password”:"""" + password + “”"",
“variable3”:"""" + variable3 + “”""
}"""

val login = exec(http(“Login”)
.post(“http://someURLwebsite.com”)
.body(StringBody(jsonrequest))
.transformResponse{
case response if response.isReceived =>
new ResponseWrapper(response) {
val stripped = response.body.string
override val body = new StringResponseBody(stripped, response.charset)
}
}
.asJSON
.check(jsonPath("$…result").is(“true”))
.check(jsonPath("$…responsetoken")
.find
.saveAs(“giventoken”)))

val accessToken = exec(session => {
token = session(“giventoken”).as[String]
println("session: " + token)
session
})

}

So this is what I tried. I have not been able to provide the main test’s “sessionToken” variable with the value provided by the “responsetoken” in the JSON response. Is there something I’m missing? Some way that will make this all easier? Or is this thought process and methodology flawed to begin with?

I did find solutions for others that were looking to allow multiple users to login with the same token, or others that wanted to utilize a token provided in one session as an argument in another session, but I have not found a solution to creating a global variable that has the value of a session variable that can be passed to another file.

If I could at least get a link to such a response, I would be most grateful.

TIA

Rob

Hi,

I suspect your programming background is with languages that don’t support multithreading (Python?) and where global mutable variables is fine.
Here, in a multithreaded context such as Gatling’s, you’re definitively shooting yourself in the foot.

The proper way to pass parameters is to create methods and pass method parameters.

Regards,

Thanks for the quick response Stéphane.

I am comfortable using methods with parameters, but I am fairly new to scala. I have been working with it since the beginning of this past summer. So I guess I’m still feeling out the capabilities and limitations of the language.

So is it possible to create methods that go from one file to the other and vice versa? Or is that more of a one-way street?

I did try to use a method for my situation above. Here is what I came up with:

package computerdatabase

import io.gatling.core.Predef._
import io.gatling.core.feeder._
import io.gatling.core.session._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.http.response.
ResponseWrapper
import io.gatling.http.response.StringResponseBody
import scala.concurrent.duration._
import scala.util.parsing.json._
import scala.util.Random
import addons._
import modules._

class MutableTest extends Simulation {

val variable1 = “value1”
val variable2 = “value2”

val login = Login.login(variable1, variable2)

val t_iterations = Integer.getInteger(“iterations”, 1).toInt
val t_concurrency = Integer.getInteger(“concurrency”, 1).toInt
val t_rampUp = Integer.getInteger(“ramp-up”, 10).toInt

val httpConf = http
.baseURL(“https://funwebaddress.com”)
.headers(Map(“Content-Type” → “application/json,text/html,application/xhtml+xml,application/xml”, “charset” → “UTF-8”))
.doNotTrackHeader(“1”)
.acceptLanguageHeader(“en-US,en;q=0.5”)
.acceptEncodingHeader(“gzip, deflate”)
.userAgentHeader(“Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0”)

val scn = scenario(“Test”)
.repeat(t_iterations){
exec(login)
}

setUp(scn.inject(rampUsers(t_concurrency) over (t_rampUp)))
.protocols(httpConf)

}

And the module file:

package computerdatabase.modules

import io.gatling.core.Predef._
import io.gatling.core.feeder._
import io.gatling.core.session._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.commons.validation._
import io.gatling.http.response.ResponseWrapper
import io.gatling.http.response.StringResponseBody
import scala.concurrent.duration._
import scala.util.parsing.json._
import scala.util.Random
import java.util.Calendar
import java.math.BigInteger
import java.security.SecureRandom
import java.text.SimpleDateFormat
import java.text.DateFormat
import java.nio.ByteBuffer
import org.apache.commons.codec.binary.Base64
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher
import org.bouncycastle.crypto.modes.CBCBlockCipher
import org.bouncycastle.crypto.engines.RijndaelEngine
import org.bouncycastle.crypto.paddings.PKCS7Padding
import org.bouncycastle.crypto.params._
import org.bouncycastle.crypto._

object Login {

def login (variable1:String, variable2:String) : String = {

val user = “username”

val password = “associatedPassword”

val modvar1 = variable1
val modvar2 = variable2
var token = “”

val jsonrequest = “”"{“variable1”:"""" + modvar1 + “”"",
“variable2”:"""" + modvar2 + “”"",
“user”:"""" + user + “”"",
“password”:"""" + password + “”""
}"""

val login = exec(http(“Login”)
.post(“http://someURLwebsite.com”)
.body(StringBody(jsonrequest))
.transformResponse{
case response if response.isReceived =>
new ResponseWrapper(response) {
val stripped = response.body.string
override val body = new StringResponseBody(stripped, response.charset)
}
}
.asJSON
.check(jsonPath("$…result").is(“true”))
.check(jsonPath("$…responsetoken")
.find
.saveAs(“giventoken”)))

return giventoken
})

}

}

When I attempted this setup, I received a compatibility error. “login” was a string, while it needed to be a gatling chain. How do I get the token from the module file, while still setting it up as a gatling execution for the scenario?

Am I wrong in thinking this is possible?

Thanks again,

Rob