1
votes

I have a few .csv files I want to use for the same data in Gatling. Each of these files has a certain number of ID's that I want to be accessed fairly equally. I don't want to put them all in the same file because the .csv files are generated from SQL queries and, while I may have a lot of IDs in one file, I only have a few in another. What's important to me is that I have a random sample from each of my files and a way to specify the distribution.

I found an example of how to do this but I'm having trouble applying it in my case. Here is the code I have so far. I try to both 1) print out the value from the feeder in the session and 2) try to use the value from the feeder in a get request. Both attempts fail with various errors which I detail below:

import scala.concurrent.duration._

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

class FeederTest extends Simulation {

  //headers...

  val userCreds = csv("user_creds.csv")

  val sample1 = csv("sample1.csv")

  val sample2 = csv("sample2.csv")

  def randFeed(): String = {
    val foo = Random.nextInt(2)
    var retval = ""
    if (foo == 0) retval = "file1"
    if (foo == 1) retval = "file2"
    return retval
  }

  val scn = scenario("feeder test")
    .repeat(1) {
      feed(userCreds)
        .doSwitch(randFeed)(
          "file1" -> feed(sample1),
          "file2" -> feed(sample2)
        )  
        .exec(http("request - login")
          .post("<URL>")
          .headers(headers_login)
          .formParam("email", "${username}")
          .formParam("password", "<not telling>"))
        .exec(session => {
           println(session)
           println(session("first").as[String])
           session})
        .exec(http("goto_url")
          .get("<my url>/${first}"))

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

This is the error I get when I attempt to printout the feeder value in the session (as in the above code using session(<value>).as[String]):

[ERROR] [03/13/2015 10:22:38.221] [GatlingSystem-akka.actor.default-dispatcher-8] [akka://GatlingSystem/user/sessionHook-2] key not found: first                                                                              
java.util.NoSuchElementException: key not found: first                                                         
        at scala.collection.MapLike$class.default(MapLike.scala:228)                                                    at scala.collection.AbstractMap.default(Map.scala:59)                                                  
        at scala.collection.MapLike$class.apply(MapLike.scala:141)                                             
        at scala.collection.AbstractMap.apply(Map.scala:59)                                                    
        at io.gatling.core.session.SessionAttribute.as(Session.scala:40)                                       
        at FeederTest$$anonfun$2.apply(feeder_test.scala:81)                                                   
        at FeederTest$$anonfun$2.apply(feeder_test.scala:79)                                                   
        at io.gatling.core.action.SessionHook.executeOrFail(SessionHook.scala:35)                              
        at io.gatling.core.action.Failable$class.execute(Actions.scala:71)                                     
        at io.gatling.core.action.SessionHook.execute(SessionHook.scala:28)                                    
        at io.gatling.core.action.Action$$anonfun$receive$1.applyOrElse(Actions.scala:29)                      
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:171)                                 
        at akka.actor.Actor$class.aroundReceive(Actor.scala:465)                                               
        at io.gatling.core.akka.BaseActor.aroundReceive(BaseActor.scala:22)                                    
        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)                                            
        at akka.actor.ActorCell.invoke(ActorCell.scala:487)                                                    
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254)    
        at akka.dispatch.Mailbox.run(Mailbox.scala:221)                                                        
        at akka.dispatch.Mailbox.exec(Mailbox.scala:231)                                                       
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)                                
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)                    
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)                            
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

I have also tried just using the EL expression ${first} in the session. All this does is print out the string ${first}. Similarly in the last .get line I get an error saying "No attribute named 'first' is defined.

The CSV files I'm currently using just have two columns of first and last in them like so:

sample1.csv:
first, last
george, bush
bill, clinton
barak, obama

sample2.csv:
first, last
super, man
aqua, man
bat, man

I'm using Gatling 2.1.4.

2
After correcting the typo, I realized I still had a problem (sorry for the incorrect marking). It appears my problem is that either you can't access the feeder data inside of session or I'm using the wrong syntax for it. When I debug the session output I don't see any of the feeder data there. Is it even possible to do what I'm trying to do by printing this in the session? - Alan Baird
I've never used feeders, but from the documentation, I see two possible problems - 1. randFeed returns either "foo" or "bar" but you're mapping with "file1" and "file2", so is anything being loaded? 2. The examples for feeders I see don't show accessing fed data with session(varname) but rather "${varname}". - childofsoong
The "foo", "bar" in randFeed was a cut paste mistake which I have fixed. As for using "${varname}", whenever I use that, it just prints out ${first}. I don't believe you can use EL expressions inside session - I may be wrong. - Alan Baird

2 Answers

2
votes

doSwitch takes an Expression[Any], which is a type alias for Session => Validation[Any]. Gatling has an implicit conversion that let you pass a static value instead, see documentation.

Which is exactly what you do. Even if randFeed is a def, it still doesn't return a function, but a String.

As you want randFeed to be called every time a virtual user pass through this step, you have to wrap the randFeed inside a function, even if you don't use the Session input parameter.

doSwitch(_ => randFeed)

Then, your randFeed is both ugly (no offense) and inefficient (Random is synchronized):

import scala.concurrent.forkjoin.ThreadLocalRandom
def randFeed(): String =
  ThreadLocalRandom.current().nextInt(2) match {
    case 0 => "file1"
    case 1 => "file2"
  }
2
votes

I've never used feeders, but from the documentation, I see two possible problems:

  1. randFeed returns either "foo" or "bar" but you're mapping with "file1" and "file2", so is anything being loaded? (The documentation says "If no switch is selected, the switch is bypassed.")
  2. The examples for feeders I see don't show accessing fed data with session(varname) but rather "${varname}".