Hello! In our company’s technical business processes we have a need to filter simulations which are present in classpath by different custom attributes (annotations with specific values or concrete simulation names in sbt run args, for example).
So, I wrote a code, which scans a classpath, searching for subclasses of io.gatling.core.scenario.Simulation, and then filters it with a predicate, making a subset of simulations of interest.
Okay, now I need any means to launch these simulations one by one, so I wrote another piece of code:
def runMultipleSimulations(): Unit = {
simulations
.filter(simulation => {
val doesCurrentSimulationInArgs = args.contains(simulation.getCanonicalName)
logger.debug(s"Simulation ${simulation.getCanonicalName} is in args? $doesCurrentSimulationInArgs")
doesCurrentSimulationInArgs
})
.foreach(launchSimulation)
}
def launchSimulation(simulation: Class[Simulation]): Unit = {
val props = new GatlingPropertiesBuilder
props.simulationClass(simulation.getCanonicalName)
println(s"##teamcity[testStarted name='${simulation.getSimpleName}']")
Gatling.fromMap(props.build) match {
case 0 => println(s"##teamcity[message text='Simulation is successful' status='NORMAL']")
case 1 => println(s"##teamcity[testIgnored name='${simulation.getSimpleName}' message='Simulation has been ignored because of invalid parameters']")
case 2 => println(s"##teamcity[testFailed name='${simulation.getSimpleName}' message='Simulation has been failed by assertion']")
}
println(s"##teamcity[testFinished name='${simulation.getSimpleName}']")
}
At this point simulations are run sequentially, reports are generated, everything seems OK, but here I happen to observe very strange behavior - first launched simulation has a complete logs in STDOUT (output from io.gatling.core.stats.writer.ConsoleSummary object + output from StrictLogging trait’s logger), but any subsequent ones have only output from ConsoleSummary (progress bar, etc.).
I investigated this case a bit and found something suspicious in io.gatling.app.Gatling private method start():
} finally {
val factory = LoggerFactory.getILoggerFactory
try {
factory.getClass.getMethod("stop").invoke(factory)
} catch {
case _: NoSuchMethodException => //Fail silently if a logging provider other than LogBack is used.
case NonFatal(ex) => logger.warn("Logback failed to shutdown.", ex)
}
}