Search code examples
gatlingscala-gatling

Implement user behavior in Gatling via sequential http requests


Is there a way to implement sequential http requests in one scenario?

Clearly what i want: make a load test on REST API with "simulating" users behavior.

1.1. User goes to /a

1.2. Get some info

2.1. Then fo to /b with some previously taken info

2.2. ... etc

And this scenario must be executed by some amount of VU at same time.

But what i see on graphics all VU doing request 1 simultaneously multiple times then all do request 2 and so on:

  1. requests to /a goes for 10s
  2. then requests to /b goes for 10s

But each rout response in about 20-30ms, so its not delaying by waiting response. That's now how users will behavior and not what i want from my test.

What i am doing in my project:

pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>a</groupId>
        <artifactId>b</artifactId>
        <version>1.0.0</version> <!-- build_version -->
    
        <properties>
            <java.version>1.8</java.version>
            <scala.version>2.12</scala.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    
            <scala.maven.plagin.version>4.4.0</scala.maven.plagin.version>
            <gatling.maven.plagin.version>3.0.5</gatling.maven.plagin.version>
    
            <gatling.version>3.3.1</gatling.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>io.gatling.highcharts</groupId>
                <artifactId>gatling-charts-highcharts</artifactId>
                <version>${gatling.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <repositories>
            <repository>
                <id>sonatype</id>
                <url>https://oss.sonatype.org/content/repositories/releases/</url>
            </repository>
        </repositories>
    
        <build>
            <sourceDirectory>src/main/scala</sourceDirectory>
            <testSourceDirectory>src/test/scala</testSourceDirectory>
    
            <plugins>
                <plugin>
                    <groupId>io.gatling</groupId>
                    <artifactId>gatling-maven-plugin</artifactId>
                    <version>${gatling.maven.plagin.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>test</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>scala-maven-plugin</artifactId>
                    <version>${scala.maven.plagin.version}</version>
                    <configuration>
                        <jvmArgs>
                            <jvmArg>-Xss100M</jvmArg>
                        </jvmArgs>
                        <args>
                            <arg>-target:jvm-${java.version}</arg>
                            <arg>-deprecation</arg>
                            <arg>-feature</arg>
                            <arg>-unchecked</arg>
                            <arg>-language:implicitConversions</arg>
                            <arg>-language:postfixOps</arg>
                        </args>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                                <goal>testCompile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
    
        </build>
    
    </project>

.scala file:

    import io.gatling.core.Predef._
    import io.gatling.core.structure.ScenarioBuilder
    import io.gatling.http.Predef._
    import io.gatling.http.protocol.HttpProtocolBuilder
    import scala.concurrent.duration._
    
    class SimpleScenario extends Simulation {
    
      val users  = 200
      val maxRPS = 200
    
      val rampUp: FiniteDuration   = 1 minutes
      val duration: FiniteDuration = 1 minutes
    
      val httpProtocol: HttpProtocolBuilder = http
        .baseUrl("http://some.site")
    
      val scn0: ScenarioBuilder = scenario("ASimulation")
        .exec(
          Seq(
            exec(
              http("a")
                .post("/a")
                .body(StringBody("""{"username": "a", "password": "b"}"""))
                .check(status.is(200))
            )
              .exec(
                http("b")
                  .get("/b")
                  .check(status.is(200))
              )
              // ... and so on
          )
        )
    
      setUp(
        scn0
          .inject(
            constantConcurrentUsers(users) during(rampUp + duration)
          )
          .throttle(
            reachRps(maxRPS) in (rampUp),
            holdFor(duration)
          )
      ).protocols(httpProtocol)
    }

Command that i run to execute test:

mvn gatling:test

And i am tryed already:

  1. .repeat(1)
  2. .exec without Seq
  3. chain of .exec's outside of one

Solution

  • so its not delaying by waiting response

    Yes it is. Each virtual user will wait for response "a" before sending request "b".