简体   繁体   English

为什么此加特林作业无法按顺序运行?

[英]Why is this Gatling job not running sequentially?

What I am trying to do is: 我正在尝试做的是:

  1. Make a GET call to get a list of id 进行GET调用以获取id列表
  2. For all those ids make a series of another GET calls 对于所有这些ID,请进行一系列其他GET调用

Here is my code for that: 这是我的代码:

/** * Created by pbane3 on 11/10/16. / ** *由pbane3在16/10/10上创建。 */ * /

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import scala.concurrent.forkjoin.ThreadLocalRandom
import scala.collection.mutable
import scala.collection.Map


class RunWithMePerfTest extends Simulation {

  var idList  = List[String]()

  var count = 0;

  def idFeeder(idString:String):Unit = {
    idList = idString.split(",").map(_.trim).toList;
    println(idList)
  }

  def getRunId() : String = {
     println(count)
     var id = idList(count);
     count = count+1;
     return id;
  }

  object GetAllRunDetails {

    val getAllRunDetails = exec(http("Get Run Ids")
      .get("**/**")
      .check(status in (200 to 209))
      // .check(bodyString.saveAs("GetResponse"))
      .check(jsonPath("$..id").ofType[String].findAll.transform(_.mkString(",")).saveAs("runId")))
      .exec(
        session => {
          var getJson = session.get("GetResponse").asOption[String];
          var runId = session.get("runId").asOption[String]
        //  println("Run ID === ")
        //  println(runId.get)
          idFeeder(runId.get)
          session
        }
      )
  }

  object GetRunIdDetails{

    println("Length=" + idList.length)
    val getRunIdDetails = repeat(idList.length) {

      exec(http("Getting Run Details")
        .get(s"****/***" + getRunId())
        .check(status in (200 to 209))
        .check(bodyString.saveAs("GetRunIdResponse"))
      )
        .exec(
          session => {
            var getResponse = session.get("GetRunIdResponse").asOption[String];
            println("Response from Get" + getResponse.get)
            session
          }
        )

    }
  }

  val scn = scenario("All run details")
    .exec(GetAllRunDetails.getAllRunDetails, GetRunIdDetails.getRunIdDetails)

  setUp(scn.inject(atOnceUsers(1)));

}

But here why is GetAllRunDetails.getAllRunDetails not running before GetRunIdDetails.getRunIdDetails ? 但是,为什么在GetAllRunDetails.getAllRunDetails之前没有运行GetRunIdDetails.getRunIdDetails That is my idList is never getting defined. 那是我的idList从未定义。

The error that I am getting is this: 我得到的错误是这样的:

Length=0
0
Exception in thread "main" java.lang.IndexOutOfBoundsException: 0
    at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:65)
    at scala.collection.immutable.List.apply(List.scala:84)
    at nike.runwithme.performance.RunWithMePerfTest.getRunId(RunWithMePerfTest.scala:27)
    at nike.runwithme.performance.RunWithMePerfTest$GetRunIdDetails$.<init>(RunWithMePerfTest.scala:57)
    at nike.runwithme.performance.RunWithMePerfTest.GetRunIdDetails$lzycompute(RunWithMePerfTest.scala:51)
    at nike.runwithme.performance.RunWithMePerfTest.GetRunIdDetails(RunWithMePerfTest.scala:51)
    at nike.runwithme.performance.RunWithMePerfTest.<init>(RunWithMePerfTest.scala:73)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at io.gatling.app.Gatling$.io$gatling$app$Gatling$$$anonfun$1(Gatling.scala:41)
    at io.gatling.app.Gatling$lambda$1.apply(Gatling.scala:41)
    at io.gatling.app.Gatling$lambda$1.apply(Gatling.scala:41)
    at io.gatling.app.Gatling.run(Gatling.scala:92)
    at io.gatling.app.Gatling.runIfNecessary(Gatling.scala:75)
    at io.gatling.app.Gatling.start(Gatling.scala:65)
    at io.gatling.app.Gatling$.start(Gatling.scala:57)
    at io.gatling.app.Gatling$.fromArgs(Gatling.scala:49)
    at io.gatling.app.Gatling$.main(Gatling.scala:43)
    at io.gatling.app.Gatling.main(Gatling.scala)

