Build executable JAR for Gatling load test

后端 未结 6 1130
感动是毒
感动是毒 2020-12-30 02:01

I am new to Gatling (2.1.2) and want to do a small prototype project to show to my colleagues.

According to the quick start page, there are several ways I can run a

相关标签:
6条回答
  • 2020-12-30 02:40

    I use IntelliJ Idea and I got this fixed by right clicking on the scala folder > Mark Directory as > Test Sources Root . Now Execute "Engine" and you will be all good !

    0 讨论(0)
  • 2020-12-30 02:42

    I've recently blogged about this Creating a versionable, self-contained (fat-/uber-) JAR for Gatling tests, the source of which can be found in jamietanna/fat-gatling-jar.

    For a Maven project, the steps would be as follows.

    The main things you need are to add the dependency on gatling-charts-highcharts:

    <project>
        <!-- ... -->
        <dependencies>
            <dependency>
                <groupId>io.gatling.highcharts</groupId>
                <artifactId>gatling-charts-highcharts</artifactId>
                <version>${gatling.version}</version>
            </dependency>
        </dependencies>
    </project>
    

    Next, you need to make sure your Gatling scenarios/simulations are in src/main instead of src/test.

    Finally, you can use the maven-shade-plugin to build an executable JAR which uses Gatling's CLI runner as the mainClass:

    <project>
        <!-- ... -->
        <build>
            <plugins>
                <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-shade-plugin</artifactId>
                  <version>3.1.1</version>
                  <configuration>
                    <filters>
                      <!-- https://stackoverflow.com/a/6743609 -->
                      <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                          <exclude>META-INF/*.DSA</exclude>
                          <exclude>META-INF/*.SF</exclude>
                          <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                      </filter>
                    </filters>
                  </configuration>
                  <executions>
                    <execution>
                      <phase>package</phase>
                      <goals>
                        <goal>shade</goal>
                      </goals>
                      <configuration>
                        <transformers>
                          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>io.gatling.app.Gatling</mainClass>
                          </transformer>
                        </transformers>
                      </configuration>
                    </execution>
                  </executions>
                </plugin>
            </plugins>
        </build>
    </project>  
    
    0 讨论(0)
  • 2020-12-30 02:46

    I tried to do something similar. I could not use Maven as well. I will try to remember how I did this.

    1) I have configured maven-assembly-plugin to generate single JAR with dependencies like this:

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
    

    You need to ensure all required libraries (gatling, scala runtime, zinc compiler) are present on your resulting classpath.

    2) Check the scope of your dependencies as Maven packs only classes defined with scope=compile by default. The most simple way is probably to use no test dependencies.

    3) Create a launch script, e.g. launch.sh. It should contain something like this:

    #!/bin/sh
    USER_ARGS="-Dsomething=$1"
    COMPILATION_CLASSPATH=`find -L ./target -maxdepth 1 -name "*.jar" -type f -exec printf :{} ';'`
    JAVA_OPTS="-server -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -Xms512M -Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -XX:+AggressiveOpts -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false ${JAVA_OPTS}"
    java $JAVA_OPTS $USER_ARGS -cp $COMPILATION_CLASSPATH io.gatling.app.Gatling -s your.simulation.FullClassName
    

    To explain, I took gatling`s own launch script for inspiration. Note mainly the presence of target directory in classpath parameter definition.

    4) Compile your compiled target directory and launch.sh to a single directory and distribute this (e.g. as archive). Then you can the scenarios by executing ./launch.sh.

    I know this is not a standard solution, but it worked for me. Hopefully it will help you too. If you have any problems or tips to improve, please share with us.

    0 讨论(0)
  • 2020-12-30 02:53

    I had a similar issue, I fixed it as following:

    Inside Gatling package there is bin/ and take a look at gatling.sh. You see that it simply adds certain configurations into classpath and then runs io.gatling.app.Gatling class in gatling-compiler-<version_number>.jar. So, all you need to do is to make a jar that includes compiler, add configurations and tests to classpath and run io.gatling.app.Gatling. steps:

    add compiler dependency:

    <dependency>
            <groupId>io.gatling</groupId>
            <artifactId>gatling-compiler</artifactId>
            <version>${gatling.version}</version>
        </dependency
    

    create jar with dependencies:

      <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <finalName>${project.build.finalName}</finalName>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    

    create test jar (this includes your gatling tests)

     <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                        <configuration>
                            <excludes>
                                <exclude>src/test/resources/*</exclude>
                            </excludes>
                            <finalName>${project.build.finalName}</finalName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    

    create a package out of your configuration. You can use maven assembly for that. What I usually do, is to create a separate module that handles creating the package for different environments. This package contains your gatling.conf, logback.xmland all the other resources you application wants including test data. Now you basically have three packages: application.jar, application-tests.jar and application-conf.zip. Unzip application-conf.zip, copy application.jarand application-tests.jarin the same folder.

    In this folder, You need to create target/test-classes/ folder, just leave it empty. In my case, it was required. I think you can some how change that in gatling.conf. But I am not sure how.

    Run

    java -cp ".:application-test.jar:application.jar" io.gatling.app.Gatling  
    
    0 讨论(0)
  • 2020-12-30 02:59

    I think is a bit late for that but I face kinda the same problem related here, but instead to use maven I used gradle. Guess that the approach it's the same, a bit mix of the first solution and something or my own.

    First, define a gradle build file with gatling dependencies and a task to build a fatjar

    apply plugin: 'scala'
    version 0.1
    
    dependencies {
      compile group: 'io.gatling', name: 'gatling-test-framework', version: '2.1.7'
      compile group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.4.7'
      compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.7'
    }
    
    repositories{
       mavenCentral()
       mavenLocal()
    }
    
    
    task fatJar(type: Jar) {
       manifest {
           attributes 'Implementation-Title': 'Preparing test',  
              'Implementation-Version': version,
              'Main-Class': 'io.gatling.app.Gatling'
       }
       baseName = project.name + '-all'
          from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } {
            exclude 'META-INF/MANIFEST.MF'
            exclude 'META-INF/*.SF'
            exclude 'META-INF/*.DSA'
            exclude 'META-INF/*.RSA'
    
       }
       with jar
    }
    

    That task executed as

    gradle clean build fatJar
    

    will generate a self contained jar which will run the Gatling main class as default. So tell it witch test you want to run is made with the standard '-s' parameter.

    So last step is create, if you want, a script to run it. I will "steal" the script for the first comment and change a bit

    #!/bin/sh
    
    if [ -z "$1" ];
    then
        echo "Test config tool"
        echo
        echo "Running Parameters : "
        echo
        echo " <Config file> : Test definition file. Required"
        echo
       exit 0;
     fi
    
    USER_ARGS="-DCONFIG_FILE=$1"
    JAVA_OPTS="-server -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -Xms512M -Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -XX:+AggressiveOpts -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false ${JAVA_OPTS}"
    java $JAVA_OPTS $USER_ARGS -jar test-project-all-0.1.jar -s FunctionalTestSimulation -nr
    

    In my case I will run the same test with different, easy to configure, parameters so my Simulation is always the same. All my scala files are compiled by gradle and package in the jar that's mean they are in the classpath, changing the "FunctionalTestSimulation" name for a Script variable make easy adapt this script for something more generic.

    Guess that make a Maven version will be easy.

    Hope that help somebody.

    Update with folder structure After a request will add an small draft of the folder structure for the project:

    test-project
        |_ build.gradle
        |_ src
            |_ main
                |_ scala
                |_ resources
        |_ runSimulation.sh
        |_ configFile.conf
    

    When have time will provide a link to my github with a working one. Cheers

    0 讨论(0)
  • 2020-12-30 03:06

    You can always create a simple Java class that starts Gatling with the Gatling.fromArgs. With this setup you can have all in just one happy executable jar. Let this class be the jar mainClass instead of "io.gatling.app.Gatling". This example is for a scala simulation class "my.package.MySimulation".

    import scala.Option;
    import io.gatling.app.Gatling;
    import io.gatling.core.scenario.Simulation;
    
    public class StartSimulation {
    
      public static void main(String[] args) {
        Gatling.fromArgs(new String[]{}, new Option<Class<Simulation>>() {
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public int productArity() {
                return 0;
            }
    
            @Override
            public Object productElement(int arg0) {
                return null;
            }
    
            @SuppressWarnings("unchecked")
            @Override
            public Class<Simulation> get() {
                try {
                    return (Class<Simulation>) Class.forName("my.package.MySimulation");
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                return null;
            }
    
            @Override
            public boolean isEmpty() {
                return false;
            }
    
            @Override
            public boolean canEqual(Object o) {
                return false;
            }
        });
      }
    }
    
    0 讨论(0)
提交回复
热议问题