Search code examples
gatling

How can I create a Gatling simulation that peaks/spikes every hour and returns to normal after 10 minutes?


I am trying to create a test that runs for 10 hours with 100 users. Every hour, i'd like to increase the number of users by 50 for 10 minutes and than go back to 100 users. Note that I am talking about number of users and not TPS.

Since I couldn't find any normal way to do it with once scenario, I thought about the following approach. I create two scenarios and run them simultaneously:

  setUp(scenario1.inject(rampConcurrentUsers(1) to (100) during (10 minutes))
    .protocols(httpconf),
    scenario2.inject(nothingFor(60 minutes), rampUsers(50) during (10 minute)).protocols(httpconf))
    .maxDuration(10 hours))

The problem with this simulation is that the users that start to ramp up from scenario2 never stop, so after an hour I end up with 150 users until the end of the simulation.

Note that Scenario1 and scenario2 are identical apart from simulation name... there must be a better way to achieve this with one scenario or at least make it work with two. Any ideas/help will be highly appreciated!

UPDATE:

As suggested by John, I tried the following code:

 setUp(fastZappingSpeed.inject(nothingFor(1 second),sInjection(1): _*
  ).protocols(httpconf)).maxDuration(6 minutes)

  def sInjection( hours : Int )  = {
    val seq = Seq(rampUsers(10) during (1 minute))
    var i = hours
    while ( i > 0 ) {
      seq  ++ Seq(nothingFor(2 minute)) ++ Seq(rampUsers(10) during (1 minute))
      i -= 1
    }
    seq
  }

However, I did not get the expected behavior:

enter image description here

If I wrote the exact same behavior "manually", I did get the expected result:

  setUp(scenario.inject(
    rampUsers(10) during (1 minute),
    nothingFor(2 minute),
    rampUsers(10) during (1 minute)
  ).protocols(httpconf)).maxDuration(3 minutes)

enter image description here

What am I missing here?


Solution

  • I ended up solving it with a different approach. Instead of injecting users and trying to remove them and them ramp up again, I ramped up all users and used pause time in the scenario.

    Here are the steps I took:

    1. Created to injection scenarios that run in parallel, one is your usual load while the other is your additional users that you would like to use as your spike:

      setUp(scenario.inject(rampConcurrentUsers(1) to (numberOfTestUsers) during (Config.rampUpDuration minutes))
        .protocols(httpconf),
        peakScenario.inject(rampConcurrentUsers(1) to (numberOfPeakTestUsers) during (Config.rampUpDuration minutes))
          .protocols(httpconf))
      
    2. The scenario itself has a parameterised pause time at the beginning, so you can either shoot it with pause or without:

      scenario(name).feed(feed).forever() {
      
            doIf(isPeakDelay) {
              pause(pauseDuration + getRandomPeakDelayInSeconds)
            }
              .exec(api.call1)
              .exec(api.call2)
             ....}
      

      (Note the addition of random time for the pause, you dont want all users to shoot at once)

    To recap, in this solution you will end up having two scenarios running in parallel - one scenario shoots users during the whole duration of the test while the second one initiates all peak users at the beginning of the test but pauses for your configured gap time between peaks.