Search code examples
gatling

End Gatling simulation when scenario fails BUT generate a report


I have code which currently will not run my scenario if it fails;

//Defined outside of the scenario scope
var simulationHealthy = true

//defined within the scenario
.exec((session: io.gatling.core.session.Session) => {
  if (session.status == KO) {
      simulationHealthy = false
  }
    session
  })

However my simulation keeps running until the duration set for the simulation is over, though the scenario will not keep executing.

What I would like to do is to have a scenario fail under conditions I define (similar to assertions) and for the entire simulation to fail at that point as well, and also generate a report.

Thanks

Edit: I am running these tests within the IntelliJ IDE. Ending the simulation programmatically is required.


Solution

  • Thanks to @GeraldMücke 's suggestion of using system.exit I've come up with a work around. Still no where close to ideal but it does the job.

    The problems are

    • Still have to manually generate the report from the log that is created when gatling is run
    • The user has to constantly manage how long the scenario lasts for both items as I don't know a way to have a scenario last the length of a simulation
    • This is obviously a "proof of concept" it has nothing in the code to define failure over thresholds etc like the asserts and checks available in Gatling itself

    Here's the code. I've nested simulations within the setUp function because it fits the criteria of the work I am doing currently, allowing me to run multiple simulations within the main simulation.

    FailOverSimulation and ScenarioFailOver are the classes that need to be added to the list; obviously this only adds value when you are running something that loops within the setUp.

    import java.util.concurrent.atomic.AtomicBoolean
    
    import io.gatling.commons.stats.KO
    import io.gatling.core.Predef._
    import io.gatling.core.scenario.Simulation
    import io.gatling.http.Predef._
    import scala.concurrent.duration._
    
    object ScenarioTest {
      val get = scenario("Test Scenario")
        .exec(http("Test Scenario")
          .get("https://.co.uk/")
        )
        .exec((session: io.gatling.core.session.Session) => {
          if(session.status == KO) {
            ScenarioFailOver.exitFlag.set(true)
          }
          session
        })
    }
    
    object TestSimulation {
      val fullScenario = List(
        ScenarioTest.get.inject(constantUsersPerSec(1).during(10.seconds))
      )
    }
    
    object ScenarioFailOver {
      var exitFlag = new AtomicBoolean(false)
    
      val get = scenario("Fail Over")
        .doIf(session => exitFlag.get()) {
          exec(s => {
            java.lang.System.exit(0)
            s
          })
        }
    }
    
    object FailOverSimulation {
      val fullScenario = List(
        ScenarioFailOver.get.inject(constantUsersPerSec(1).during(10.seconds))
      )
    }
    
    class SimulateTestEnding extends Simulation {
      setUp(
        FailOverSimulation.fullScenario
          ::: TestSimulation.fullScenario
      ).protocols(
      )
    }