Last active
June 25, 2020 08:38
-
-
Save imavroukakis/99289df78baa7f27e93af8d5e5fca0d4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enablePlugins(PackPlugin) | |
organization := "dev.to" | |
name := "gatling-scale-out" | |
version := "1.0" | |
scalaVersion := "2.12.10" | |
val gatlingVersion = "3.3.1" | |
resolvers += Resolver.sonatypeRepo("releases") | |
resolvers += Resolver.jcenterRepo | |
libraryDependencies ++= Seq( | |
"io.gatling" % "gatling-app" % gatlingVersion, | |
"io.gatling.highcharts" % "gatling-charts-highcharts" % gatlingVersion exclude("io.gatling", "gatling-recorder"), | |
"org.rogach" %% "scallop" % "3.4.0", | |
) | |
packMain := Map("load-test" -> "dev.to.gatling.GatlingRunner") | |
packJvmOpts := Map("load-test" -> Seq("-Xms2G -Xmx2G -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:MaxGCPauseMillis=30 -XX:G1HeapRegionSize=16m -XX:InitiatingHeapOccupancyPercent=75 -XX:+ParallelRefProcEnabled -XX:+PerfDisableSharedMem -XX:+OptimizeStringConcat -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false")) | |
Compile / run / fork := true | |
javaOptions ++= { | |
val props = sys.props.toList | |
props.map { | |
case (key, value) => s"-D$key=$value" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dev.to.gatling | |
import java.text.SimpleDateFormat | |
import java.util.Calendar | |
import io.gatling.app.Gatling | |
import io.gatling.core.config.GatlingPropertiesBuilder | |
import org.rogach.scallop.{ScallopConf, ScallopOption} | |
class Conf(arguments: Seq[String]) extends ScallopConf(arguments) { | |
val usersPerSecond: ScallopOption[Int] = opt[Int](default = Some(5)) | |
val reportOnly: ScallopOption[String] = opt[String]() | |
val testDuration: ScallopOption[String] = opt[String](default = Some("60_seconds")) | |
verify() | |
} | |
object GatlingRunner { | |
var conf: Option[Conf] = None | |
def main(args: Array[String]) { | |
conf = Some(new Conf(args)) | |
conf match { | |
case Some(conf) => { | |
val simClass = classOf[LoadSimulation].getName | |
val props = new GatlingPropertiesBuilder | |
props.simulationClass(simClass) | |
props.runDescription("Gatling Load Test") | |
if (conf.reportOnly.isDefined) { | |
props.reportsOnly(conf.reportOnly()) | |
} else { | |
val now = Calendar.getInstance().getTime | |
val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH_mm_ss") | |
props.resultsDirectory(s"results/${dateFormat.format(now)}") | |
} | |
Gatling.fromMap(props.build) | |
} | |
case None => throw new IllegalArgumentException | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def gitUrl = 'https://github.com/your_repo/gatling-scale-out' | |
def gitCredentials = 'Github' | |
def testGroups = [:] | |
def numberOfTestNodes = 5 | |
def splitTestsAbove = 50.0 | |
def jdkTool = 'openjdk-11' | |
def sbtTool = '1.3.8' | |
pipeline { | |
agent any | |
tools { | |
jdk jdkTool | |
} | |
environment { | |
SBT_HOME = tool name: sbtTool, type: 'org.jvnet.hudson.plugins.SbtPluginBuilder$SbtInstallation' | |
PATH = "${env.SBT_HOME}/bin:${env.PATH}" | |
} | |
parameters { | |
choice(choices: ['5', '10', '15', '20', '30', '40', '50', '60', '70', '80', '90', '100'], description: 'The amount of users per second to generate', name: 'usersPerSecond') | |
choice(choices: ['1_minute', '2_minutes', '5_minutes', '10_minutes', '15_minutes', '20_minutes'], description: 'The amount of time to run the simulation for', name: 'duration') | |
} | |
stages { | |
stage('Checkout') { | |
steps { | |
deleteDir() | |
git branch: 'main', credentialsId: "$gitCredentials", poll: false, url: "$gitUrl" | |
} | |
} | |
stage('Build') { | |
steps { | |
sh "sbt clean compile packArchiveTgz" | |
stash name: 'load-test', includes: 'target/gatling-scale-out-1.0.tar.gz' | |
} | |
} | |
stage('Load Test') { | |
steps { | |
script { | |
currentBuild.description = "Users/sec:${params.usersPerSecond}/Duration:${params.duration}" | |
def userPerSecond = "${params.usersPerSecond}" as Double | |
int usersPerNodeCount | |
if (userPerSecond >= splitTestsAbove) { | |
usersPerNodeCount = Math.round(userPerSecond / numberOfTestNodes) | |
} else { | |
usersPerNodeCount = userPerSecond | |
numberOfTestNodes = 1 | |
} | |
for (int i = 0; i < numberOfTestNodes; i++) { | |
def num = i | |
testGroups["node $num"] = { | |
node { | |
def javaHome = tool name: jdkTool | |
deleteDir() | |
unstash 'load-test' | |
sh 'mv target/gatling-scale-out-1.0.tar.gz ./' | |
sh 'tar xf gatling-scale-out-1.0.tar.gz' | |
sh "JAVA_HOME=$javaHome gatling-scale-out-1.0/bin/load-test --users-per-second=$usersPerNodeCount --test-duration=${params.duration}" | |
stash name: "node $num", includes: '**/simulation.log' | |
} | |
} | |
} | |
parallel testGroups | |
} | |
} | |
} | |
stage('Collect results') { | |
steps { | |
script { | |
for (int i = 0; i < numberOfTestNodes; i++) { | |
def num = i | |
unstash "node $i" | |
} | |
} | |
sh 'mv target/gatling-scale-out-1.0.tar.gz ./' | |
sh 'tar xf gatling-scale-out-1.0.tar.gz' | |
sh "gatling-scale-out-1.0/bin/load-test --report-only \"${env.WORKSPACE}/results\"" | |
sh "mv results results-test-${env.BUILD_NUMBER}" | |
sh "tar zcf results-test-${env.BUILD_NUMBER}.tar.gz results-test-${env.BUILD_NUMBER}" | |
archiveArtifacts artifacts: "results-test-${env.BUILD_NUMBER}.tar.gz", caseSensitive: false, onlyIfSuccessful: true | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dev.to.gatling | |
import com.typesafe.scalalogging.StrictLogging | |
import io.gatling.core.Predef._ | |
import io.gatling.core.scenario.Simulation | |
import io.gatling.http.Predef._ | |
import scala.concurrent.duration._ | |
import scala.language.postfixOps | |
import scala.util.{Failure, Success, Try} | |
class LoadSimulation extends Simulation with StrictLogging { | |
GatlingRunner.conf match { | |
case Some(conf) => { | |
val duration: FiniteDuration = Try(Duration(conf.testDuration().replace('_', ' '))) match { | |
case Success(duration) => duration.asInstanceOf[FiniteDuration] | |
case Failure(exception) => throw exception | |
} | |
val usersPerSecond = conf.usersPerSecond().toDouble | |
val postsScenario = | |
scenario("Posts") | |
.exec(http("Get 100 posts").get("http://jsonplaceholder.typicode.com/todos")) | |
setUp( | |
postsScenario.inject( | |
constantUsersPerSec(usersPerSecond) during duration | |
).protocols(http) | |
) | |
} | |
case None => throw new IllegalStateException | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment