Gatling – 基于配置的动态场景、注入配置和断言创建

huangapple go评论49阅读模式
英文:

Gatling - Dynamic Scenario, InjectionProfile, Assertion creation based on Configuration

问题

我正试图编写一个模拟程序,它可以从配置文件中读取一组具有一组属性的API。以下是您提供的代码的翻译部分:

  // 从配置文件获取活动场景
  val activeApiScenarios: List[String] = Utils.getStringListProperty("my.active_scenarios")

  // 从配置文件构建所有活动场景
  var activeScenarios: Set[CommonScenario] = Set[CommonScenario]()
  activeApiScenarios.foreach { scenario =>
    activeScenarios += CommonScenarioBuilder()
      .withRequestName(Utils.getProperty("my." + scenario + ".request_name"))
      .withRegion(Utils.getProperty("my." + scenario + ".region"))
      .withConstQps(Utils.getDoubleProperty("my." + scenario + ".const_qps"))
      .withStartQps(Utils.getDoubleListProperty("my." + scenario + ".toth_qps").head)
      .withPeakQps(Utils.getDoubleListProperty("my." + scenario + ".toth_qps")(1))
      .withEndQps(Utils.getDoubleListProperty("my." + scenario + ".toth_qps")(2))
      .withFeeder(Utils.getProperty("my." + scenario + ".feeder"))
      .withAssertionP99(Utils.getDoubleProperty("my." + scenario + ".p99_lte_assertion"))
      .build
  }

  // 通过添加注入配置值构建人口生成器集合
  var injectScenarios: Set[PopulationBuilder] = Set[PopulationBuilder]()
  var assertions : Set[Assertion] = Set[Assertion]()

  activeScenarios.foreach { scenario =>
    // 从CommonScenarios创建注入配置
    injectScenarios += scenario.getCommonScenarioBuilder
      .inject(nothingFor(5 seconds),
        rampUsersPerSec(scenario.startQps).to(scenario.rampUpQps).during(rampOne seconds),
        rampUsersPerSec(scenario.rampUpQps).to(scenario.peakQps).during(rampTwo seconds),
        rampUsersPerSec(scenario.peakQps).to(scenario.rampDownQps) during (rampTwo seconds),
        rampUsersPerSec(scenario.rampDownQps).to(scenario.endQps).during(rampOne     seconds)).protocols(httpProtocol)

    // 创建场景断言,但是存在问题
    assertions += Assertion(Details(List(scenario.requestName)), TimeTarget(ResponseTime, Percentiles(4)), Lte(scenario.assertionP99))
  }

  setUp(injectScenarios.toList)
    .assertions(assertions)

注意,您的代码中有一些HTML转义字符(例如"),在实际代码中应该是双引号"。此外,您的代码似乎在模拟测试方面有一些问题,可能需要进行一些调试和修复。希望这个翻译有助于您更好地理解您的代码。

英文:

I am attempting to write a simulation that can read from a config file for a set of apis that each have a set of properties.

  • I read the config for n active scenarios and create requests from a CommonRequest class
  • Then those requests are built into scenarios from a CommonScenario
  • CommonScenarios have attributes that are using to create their injection profiles

That all seems to work no issue. But when I try to use the properties / CommonScenario request to build a set of Assertions it does not work as expected.

  // get active scenarios from the config
val activeApiScenarios: List[String] = Utils.getStringListProperty("my.active_scenarios")
// build all active scenarios from config
var activeScenarios: Set[CommonScenario] = Set[CommonScenario]()
activeApiScenarios.foreach { scenario =>
activeScenarios += CommonScenarioBuilder()
.withRequestName(Utils.getProperty("my." + scenario + ".request_name"))
.withRegion(Utils.getProperty("my." + scenario + ".region"))
.withConstQps(Utils.getDoubleProperty("my." + scenario + ".const_qps"))
.withStartQps(Utils.getDoubleListProperty("my." + scenario + ".toth_qps").head)
.withPeakQps(Utils.getDoubleListProperty("my." + scenario + ".toth_qps")(1))
.withEndQps(Utils.getDoubleListProperty("my." + scenario + ".toth_qps")(2))
.withFeeder(Utils.getProperty("my." + scenario + ".feeder"))
.withAssertionP99(Utils.getDoubleProperty("my." + scenario + ".p99_lte_assertion"))
.build
}
// build population builder set by adding inject profile values to scenarios
var injectScenarios: Set[PopulationBuilder] = Set[PopulationBuilder]()
var assertions : Set[Assertion] = Set[Assertion]()
activeScenarios.foreach { scenario =>
// create injection profiles from CommonScenarios
injectScenarios += scenario.getCommonScenarioBuilder
.inject(nothingFor(5 seconds),
rampUsersPerSec(scenario.startQps).to(scenario.rampUpQps).during(rampOne seconds),
rampUsersPerSec(scenario.rampUpQps).to(scenario.peakQps).during(rampTwo seconds),
rampUsersPerSec(scenario.peakQps).to(scenario.rampDownQps) during (rampTwo seconds),
rampUsersPerSec(scenario.rampDownQps).to(scenario.endQps).during(rampOne     seconds)).protocols(httpProtocol)
// create scenario assertions this does not work for some reason
assertions += Assertion(Details(List(scenario.requestName)), TimeTarget(ResponseTime, Percentiles(4)), Lte(scenario.assertionP99))
}
setUp(injectScenarios.toList)
.assertions(assertions)

Note scenario.requestName is straight from the build scenario

    .feed(feederBuilder)
.exec(commonRequest)

I would expect the Assertions get built from their scenarios into an iterable and pass into setUp().

What I get:

When I print out everything the scenarios, injects all look good but then I print my "assertions" and get 4 assertions for the same scenario name with 4 different Lte() values. This is generalized but I configured 12 apis all with different names and Lte() values, etc.

Details(List(Request Name)) - TimeTarget(ResponseTime,Percentiles(4.0)) - Lte(500.0)
Details(List(Request Name)) - TimeTarget(ResponseTime,Percentiles(4.0)) - Lte(1500.0)
Details(List(Request Name)) - TimeTarget(ResponseTime,Percentiles(4.0)) - Lte(1000.0)
Details(List(Request Name)) - TimeTarget(ResponseTime,Percentiles(4.0)) - Lte(2000.0)

After the simulation the assertions all run like normal:

Request Name: 4th percentile of response time is less than or equal to 500.0 : false
Request Name: 4th percentile of response time is less than or equal to 1500.0 : false
Request Name: 4th percentile of response time is less than or equal to 1000.0 : false
Request Name: 4th percentile of response time is less than or equal to 2000.0 : false

Not sure what I am doing wrong when building my assertions. Is this even a valid approach? I wanted to ask for help before I abandon this for a different approach.

答案1

得分: 0

免责声明:Gatling的创建者在这里。

应该可以工作。

然后,有几件事情我非常不喜欢。

assertions += Assertion(Details(List(scenario.requestName)), TimeTarget(ResponseTime, Percentiles(4)), Lte(scenario.assertionP99))

你不应该在这里使用内部AST。你应该像你对注入配置文件所做的那样使用DSL。

var assertions: Set[Assertion] = SetAssertion
;
activeScenarios.foreach { scenario =>

你应该在activeScenarios上使用map(类似于Java的Stream API),而不是使用可变的累加器。

val activeScenarios = activeApiScenarios.map(???)
val injectScenarios = activeScenarios.map(???)
val assertions = activeScenarios.map(???)

另外,由于你似乎不熟悉Scala,也许应该考虑切换到Java(支持超过1年)。

英文:

Disclaimer: Gatling creator here.

It should work.

Then, there are several things I'm super not found of.

> assertions += Assertion(Details(List(scenario.requestName)), TimeTarget(ResponseTime, Percentiles(4)), Lte(scenario.assertionP99))

You shouldn't be using the internal AST here. You should use the DSL like you've done for the injection profile.

> var assertions : Set[Assertion] = SetAssertion
>
> activeScenarios.foreach { scenario =>

You should use map on activeScenarios (similar to Java's Stream API), not use a mutable accumulator.

val activeScenarios = activeApiScenarios.map(???)
val injectScenarios = activeScenarios.map(???)
val assertions = activeScenarios.map(???)

Also, as you seem to not be familiar with Scala, you should maybe switch to Java (supported for more than 1 year).

huangapple
  • 本文由 发表于 2023年2月10日 05:32:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404620.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定