Multiple "Users" - Same Session

I want to simulate something where I have a single session to my website, but multiple things happening to that session at the same time (please save the “why are you doing that?” :).

What I thought I could do was this:

  • Execute a /Login
  • Grab the “.Authentication” and “ASP.NET_SessionId” that I got and save them
  • Create my actual scenario and set the cookies I stored off and simulated N # of users doing some action
    Is there an easier way to do this?

Please let me know if you need further information.

Thanks,

Levi

I want to simulate something where I have a single session to my website,
but multiple things happening to that session at the same time (please save
the "why are you doing that?" :).

Good thing you started with this :wink:

Is there an easier way to do this?

I don't think so

You have to way of doing this:

   - Don't use Gatling DSL for login in and fetching the session cookie.
   Use whatever HTTP client you like. Gatling ships AsyncHttpClient
   <https://github.com/AsyncHttpClient/async-http-client>. Do that in the
   before
   <http://gatling.io/docs/2.0.2/general/simulation_structure.html#hooks>
   hook.
   - Use Gatling DSL with a dedicated scenario. This ugly thing here is
   that you'll have to introduce some sort of coordination so that the users
   don't start before you've fetched the session cookie. Depending on your
   Scala skills, a simple delay might be the best solution.

Either way, you'll have to store the cookie in some sort of shared
threadsafe placeholder such as an AtomicReference, then inject this cookie
<http://gatling.io/docs/2.0.2/http/http_helpers.html#adding-a-cookie> in
the "real" users.

Awesome, thanks for the sensible response :wink:

I don’t know Scala at all, so the former is probably what I’ll look into to see if I can do what I want to do.

I suppose I can achieve what I’m trying to do by having many users login and repeating the same action N # of times and then logging out.

Thanks again!

Sometimes how we phrase something creates artificial limits in our understanding of the problem. Instead of asking “why are you doing that” I will ask, “what is the real-world situation that you are trying to simulate?”

I ask because how to move forward depends a great deal on what you want to do after the login is complete, and whether there will be simultaneous requests or not. Will you ever have two real-world users operating under the same web session at the same time? Or are the “multiple things happening” referring to actions taken once the login is completed?

Part of what I’m trying to achieve is admittedly not much of a possibility in the real-world. In my case, our business requirements force of to have to keep a session to a DMS around in Session state on the server (not awesome, I know, but our hands our tied). Out of the box, the object that is stored isn’t thread-safe, however we built a wrapper around it to make it thread-safe.

I wanted to use Gatling to fire off a ton of requests against that same object to vet that but that only works if it’s the same session.

Again, admittedly, that isn’t a real-world scenario as the closer real-world scenario is every session would have its own object in memory, but since we were using Gatling already for other load testing scenarios I thought I’d give this a stab.

In the real world, if the user opened two tabs to the site and fired off two actions it’d be possible for this to happen I suppose.

I’m very close. I’ve gotten the cookies I need in the before like so:

`
var myCookie = “”
var sessionCookie = “”

before {
val client = new AsyncHttpClient()
val response = client.preparePost(url + “/Login”)
.addFormParam(“Username”, “SomeUser”)
.addFormParam(“Password”, “ThePassword”)
.execute()
.get()

// I’m sure ugly…but I do not know Scala
var cookies = response.getCookies().toList
cookies.foreach(c => {
if(c.getName() == “.MyCookie”) {
myCookie = c.getValue()
}

if(c.getName() == “ASP.NET_SessionId”) {
sessionCookie = c.getValue()
}
})
}
`

However I don’t think it’s working. Here is a gist of what I’m doing:

`
val tryIt =
exec(addCookie(Cookie(“ASP.NET_SessionId”, sessionCookie).withDomain("/")))
exec(addCookie(Cookie(".MyCookie", myCookie).withDomain("/")))
.exec(http(“go-to-main-page”)
.get("/")
.headers(initialPageHeader)
.check(status.is(200))
)
.pause(minWaitMs, maxWaitMs)

.exec( session => {
val time = System.currentTimeMillis
session.set(“timestamp”, time)
})
.exec(
http(“get-job-id”)
.get(jobIdURL + “/${timestamp}”)
.check(status.is(200))
.check(jsonPath("$.jobId").ofType[Int].saveAs(“jobId”))
)

val scn = scenario(baseName)
.during(testTimeSecs) {
exec(tryIt)
}

setUp(scn.inject(atOnceUsers(1))).protocols(httpConf)

`

Though it doesn’t appear to be passing along the cookie that I got in the before {} (because I’m getting bad responses like I have not logged in).

I’m sure I’m holding it wrong; what did I do wrong? I tried watching the traffic using Fiddler, but none of it is showing up :frowning:

Levi

val tryIt =
exec(addCookie(Cookie(“ASP.NET_SessionId”, sessionCookie).withDomain("/")))
.exec(addCookie(Cookie(".MyCookie", myCookie).withDomain("/"))) // <==== YOU FORGOT A LEADING DOT HERE SO IT’S NOT CHAINED
.exec(http(“go-to-main-page”)

Sorry, that was a bad paste error when I did the post. I have that in there as it runs, it just doesn’t work and I can’t see what the submission looks like. Is there a way to dump the requests as it’s doing it to see what is in there?

http://gatling.io/docs/2.0.2/general/configuration.html#logback-xml

Ok, so it appears that for whatever reason when I call addCookie it still has the default values and not the ones that the before {} should’ve set them to (even though they’re correctly printed at the top prior to anything else.

Cookies are: 890A75EDFF9FE446D3440F1C3956104DE3306A1B4EF7C41A9428F69A3CC3B00EFA39B2B5974E3B129C18CE4A8111B58932184FBA4C8D2FE37B2D9B7BEEC47C0DE246F1A08A288BF18 E450F775D9F8FA7F9778859FF6F89E326BD76F875F84330C3649E00EBDA4A2690A6718E518408F2
3no0shixfiisf4s1nqnc0jeq

Are you sure your cookies are returned on the same request? Usually, login process involves a redirect, so are you sure you don’t have one cookie on log in POST, and one from the redirect?

Then note that you should close your client.

Yep, they’re returned in the POST to Login (that’s what I’m dumping out in the before {} block.

If you have the following code:

`
class MyLoadTest extends Simulation {

var myCookie = “”
var sessionCookie = “”

before {
/* stuff to get myCookie and sessionCookie */
}

val theTest =
exec(addCookie(Cookie(".MyCookie", myCookie).withDomain("/")))
.exec(addCookie(Cookie(“ASP.NET_SessionId”, sessionCookie).withDomain("/")))
.exec(http(“initial_page”).get("/").check(status.is(200))
)
.pause(minWaitMs, maxWaitMs)

val scn = scenario(“Test”).during(10) { exec(theTest)}
setUp(scn.inject(atOnceUsers(1))).protocols(httpConf)
}

`

When does Scala evaluate the myCookie parameter in exec(addCookie(Cookie(".MyCookie", myCookie).withDomain("/")))? Because it seems like it evaluates that before the before {} actually runs.

Oh, right!

Then, directly write the before content inside the simulation (ie, in the constructor).

Awesome, works! I’d have tried this before if I actually knew that that was considered the constructor (clearly I know nothing about Scala). Thanks again for your help!