CSV Feeder and looping

Hi All,

I’m a newbie. I could use some help in looping with csv feeder.

I have 2 data files:

  • user.csv (1st column: email; 2nd column: password)
  • isbn.csv (1st column: isbn)
  • There 20 users, each entitled with 5 unique isbn. Load test requires 100 simulations.

What I did is to put this in the (csv) data files: 100 lines, emails and passwords are replicated 5 times (user.csv), but only one ISBN per line (isbn.csv).

email,password
turbano@yopmail.org,password123
turbano@yopmail.org,password123
turbano@yopmail.org,password123
turbano@yopmail.org,password123
turbano@yopmail.org,password123
jsl100@yopmail.org,password123
jsl100@yopmail.org,password123
jsl100@yopmail.org,password123
jsl100@yopmail.org,password123
jsl100@yopmail.org,password123
rguerrero@yopmail.org,password123
rguerrero@yopmail.org,password123
rguerrero@yopmail.org,password123
rguerrero@yopmail.org,password123
rguerrero@yopmail.org,password123…and so on

Here’s the scenario:

  1. Login
  2. Search ISBN
  3. Logout

What I need to do:
The idea is, since every user is entitled with 5 isbn, the simulation should be like this:

  1. the first user must LOGIN and then
  2. SEARCH ISBN (5 times, same user, with 5 different isbn numbers) and then
  3. LOGOUT.

Technically, there should be a loop for the whole simulation (Login-Logout) and another loop for Search_ISBN only.

I was able to create a script that works fine when it comes to feeder, but I am having a hard time with the looping.

Please help. Thanks in advance.

By the way, here’s the script:

package test_performance_test

import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._

class TestLoadTest extends Simulation {
val scn = scenario(“TestLoadTest”)

val userCredentials = csv(“user.csv”).queue
val isbnFeeder = csv(“isbn.csv”).queue

// LOGIN

.feed(userCredentials)
.exec(http(“EnterCredentials”)
.post(uri1 + “/login.do”)
.headers(headers_2)
.formParam(“location”, " ")
.formParam(“email”, “${email}”)
.formParam(“password”, “${password}”))
.pause(13)

// SEARCH ISBN
.feed(isbnFeeder)
.exec(http(“SearchISBN”)
.post("/nams/nams_search.do")
.headers(headers_2)
.formParam(“searchWord”, “${isbn}”)
.formParam(“quickSearch”, “search”)
.formParam(“rdosearch”, “nams_search_titlelist”))
.pause(9)

// LOGOUT

val log_out = exec(http(“Logout”)
.get("/nams/logout.do")
.headers(headers_0))
.pause(1)
.exec(http(“NavigateHomepage”)
.get(uri1 + “/ListApplications.do”)
.headers(headers_2))
}

setUp(scn.inject(atOnceUsers(100))).protocols(httpProtocol)
}

Looking at this, it doesn’t look like you understand how Gatling DSL works.

You can’t put a variable declaration in the middle of your scenario definition. .exec(…) is a method call on the return value of the previous operation. You are calling ‘.feed()’ on your val isbnFeeder. Clearly, not what you want. Remember, as you step through the code, you are not executing the scenario, you are building an object that encapsulates the intended behavior. It doesn’t actually run until later. That is the difference between build-time and run-time.

First step for you will be to wrap your head around the DSL. It has some constraints. Once you understand those constraints, maybe your question will be answered?

Hi John,

You can’t put a variable declaration in the middle of your scenario definition. .exec(…) is a method call on the return value of the previous operation.

My bad. That was supposed to be a declaration for an object. Initially I separated the processes by splitting them as objects then I decided not to do it. I just forgot to delete it.

You are calling ‘.feed()’ on your val isbnFeeder. Clearly, not what you want. Remember, as you step through the code, you are not executing the scenario, you are building an object that encapsulates the intended behavior. It doesn’t actually run until later. That is the difference between build-time and run-time.

I have no issue when it comes to feeders. Feeders work as expected. My problem is how to make my looping work. Here’s a part of my script:

val userIdFeeder = Iterator.from(0).map(i => Map(“userId” → i))
val iterations = 1;

val scn = scenario(“SampleTest”)

// LOGIN

.repeat(iterations, “index”){
feed(userIdFeeder)
exec(session => {
val userIdFeeder = session(“userIdFeeder”).as[Int]
val index = session(“index”).as[Int]
val email = iterations * userIdFeeder + index
session.set(“email”, email)
})

.exec(http(“NavigateIntranet”)
.get(uri1 + “/ListApplications.do”)
.headers(headers_0))
//.pause(13)

.feed(userCredentials)
.exec(http(“EnterCredentials”)
.post(uri1 + “/login.do”)
.headers(headers_2)
.formParam(“location”, " ")
.formParam(“email”, “${email}”)
.formParam(“password”, “${password}”))
//.pause(13)

// SEARCH ISBN

.repeat(5){
feed(isbnFeeder)
.exec(http(“SearchISBN”)
.post(“/nams/nams_search.do”)
.headers(headers_2)
.formParam(“searchWord”, “${isbn}”)
.formParam(“quickSearch”, “search”)
.formParam(“rdosearch”, “nams_search_titlelist”))
//.pause(9)
}

// LOGOUT

.exec(http(“Logout”)
.get(“/nams/logout.do”)
.headers(headers_0))
//.pause(1)

.exec(http(“NavigateHomepage”)
.get(uri1 + “/ListApplications.do”)
.headers(headers_2))
}

The isbn part works as expected. It iterates 5 times per user. But in the user’s part, loop works but only the first value in the feeder is being extracted.

There’s a missing dot to chain the feed and exec in the login loop.

Hi Stephane,

There’s a missing dot to chain the feed and exec in the login loop.

Noted. But is it not right that they do not have dots since they are the first line after { ? When I add the dots, error occurs.

Hi Kurt,

Nope, your simulation only misses the dot Stéphane referred to, because you’re chaining feed then exec.
If you add a dot after {, it’s actually a syntax error.

Cheers,

Pierre