Hi all,
I have build job that calls my gatling simulation file and sets some configuration parameters like ramp duration, peak TPS, and steady state duration. Sometimes the job is kicked off with a ramp duration specified, but other times, ramp duration is zero. I am wondering what the best way is to maintain a single file that can handle both zero and nonzero ramp duration.
In other words, I am trying to do a ramp only if durationRampupInMinutes is specified as non-zero, followed by steady state for durationSteadyStateInMinutes always.
First, here was my original attempt - “if” condition inside a scenario.inject(). But it seems to be skipping over the “if” part, even when ramp time is specified.
setUp(
callChainFlow.inject(
{
if (durationRampupInMinutes != 0) {
rampUsersPerSec(0) to constUsersPerSec during (durationRampupInMinutes minutes)
}
constantUsersPerSec(constUsersPerSec) during (durationSteadyStateInMinutes minutes)
}
)
).protocols(http)
Also tried hard coding if (true) but even that does not trigger.
Second, here is alternate form that works (but is more verbose and has code duplication):
if (durationRampupInMinutes != 0) {
setUp(
callChainFlow.inject(
rampUsersPerSec(0) to constUsersPerSec during (durationRampupInMinutes minutes),
constantUsersPerSec(constUsersPerSec) during (durationSteadyStateInMinutes minutes)
)
).protocols(http)
} else {
setUp(
callChainFlow.inject(
constantUsersPerSec(constUsersPerSec) during (durationSteadyStateInMinutes minutes)
)
).protocols(http)
}
Finally, here what I settled on - a way to simulate zero with a very small value:
// If ramp is zero, set to some value so rampUsersPerSec can pass, but essentially simulate zero.
var nonZeroRampInMinutes = 0.00001
if (durationRampupInMinutes != 0) {
nonZeroRampInMinutes = durationRampupInMinutes
}
setUp(
callChainFlow.inject(
rampUsersPerSec(0) to constUsersPerSec during (nonZeroRampInMinutes minutes),
constantUsersPerSec(constUsersPerSec) during (durationSteadyStateInMinutes minutes)
)
).protocols(http)
Is there a better way?
Did something change between Gatling 2.2.3 and Gatling 3.2.0 in terms of rampUsersPerSec supporting small durations? The third approach above works for me in Gatling 2.2.3. But in Gatling 3.2.0, the same code produces this error:
21:30:47.088 [ERROR] a.a.OneForOneStrategy - Division by zero
java.lang.ArithmeticException: Division by zero
at java.math.BigDecimal.divide(BigDecimal.java:1742)
at scala.math.BigDecimal.$div(BigDecimal.scala:555)
at io.gatling.core.controller.inject.open.RampRateOpenInjection.chain(OpenInjectionStep.scala:200)
at io.gatling.core.controller.inject.open.UserStream$.$anonfun$apply$1(UserStream.scala:31)
at scala.collection.immutable.List.$anonfun$foldRight$1(List.scala:408)
at scala.collection.immutable.List.foldRight(List.scala:89)
at io.gatling.core.controller.inject.open.UserStream$.apply(UserStream.scala:31)
at io.gatling.core.controller.inject.open.OpenInjectionProfile.workload(OpenInjectionProfile.scala:39)
at io.gatling.core.controller.inject.Injector$$anonfun$1.$anonfun$applyOrElse$1(Injector.scala:88)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237)
at scala.collection.immutable.List.foreach(List.scala:392)
at scala.collection.TraversableLike.map(TraversableLike.scala:237)
at scala.collection.TraversableLike.map$(TraversableLike.scala:230)
at scala.collection.immutable.List.map(List.scala:298)
at io.gatling.core.controller.inject.Injector$$anonfun$1.applyOrElse(Injector.scala:89)
at io.gatling.core.controller.inject.Injector$$anonfun$1.applyOrElse(Injector.scala:82)
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:38)
at akka.actor.FSM.processEvent(FSM.scala:707)
at akka.actor.FSM.processEvent$(FSM.scala:704)
at io.gatling.core.controller.inject.InjectorFSM.processEvent(InjectorFSM.scala:37)
at akka.actor.FSM.akka$actor$FSM$$processMsg(FSM.scala:701)
at akka.actor.FSM$$anonfun$receive$1.applyOrElse(FSM.scala:695)
at akka.actor.Actor.aroundReceive(Actor.scala:539)
at akka.actor.Actor.aroundReceive$(Actor.scala:537)
at io.gatling.core.akka.BaseActor.aroundReceive(BaseActor.scala:25)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:612)
at akka.actor.ActorCell.invoke(ActorCell.scala:581)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
at akka.dispatch.Mailbox.run(Mailbox.scala:229)
at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Thanks,
Richard