So here is the answer that worked for me. 所以这是对我有用的答案。 Almost same code, but added a session to the second scenario. 几乎相同的代码,但是在第二种情况下增加了session Makes sense, because everything is added to the session : 很有道理,因为所有内容都添加到了session

/**
  * Created by pbane3 on 11/10/16.
  *
  * The First test gets the Run Id's
  *
  * Then it creates a a List of all the RunIDs
  *
  * After that loops through each of the RunIDs
  * and makes a GET call for each of them
  */

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import scala.concurrent.forkjoin.ThreadLocalRandom
import scala.collection.mutable
import scala.collection.Map
import java.io.File
import java.io.PrintWriter



class RunWithMePerfTest extends Simulation {

  //this is used to store the list of the runIds
  var idList  = List[String]()

  var count = 0;

  //used to build the list and feed to the session
  def idFeeder(idString:String):Unit = {
    idList = idString.split(",").map(_.trim).toList;
    println(idList)
  }

  //used to access the list and feed to the session
  def getRunId() : String = {
     println(count)
     var id = idList(count);
     count = count+1;
     return id;
  }

  //makes the initial call to get all the run IDs
  object GetAllRunDetails {
    println("I come in scn1")
    val getAllRunDetails = exec(http("Get Run Ids")
      .get("https://someUrl")
      .check(status in (200 to 209))
      // .check(bodyString.saveAs("GetResponse"))
      .check(jsonPath("$..id").ofType[String].findAll.transform(_.mkString(",")).saveAs("runId")))
      .exec(
        session => {
          var getJson = session.get("GetResponse").asOption[String];
          var runId = session.get("runId").asOption[String]

          idFeeder(runId.get)
          session
        }
      )
  }

  //makes one get call for each of the run ids obtained from the last get call
  object GetRunIdDetails{
    val getRunIdDetails =  repeat(session=>idList.length) {
      exec(http("Getting Run Details")
        .get(session => (s"https://someUrl" + getRunId()))
        .check(status in (200 to 209))
        .check(bodyString.saveAs("GetRunIdResponse"))
      )
        .exec(
          session => {
            var getResponse = session.get("GetRunIdResponse").asOption[String];
            println("Response from Get:")
            println(getResponse.get)
            session
          }
        )
    }
  }

  val scn1 = scenario("All run details")
    .exec(GetAllRunDetails.getAllRunDetails)

  val scn2 = scenario("All run ID Details")
    .exec(GetRunIdDetails.getRunIdDetails)


  setUp(scn1.inject(atOnceUsers(1)),scn2.inject(nothingFor(10 seconds),atOnceUsers(1)));

}

You can chain your scenarios to run sequentially. 您可以链接方案以按顺序运行。 Try creating two scenarios and then chain them eg. 尝试创建两个方案,然后将它们链接起来。

scn1 = scenario("Get All run details")
    .exec(GetAllRunDetails.getAllRunDetails)

scn2 = scenario("bla").exec(GetRunIdDetails.getRunIdDetails)

seqScenario = scn1.exec(scn2)

Adding to the answer: exec gets initialized before your run. 添加到答案:exec在运行前被初始化。 At that time since you are calling the .get(s"****/***" + getRunId()) method, there'e no data in idList yet, and so your run fails even before it starts. 那时,由于您正在调用.get(s“ **** / ***” + getRunId())方法,因此idList中还没有数据,因此您的运行甚至在启动之前就失败了。 You can add another exec which puts the data in session before you can use it in your get call. 您可以添加另一个exec,以便将数据放入会话中,然后才能在get调用中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM