Gatling Binary generation

FrontLine Gatling Versions

FrontLine actually uses custom versions of the Gatling components. Those binaries are not open sources and their usage is restricted to FrontLine.

When you’ll be deploying tests with FrontLine, it will replace your Gatling OSS dependencies with their custom counterparts.

Configuring Gatling Projects

Maven

In your pom.xml, you have to add in:

  • pull Gatling dependencies
  • add the maven plugin for Scala, so your code gets compiled
  • add the maven plugin for FrontLine, so it can package your code into a deployable artifact
<project>
  <dependencies>
    <dependency>
      <groupId>io.gatling.highcharts</groupId>
      <artifactId>gatling-charts-highcharts</artifactId>
      <version>3.5.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <!-- so maven compiles src/test/scala and not only src/test/java -->
    <testSourceDirectory>src/test/scala</testSourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.2.0</version>
      </plugin>
      <!-- so maven can compile your scala code -->
      <plugin>
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
        <version>4.4.0</version>
        <executions>
          <execution>
            <goals>
              <goal>testCompile</goal>
            </goals>
            <configuration>
              <recompileMode>all</recompileMode>
              <jvmArgs>
                <jvmArg>-Xss100M</jvmArg>
              </jvmArgs>
              <args>
                <arg>-target:jvm-1.8</arg>
                <arg>-deprecation</arg>
                <arg>-feature</arg>
                <arg>-unchecked</arg>
                <arg>-language:implicitConversions</arg>
                <arg>-language:postfixOps</arg>
              </args>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <!-- so maven can build a package for FrontLine -->
      <plugin>
        <groupId>io.gatling.frontline</groupId>
        <artifactId>frontline-maven-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
          <execution>
            <goals>
              <goal>package</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

You can run mvn package -DskipTests in your terminal and check you get a jar containing all the dependencies of the simulation.

You can also exclude dependencies you don’t want to ship, eg:

<plugin>
  <groupId>io.gatling.frontline</groupId>
  <artifactId>frontline-maven-plugin</artifactId>
  <version>1.2.1</version>
  <executions>
    <execution>
      <goals>
        <goal>package</goal>
      </goals>
      <configuration>
        <excludes>
          <exclude>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest_2.13</artifactId>
          </exclude>
        </excludes>
      </configuration>
    </execution>
  </executions>
</plugin>

SBT

In a sbt project, you have to:

  • pull Gatling dependencies
  • add the sbt plugin for FrontLine, so it can package your code into a deployable artifact

A build.sbt file should look like this:

enablePlugins(GatlingPlugin, FrontLinePlugin)

// If you want to package simulations from the 'it' scope instead
// inConfig(IntegrationTest)(_root_.io.gatling.frontline.sbt.FrontLinePlugin.frontlineSettings(IntegrationTest))

scalaVersion := "2.13.4"
scalacOptions := Seq("-encoding", "UTF-8", "-target:jvm-1.8", "-deprecation", "-feature", "-unchecked", "-language:implicitConversions", "-language:postfixOps")

val gatlingVersion = "3.5.1"

libraryDependencies += "io.gatling.highcharts" % "gatling-charts-highcharts" % gatlingVersion % "test"
// only required if you intend to use the gatling-sbt plugin
libraryDependencies += "io.gatling" % "gatling-test-framework" % gatlingVersion % "test"
export SBT_OPTS="-Xss100M"

You will also need the following lines in the project/plugins.sbt file:

// only if you intend to use the gatling-sbt plugin for running Gatling locally
addSbtPlugin("io.gatling" % "gatling-sbt" % "3.2.1")
// so sbt can build a package for FrontLine
addSbtPlugin("io.gatling.frontline" % "sbt-frontline" % "1.3.1")

You can run sbt test:assembly (or sbt it:assembly if you’ve configured the plugin for integration tests) in your terminal and check you get a jar containing all the dependencies of the simulation.

Gradle

In a Gradle project, you have to:

  • pull Gatling dependencies
  • add the gradle plugin for FrontLine, so it can package your code into a deployable artifact

A build.gradle file should look like this:

plugins {
  // The following line allows to load io.gatling.gradle plugin and directly apply it
  id 'io.gatling.frontline.gradle' version '1.3.1'
}

// This is needed to let io.gatling.gradle plugin to loads gatling as a dependency
repositories {
  jcenter()
  mavenCentral()
}

gatling {
  toolVersion = '3.5.1'
}

You can run gradle frontLineJar in your terminal and check you get a jar containing all the dependencies of the simulation.

Multi-Module Support

If your project is a multi-module one, make sure that only the one containing the Gatling Simulations gets configured with the Gatling related plugins describes above.

FrontLine will take care of deploying all available jars so you can have Gatling module depend on the other ones.

Note on Feeders

A typical mistake with Gatling and FrontLine is to rely on having an exploded maven/gradle/sbt project structure and try loading files from the project filesystem.

This filesystem structure will be gone once FrontLine will have compiled your project and uploaded your binaries on the injectors.

If your feeder files are packaged with your test sources, you must resolve them from the classpath. This way will always work, both locally and with FrontLine.

// incorrect
val feeder = csv("src/test/resources/foo.csv")

// correct
val feeder = csv("foo.csv")

Specific Gatling Features

Load Sharding

Injection rates and throttling rates are automatically distributed amongst nodes.

However, Feeders data is not automatically sharded, as it might not be the desired behavior.

If you want data to be unique cluster-wide, you have to explicitly tell Gatling to shard the data, e.g.:

val feeder = csv("foo.csv").shard

Assuming a CSV file contains 1000 entries, and 3 Gatling nodes, the entries will be distributed the following way:

  • First node will access the first 333 entries
  • Second node will access the next 333 entries
  • Third node will access the last 334 entries

Resolving Injector Location in Simulation

When running a distributed test from multiple locations, you could be interested in knowing where a given injector is deployed in order to trigger specific behaviors depending on location.

For example, you might want to hit https://mydomain.co.uk baseUrl if injector is deployed on AWS London, and https://mydomain.com otherwise.

You can resolve in your simulation code the name of the pool a given injector is deployed on:

val poolName = System.getProperty("gatling.frontline.poolName")
val baseUrl = if (poolName == "London") "https://domain.co.uk" else "https://domain.com"

Publishing Fatjars into Binary Repositories

Instead of building tests from sources, you have the option of building binaries upstream and publishing them into a binary repository (JFrog Artifactory, Sonatype Nexus or AWS S3) so FrontLine just has to download them.

Maven

You’ll have to configure either repository or snapshotRepository block whether you want to deploy releases or snapshots.

<distributionManagement>
  <repository>
    <id>your.releases.repository.id</id>
    <url>REPLACE_WITH_YOUR_RELEASES_REPOSITORY_URL</url>
  </repository>
  <snapshotRepository>
    <id>your.snapshots.repository.id</id>
    <url>REPLACE_WITH_YOUR_SNAPSHOTS_REPOSITORY_URL</url>
  </snapshotRepository>
</distributionManagement>

You’ll need frontline-maven-plugin version 1.0.3 at least. Fatjar artifact will be automatically attached to your project and deployed with the shaded classifier.

mvn deploy

Gradle

The main idea is to use the official maven publish plugin and ask it to use the task named frontLineJar, then define a repository:

apply plugin: "maven-publish"

publishing {
  publications {
    mavenJava(MavenPublication) {
      artifact frontLineJar
    }
  }
  repositories {
    maven {
      if (project.version.endsWith("-SNAPSHOT")) {
        url "REPLACE_WITH_YOUR_SNAPSHOTS_REPOSITORY_URL"
      } else {
        url "REPLACE_WITH_YOUR_RELEASES_REPOSITORY_URL"
      }
    }
  }
}

You can deploy the test jar with the following command:

gradle publish

An artifact will be published will the tests classifier.

Sbt

packageBin in Test := (assembly in Test).value
publishArtifact in Test := true
publishTo :=
	(if (isSnapshot.value)
		Some("private repo" at "REPLACE_WITH_YOUR_SNAPSHOTS_REPOSITORY_URL")
	else
		Some("private repo" at "REPLACE_WITH_YOUR_RELEASES_REPOSITORY_URL")
)
sbt test:publish

An artifact will be published will the tests classifier.

Edit this page on GitHub