reusing common requests

Hi All,

I have been evaluating Gatling for a while and I’m impressed with the simplicity and robustness of the tool. I look forward to using Gatling for my workflow pretty soon. I’m thinking about load testing our Restful API which uses JSON.

I have multiple Gatling simulations file to support distinct use cases and I see myself making authentication request for every scenario which is required when for multiple users. For example, lets say I have three scenarios CreateUser, UpdateUser and GetUser. To consume each of these service I need to first authenticate with the API and use the authentication token returned in the header thereafter. Here is the snippet of the code that will help explain the case better.

`
class CreateUser extends Simulation {
val scn = scenario(“CreateUserScenario”)
.exec(http(“Authentication”)
.post(https://myawesomeapi.com/auth)

    .headers(headers1)
    .body(StringBody("""{{"user": "xyz"}, {"pass":"secret"}""")).asJSON
  .check(status.is(201))
 .check(jsonPath("$.token").find.saveAs("mytoken"))
   )
 .pause(1)
 .exec(http("CreateUser")
    .post("[https://myawesomeapi.com/createuser](https://myawesomeapi.com/createuser)")
    .header("token", "${mytoken}")
    .body(StringBody("""{{"user": "xyz"}, {"pass":"secret"}, {"email" : "[user@e](mailto:user@email.com )mail.com"}""")).asJSON
 .check(status.is(200))
 .check(jsonPath("true").find.saveAs("success"))
)
setUp(scn.inject(atOnceUsers(1)).protocols(httpConf))
}

`

`
class UpdateUser extends Simulation {
val scn = scenario(“UpdateUserScenario”)
.exec(http(“Authentication”)
.post(https://myawesomeapi.com/auth)
.headers(headers1)
.body(StringBody("""{{“user”: “xyz”}, {“pass”:“secret”}""")).asJSON
.check(status.is(201))
.check(jsonPath("$.token").find.saveAs(“mytoken”))
)
.pause(1)
.exec(http(“UpdateUser”)
.post(“https://myawesomeapi.com/updateuser/123”)
.header(“token”, “${mytoken}”)
.body(StringBody("""{{“user”: “xyz”}, {“pass”:“newsecret”}, {“email” : “user@email.com”}""")).asJSON
.check(status.is(200))
.check(jsonPath(“true”).find.saveAs(“success”))
)
setUp(scn.inject(atOnceUsers(1)).protocols(httpConf))
}

`


You can see that I have to authenticate before I consume anything else. I’m thinking that there should be a better way to do this and wrap the Authentication portion of the code into a shared package and import/utilize that in the actual scenario. Something like this?

`
import Authentication._

class CreateUser extends Simulation {
val scn = scenario(“CreateUserScenario”)
.exec(DoAuthentication(“some input value here”)) //extract token returned to reuse below
)
.pause(1)
.exec(http(“CreateUser”)
.post(“https://myawesomeapi.com/createuser”)
.header(“token”, “${mytoken}”)
.body(StringBody("""{{“user”: “xyz”}, {“pass”:“secret”}, {“email” : “user@xyzemail.mail”}""")).asJSON
.check(status.is(200))
.check(jsonPath(“true”).find.saveAs(“success”))
)
setUp(scn.inject(atOnceUsers(1)).protocols(httpConf))
}

`

I am new to Scala so apologize for any errors and if this is a simple thing. How do I go about doing this? Is there an example that I can follow? I have searched the forums and haven’t found something similar to this. I plan to use this module not only for authentication but for anything that is common across multiple scripts.

Thank you in advance!

It’s all in the documentation :slight_smile:
http://gatling.io/docs/2.1.2/advanced_tutorial.html

Yes, it’s quite doable. What you have described, I am already doing.

I have a top-level object, called RTDE, which represents the platform.
I declared a file, Login.scala, in which I put all the logic for authentication. There is an object, Login, with a method, “sequence”.
Inside of the RTDE object, I make reference to it, so that RTDE.Login = the Login object.
Net result, my scenario can simply say:

exec( RTDE.Login.sequence )

I took it further. We have more than a dozen services, each with multiple methods. I create one .scala file per service. There is an object defined that represents the service, and a sub-object/property for each method.

Those, in turn, are built by using a generic “service builder” object, which in turn is built on a generic RESTful service object. The RTDE specific RESTful code knows to add the authentication headers. This part was a pain to get right, because the inheritance structure was complicated.

But the end result is, I can write scenarios that look like this:

exec( RTDE.Login.sequence )
.exec( RTDE.ServiceName.method )

Sometimes, my methods take parameters, other times, they just leverage conventional session variables.

If you look through my posts in the forum, you can see where I talked about it, and in some cases shared some of the code. If you get stuck, let me know, I’ll send you a code sample.

Thanks Stéphane. I wish I read the documentation more before thinking about posting this! This gives me good enough info for now to look at.

Very nice. Thanks for the info. I’ll read up and let you know if I have any questions.

hi everyone, I am also new to Gatling, can anyone of you help me with the below requirement :

I want to reuse the code defined in one of the file in two different scala files with different transaction name :

File 1
Header.scala file :

def Authentication() = {
feed(userCredentails)
.exec(http(“EA_T01_authentication”)
.post(“https://abs-prf.oktapreview.com/oauth2/ausdwyebrzlqF3sZQ0h7/v1/token”)

.headers(headers_0_authentication)}

File 2
val Erums_CartExecution = exec(ErumsHeaders.Authentication())

File 3 (Main Scenario file )
.exec(ErumsHeaders.Authentication())

During execution, if file2 is executed then the authentication transaction should come with different name and if file3 is executed then the transaction name should be differnt.

As of now, I am getting “EA_T01_authentication” transaction name in both the case

hi,
pass transaction name as param to the authentication method and use it as Transaction name for http(param1)
Try it … it may work

Then pass the request name as a parameter to your def Authentication() method.

Hi Nalin and Stephane,

Thanks for you reply !!

Can you please more elaborate on this, the way i tried its giving only same request name for both the pages where the function is called.

I want to use it like same module controller and transaction name that we use in jmeter like two different thread groups/Throughput controller can use the same fragment but everytime the transaction name will be different,

The same way I want to use here, created one scala file and have defined authentication as the val, then use same authentication in two different scala file, I want if one scala file is using auth then it should appear with different name respectively.

I am not able to find any way for this, can you please help me here.

Thanks