在Gatling中创建一个加权进纸器

时间:2015-03-13 04:13:42

标签: scala gatling

我想要在Gatling中使用相同数据的几个.csv文件。这些文件中的每一个都有一定数量的ID,我希望它们能够被公平地访问。我不想将它们全部放在同一个文件中,因为.csv文件是从SQL查询生成的,虽然我可能在一个文件中有很多ID,但我只有一些在另一个文件中。对我来说重要的是我从每个文件中随机抽取样本并指定分发方式。

我找到an example如何做到这一点,但我在我的案例中应用它时遇到了麻烦。这是我到目前为止的代码。我尝试两者1)在会话中打印出馈线的值,2)尝试在get请求中使用馈线的值。两次尝试均因各种错误而失败,我将在下面详述:

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)
}

这是我尝试在会话中打印出馈送器值时出现的错误(如上面的代码中使用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)

我也试过在会话中使用EL表达式${first}。所有这一切都打印出字符串${first}。类似地,在上一行.get行中,我收到错误消息“未定义名为'first'的属性。

我目前使用的CSV文件只有两列第一列和最后一列,如下所示:

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

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

我正在使用Gatling 2.1.4。

2 个答案:

答案 0 :(得分:2)

我从未使用过馈线,但从文档中我发现了两个可能的问题:

  1. randFeed返回&#34; foo&#34;或&#34; bar&#34;但是你要用&#34; file1&#34;和&#34; file2&#34;,还有什么东西被加载? (documentation说&#34;如果没有选择开关,则绕过开关。&#34;)
  2. examples for feeders我看到请勿显示使用session(varname)而非"${varname}"访问Feed数据。

答案 1 :(得分:2)

doSwitch需要Expression[Any],这是Session => Validation[Any]的类型别名。 Gatling有一个隐式转换,允许您传递静态值,请参阅documentation

这正是你做的。即使randFeed是def,它仍然不返回函数,而是返回String。

由于您希望每次虚拟用户通过此步骤时都调用randFeed,您必须将randFeed包装在函数内,即使您不使用Session输入参数。

doSwitch(_ => randFeed)

然后,你的randFeed既丑陋又没有冒犯,效率低下(随机同步):

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