├── .gitignore ├── src └── test │ ├── resources │ ├── feeders │ │ ├── search.csv │ │ ├── toungzip.json.gz │ │ ├── tounzip.json.zip │ │ ├── searchToFilter.csv │ │ └── dzejson.json │ ├── otherFiles │ │ └── dummy.pdf │ ├── logback-test.xml │ └── gatling.conf │ └── java │ ├── pl │ └── gemiusz │ │ ├── Case0012DenySomeResourcesSimulation.java │ │ ├── Case0002PDFdownloadSimulation.java │ │ ├── Case0004StatusCodeSimulation.java │ │ ├── Case0019WhenStatusCode400ThenFailSimulation.java │ │ ├── Case0014Loop5times1RPSand3sPauseSimulation.java │ │ ├── Case0005UUIDfeederSimulation.java │ │ ├── Case0020ExitBlockOnFailSimulation.java │ │ ├── Case0025JSONfeederRandomSimulation.java │ │ ├── Case0026ResponseHeaderRegexSimulation.java │ │ ├── Case0007AsyncReqSimulation.java │ │ ├── Case0003UnzipJsonForFeederSimulation.java │ │ ├── Case0015UUIDfeederTwoRecordsAtTheSameTimeSimulation.java │ │ ├── Case0011ProxyCommandLineParametersSimulation.java │ │ ├── Case0027FilterFeederAndForeverLoopSameRecordByVU.java │ │ ├── Case0009SessionValuesSimulation.java │ │ ├── Case0023foreachFromUUIDfeederFiveRecordsAtTheSameTimeSimulation.java │ │ ├── Case0013RequestBeforeSimulation.java │ │ ├── Case0006CommandLineParametersSimulation.java │ │ ├── Case0001JMESPathSimulation.java │ │ ├── Case0021CheckResourcesResponseTimeSimulation.java │ │ ├── Case0010JsonEditVariableSimulation.java │ │ ├── Case0018GetTokenWhenStatus401Simulation.java │ │ ├── Case0016ScenarioDurationSimulation.java │ │ ├── Case0024IterationLoopCondition.java │ │ ├── Case0022SetOrRefreshTokenSimulation.java │ │ ├── Case0008AsyncReqResourcesSimulation.java │ │ └── Case0017ForeachAfterForeachSimulation.java │ └── computerdatabase │ ├── BasicSimulation.java │ ├── advanced │ ├── AdvancedSimulationStep04.java │ ├── AdvancedSimulationStep02.java │ ├── AdvancedSimulationStep01.java │ ├── AdvancedSimulationStep05.java │ └── AdvancedSimulationStep03.java │ └── ComputerDatabaseSimulation.java ├── go.mod ├── .github ├── dependabot.yml └── workflows │ ├── gatling_test_all_mine_after_pull_request.yml │ └── gatling_test_all_mine_after_push.yml ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── pom.xml ├── mvnw.cmd ├── README.md └── mvnw /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.idea 3 | -------------------------------------------------------------------------------- /src/test/resources/feeders/search.csv: -------------------------------------------------------------------------------- 1 | searchCriterion,searchComputerName 2 | Macbook,MacBook Pro 3 | eee,ASUS Eee PC 1005PE 4 | -------------------------------------------------------------------------------- /src/test/resources/otherFiles/dummy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gemiusz/gatling-examples-maven-java/HEAD/src/test/resources/otherFiles/dummy.pdf -------------------------------------------------------------------------------- /src/test/resources/feeders/toungzip.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gemiusz/gatling-examples-maven-java/HEAD/src/test/resources/feeders/toungzip.json.gz -------------------------------------------------------------------------------- /src/test/resources/feeders/tounzip.json.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gemiusz/gatling-examples-maven-java/HEAD/src/test/resources/feeders/tounzip.json.zip -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gemiusz/gatling-examples-maven-java 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/gatling/gatling v3.14.3+incompatible // indirect 7 | ) 8 | -------------------------------------------------------------------------------- /src/test/resources/feeders/searchToFilter.csv: -------------------------------------------------------------------------------- 1 | searchCriterion,searchComputerName 2 | Macbook,MacBook Pro_1 3 | eee,ASUS Eee PC 1005PE_1 4 | Macbook,MacBook Pro_2 5 | eee,ASUS Eee PC 1005PE_2 6 | Macbook,MacBook Pro_3 7 | eee,ASUS Eee PC 1005PE_3 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "github-actions" 8 | # Workflow files stored in the 9 | # default location of `.github/workflows` 10 | directory: "/" 11 | schedule: 12 | interval: "daily" 13 | -------------------------------------------------------------------------------- /src/test/resources/feeders/dzejson.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "username": "UserA", 4 | "agendaID": "AgendaA_ID", 5 | "patients": [ 6 | { 7 | "patientID": "PatientAX_ID", 8 | "patientID64": "PatientAX_ID64" 9 | }, 10 | { 11 | "patientID": "PatientAY_ID", 12 | "patientID64": "PatientAY_ID64" 13 | } 14 | ] 15 | }, 16 | { 17 | "username": "UserB", 18 | "agendaID": "AgendaB_ID", 19 | "patients": [ 20 | { 21 | "patientID": "PatientBX_ID", 22 | "patientID64": "PatientBX_ID64" 23 | }, 24 | { 25 | "patientID": "PatientBY_ID", 26 | "patientID64": "PatientBY_ID64" 27 | } 28 | ] 29 | } 30 | ] -------------------------------------------------------------------------------- /.github/workflows/gatling_test_all_mine_after_pull_request.yml: -------------------------------------------------------------------------------- 1 | name: gatling:test 2 | 3 | on: 4 | pull_request: 5 | branches: [ "master" ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: CheckOut 12 | uses: actions/checkout@v4 13 | - name: Set up JDK 21 14 | uses: actions/setup-java@v4 15 | with: 16 | java-version: '21' 17 | distribution: 'temurin' 18 | cache: maven 19 | - name: Run Gatling with Maven 20 | run: mvn clean gatling:test -Dgatling.runMultipleSimulations -Dgatling.includes=pl.gemiusz.* -Dgatling.excludes=pl.gemiusz.Case0019WhenStatusCode400ThenFailSimulation 21 | -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/workflows/gatling_test_all_mine_after_push.yml: -------------------------------------------------------------------------------- 1 | name: gatling:test 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: CheckOut 12 | uses: actions/checkout@v4 13 | - name: Set up JDK 21 14 | uses: actions/setup-java@v4 15 | with: 16 | java-version: '21' 17 | distribution: 'temurin' 18 | cache: maven 19 | - name: Run Gatling with Maven 20 | run: mvn clean gatling:test -Dgatling.runMultipleSimulations -Dgatling.includes=pl.gemiusz.* -Dgatling.excludes=pl.gemiusz.Case0019WhenStatusCode400ThenFailSimulation 21 | - name: Maven Dependency Tree Dependency Submission 22 | uses: advanced-security/maven-dependency-submission-action@v5.0.0 23 | with: 24 | ignore-maven-wrapper: true 25 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip 20 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0012DenySomeResourcesSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.*; 8 | import static io.gatling.javaapi.http.HttpDsl.http; 9 | 10 | public class Case0012DenySomeResourcesSimulation extends Simulation { 11 | 12 | HttpProtocolBuilder httpProtocol = 13 | http 14 | .baseUrl("https://github.com") 15 | .inferHtmlResources( 16 | DenyList( 17 | ".*github\\.githubassets\\.com.*", 18 | ".*avatars\\.githubusercontent\\.com\\/facebook.*")); 19 | 20 | ScenarioBuilder scn = 21 | scenario("GeMi_DenySomeResourcesSimulation") 22 | .exec( 23 | http("GeMi_DenySomeResourcesSimulation_get") 24 | .get("/") 25 | ); 26 | 27 | { 28 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0002PDFdownloadSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.*; 8 | import static io.gatling.javaapi.http.HttpDsl.http; 9 | 10 | public class Case0002PDFdownloadSimulation extends Simulation { 11 | 12 | // https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf 13 | HttpProtocolBuilder httpProtocol = 14 | http 15 | .baseUrl("https://www.w3.org"); 16 | 17 | ScenarioBuilder scn = 18 | scenario("GeMi_PDFdownloadSimulation") 19 | .exec( 20 | http("GeMi_PDFdownloadSimulation_get") 21 | .get("/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf") 22 | .check(bodyBytes().is(RawFileBody("otherFiles/dummy.pdf"))) 23 | .check(bodyLength().is(13264)) 24 | ); 25 | 26 | { 27 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0004StatusCodeSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.atOnceUsers; 8 | import static io.gatling.javaapi.core.CoreDsl.scenario; 9 | import static io.gatling.javaapi.http.HttpDsl.http; 10 | import static io.gatling.javaapi.http.HttpDsl.status; 11 | 12 | public class Case0004StatusCodeSimulation extends Simulation { 13 | 14 | HttpProtocolBuilder httpProtocol = 15 | http 16 | .baseUrl("https://postman-echo.com"); 17 | 18 | ScenarioBuilder scn = 19 | scenario("GeMi_StatusCodeSimulation") 20 | .exec( 21 | http("GeMi_StatusCodeSimulation_get") 22 | .get("/status/414") 23 | .check(status().is(414).saveAs("GeMi_Status_Code")) 24 | ).exec(session -> { 25 | System.out.println("GeMi_Status_Code: " + session.get("GeMi_Status_Code").toString()); 26 | return session; 27 | }); 28 | 29 | { 30 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0019WhenStatusCode400ThenFailSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.*; 8 | import static io.gatling.javaapi.http.HttpDsl.http; 9 | import static io.gatling.javaapi.http.HttpDsl.status; 10 | 11 | /** 12 | * HOW TO RUN: 13 | * mvnw gatling:test -Dgatling.simulationClass=pl.gemiusz.Case0019WhenStatusCode400ThenFailSimulation 14 | */ 15 | public class Case0019WhenStatusCode400ThenFailSimulation extends Simulation { 16 | 17 | HttpProtocolBuilder httpProtocol = 18 | http 19 | .baseUrl("https://postman-echo.com"); 20 | 21 | ScenarioBuilder scn = 22 | scenario("GeMi_WhenStatusCode400ThenFailSimulation") 23 | .exec( 24 | http("GeMi_WhenStatusCode400ThenFailSimulation_get") 25 | .get("/status/400") 26 | .check(status().not(400)) 27 | ); 28 | 29 | { 30 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)) 31 | .assertions( 32 | global().failedRequests().count().is(0L) 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0014Loop5times1RPSand3sPauseSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.OpenInjectionStep; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.time.Duration; 9 | import java.util.stream.Stream; 10 | 11 | import static io.gatling.javaapi.core.CoreDsl.*; 12 | import static io.gatling.javaapi.http.HttpDsl.http; 13 | import static io.gatling.javaapi.http.HttpDsl.status; 14 | 15 | public class Case0014Loop5times1RPSand3sPauseSimulation extends Simulation { 16 | 17 | HttpProtocolBuilder httpProtocol = 18 | http 19 | .baseUrl("https://postman-echo.com"); 20 | 21 | ScenarioBuilder scn = 22 | scenario("GeMi_Loop5times1RPSand3sPauseSimulation") 23 | .exec( 24 | http("GeMi_Loop5times1RPSand3sPauseSimulation_get") 25 | .get("/status/200") 26 | .check(status().is(200).saveAs("GeMi_Status_Code")) 27 | ); 28 | 29 | { 30 | setUp(scn.injectOpen( 31 | Stream.generate( 32 | () -> new OpenInjectionStep[]{ 33 | atOnceUsers(1), 34 | nothingFor(Duration.ofSeconds(3)) 35 | } 36 | ).limit(5).flatMap(Stream::of).toArray(OpenInjectionStep[]::new) 37 | ) 38 | .protocols(httpProtocol)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0005UUIDfeederSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import java.util.Collections; 8 | import java.util.Iterator; 9 | import java.util.Map; 10 | import java.util.UUID; 11 | import java.util.function.Supplier; 12 | import java.util.stream.Stream; 13 | 14 | import static io.gatling.javaapi.core.CoreDsl.*; 15 | import static io.gatling.javaapi.http.HttpDsl.http; 16 | 17 | public class Case0005UUIDfeederSimulation extends Simulation { 18 | 19 | HttpProtocolBuilder httpProtocol = 20 | http 21 | .baseUrl("https://postman-echo.com"); 22 | 23 | Iterator> feederUUID = 24 | Stream.generate((Supplier>) () -> { 25 | String uuidString = UUID.randomUUID().toString(); 26 | return Collections.singletonMap("uuidString", uuidString); 27 | } 28 | ).iterator(); 29 | 30 | ScenarioBuilder scn = 31 | scenario("GeMi_UUIDfeederSimulation") 32 | .feed(feederUUID) 33 | .exec( 34 | http("GeMi_UUIDfeederSimulation_get") 35 | .get("/get?foo=#{uuidString}") 36 | .check(jmesPath("args.foo").isEL("#{uuidString}")) 37 | ).exec(session -> { 38 | System.out.println("GeMi_feederUUID_uuidString: " + session.get("uuidString")); 39 | return session; 40 | }); 41 | 42 | { 43 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0020ExitBlockOnFailSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import java.time.Duration; 8 | 9 | import static io.gatling.javaapi.core.CoreDsl.*; 10 | import static io.gatling.javaapi.http.HttpDsl.http; 11 | import static io.gatling.javaapi.http.HttpDsl.status; 12 | 13 | public class Case0020ExitBlockOnFailSimulation extends Simulation { 14 | 15 | HttpProtocolBuilder httpProtocol = 16 | http 17 | .baseUrl("https://postman-echo.com"); 18 | 19 | ScenarioBuilder scn = 20 | scenario("GeMi_ExitBlockOnFailSimulation") 21 | .exitBlockOnFail().on( 22 | exec( 23 | http("GeMi_ExitBlockOnFailSimulatio_get_200") 24 | .get("/status/200") 25 | .check(status().is(200)) 26 | ).exec( 27 | http("GeMi_ExitBlockOnFailSimulatio_get_200_or_exit") 28 | .get("/status/20#{randomInt(0,2)}") 29 | .check(status().is(200)) 30 | ).exec( 31 | http("GeMi_ExitBlockOnFailSimulatio_get_400") 32 | .get("/status/400") 33 | .check(status().is(400)) 34 | ) 35 | ); 36 | 37 | { 38 | setUp(scn.injectOpen(constantUsersPerSec(1).during(Duration.ofSeconds(10))).protocols(httpProtocol)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0025JSONfeederRandomSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.FeederBuilder; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import static io.gatling.javaapi.core.CoreDsl.*; 9 | import static io.gatling.javaapi.http.HttpDsl.http; 10 | 11 | public class Case0025JSONfeederRandomSimulation extends Simulation { 12 | 13 | HttpProtocolBuilder httpProtocol = 14 | http 15 | .baseUrl("https://postman-echo.com"); 16 | 17 | FeederBuilder feederJSON = jsonFile("feeders\\dzejson.json").random(); 18 | 19 | ScenarioBuilder scn = 20 | scenario("GeMi_JSONfeederRandomSimulation") 21 | .feed(feederJSON) 22 | .exec( 23 | http("GeMi_JSONfeederRandomSimulation_get_username") 24 | .get("/get?foo=#{username}") 25 | .check(jmesPath("args.foo").saveAs("usernameRsp")) 26 | ).exec(session -> { 27 | System.out.println("GeMi_usernameRsp: " + session.get("usernameRsp")); 28 | return session; 29 | }) 30 | .exec( 31 | http("GeMi_JSONfeederRandomSimulation_get_random_patientID") 32 | .get("/get?foo=#{patients.random().patientID}") 33 | .check(jmesPath("args.foo").saveAs("patientIdRsp")) 34 | ).exec(session -> { 35 | System.out.println("GeMi_patientIdRsp: " + session.get("patientIdRsp")); 36 | return session; 37 | }); 38 | 39 | { 40 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0026ResponseHeaderRegexSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.atOnceUsers; 8 | import static io.gatling.javaapi.core.CoreDsl.scenario; 9 | import static io.gatling.javaapi.http.HttpDsl.*; 10 | 11 | public class Case0026ResponseHeaderRegexSimulation extends Simulation { 12 | 13 | HttpProtocolBuilder httpProtocol = 14 | http 15 | .baseUrl("https://postman-echo.com"); 16 | 17 | ScenarioBuilder scn = 18 | scenario("GeMi_ResponseHeaderRegexSimulation") 19 | .exec( 20 | http("GeMi_ResponseHeaderRegexSimulation_get") 21 | .get("/response-headers") 22 | .queryParam("content-type", "text/html; charset=utf-8") 23 | .queryParam("sap-err-id", "ICFLOGONREQUIRED") 24 | .queryParam("location", "/sap/bc/ui2/flp?saml2=disabled&_sap-hash=JTIzU2hlbGwtaG9tZQ&sap-system-login=X&sap-system-login-cookie=X&**sap-contextid=**SID:ANON:IKAWEQQM1AS01_QM1_22:aK-vnihlk8JcmIebDTWefQVnZujrJlbmE8-etYjR-ATT") 25 | .queryParam("sap-server", true) 26 | .check(status().is(200)) 27 | .check( 28 | headerRegex("location", "&\\*\\*sap-contextid=\\*\\*(.*)").saveAs("GeMi_header_location_sap-contextid") 29 | ) 30 | ).exec(session -> { 31 | System.out.println("GeMi_header_location_sap-contextid: " + session.get("GeMi_header_location_sap-contextid")); 32 | return session; 33 | }); 34 | 35 | { 36 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0007AsyncReqSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | import io.netty.util.internal.ThreadLocalRandom; 7 | 8 | import java.util.Collections; 9 | import java.util.Iterator; 10 | import java.util.Map; 11 | import java.util.function.Supplier; 12 | import java.util.stream.Stream; 13 | 14 | import static io.gatling.javaapi.core.CoreDsl.*; 15 | import static io.gatling.javaapi.http.HttpDsl.http; 16 | 17 | public class Case0007AsyncReqSimulation extends Simulation { 18 | 19 | HttpProtocolBuilder httpProtocol = 20 | http 21 | .baseUrl("https://postman-echo.com"); 22 | 23 | Iterator> feederInt = 24 | Stream.generate((Supplier>) () -> { 25 | int min = 3; 26 | int max = 6; 27 | int randomInt = ThreadLocalRandom.current().nextInt(min, max); 28 | return Collections.singletonMap("randomInt", randomInt); 29 | } 30 | ).iterator(); 31 | 32 | ScenarioBuilder scn = 33 | scenario("GeMi_AsyncReqSimulation") 34 | .feed(feederInt) 35 | .exec( 36 | http("GeMi_AsyncReqSimulation_get") 37 | .get("/get?foo=#{randomInt}") 38 | .check(jmesPath("args.foo").isEL("#{randomInt}")) 39 | ) 40 | .repeat("#{randomInt}", "counterRandomInt").on( 41 | exec( 42 | http("GeMi_AsyncReqSimulation_async_#{counterRandomInt}") 43 | .get("/get?foo=#{counterRandomInt}") 44 | .check(jmesPath("args.foo").isEL("#{counterRandomInt}")) 45 | ) 46 | ); 47 | 48 | { 49 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0003UnzipJsonForFeederSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.FeederBuilder; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import static io.gatling.javaapi.core.CoreDsl.*; 9 | import static io.gatling.javaapi.http.HttpDsl.http; 10 | 11 | public class Case0003UnzipJsonForFeederSimulation extends Simulation { 12 | 13 | HttpProtocolBuilder httpProtocol = 14 | http 15 | .baseUrl("https://postman-echo.com"); 16 | 17 | FeederBuilder feederUnzip = jsonFile("feeders/tounzip.json.zip").unzip().random(); 18 | FeederBuilder feederUngzip = jsonFile("feeders/toungzip.json.gz").unzip().random(); 19 | 20 | ScenarioBuilder scn = 21 | scenario("GeMi_UnzipJsonForFeederSimulation") 22 | .feed(feederUnzip) 23 | .exec( 24 | http("GeMi_UnzipJsonForFeederSimulation_feederUnzip_post") 25 | .post("/post") 26 | .body(StringBody("#{foo}")) 27 | .asJson() 28 | .check( 29 | jmesPath("json.fruits[?details.size >= `500`].name").is("[\"Apple\"]") 30 | ) 31 | ) 32 | .feed(feederUngzip) 33 | .exec( 34 | http("GeMi_UnGzipJsonForFeederSimulation_feederUngzip_post") 35 | .post("/post") 36 | .body(StringBody("#{bar}")) 37 | .asJson() 38 | .check( 39 | jmesPath("json.fruits[?details.size >= `500`].name").is("[\"Apple\"]") 40 | ) 41 | ); 42 | 43 | { 44 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0015UUIDfeederTwoRecordsAtTheSameTimeSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import java.util.Collections; 8 | import java.util.Iterator; 9 | import java.util.Map; 10 | import java.util.UUID; 11 | import java.util.function.Supplier; 12 | import java.util.stream.Stream; 13 | 14 | import static io.gatling.javaapi.core.CoreDsl.*; 15 | import static io.gatling.javaapi.http.HttpDsl.http; 16 | 17 | public class Case0015UUIDfeederTwoRecordsAtTheSameTimeSimulation extends Simulation { 18 | 19 | HttpProtocolBuilder httpProtocol = 20 | http 21 | .baseUrl("https://postman-echo.com"); 22 | 23 | Iterator> feederUUID = 24 | Stream.generate((Supplier>) () -> { 25 | String uuidString = UUID.randomUUID().toString(); 26 | return Collections.singletonMap("uuidString", uuidString); 27 | } 28 | ).iterator(); 29 | 30 | ScenarioBuilder scn = 31 | scenario("GeMi_UUIDfeederTwoRecordsAtTheSameTimeSimulation") 32 | .feed(feederUUID, 2) 33 | .exec( 34 | http("GeMi_UUIDfeederTwoRecordsAtTheSameTimeSimulation_get") 35 | .get("/get?foo=#{uuidString(0)}&bar=#{uuidString(1)}") 36 | .check(jmesPath("args.foo").isEL("#{uuidString(0)}")) 37 | .check(jmesPath("args.bar").isEL("#{uuidString(1)}")) 38 | ).exec(session -> { 39 | Object[] uuidStringArray = session.get("uuidString"); 40 | System.out.println("GeMi_feederUUID_uuidString(0): " + uuidStringArray[0]); 41 | System.out.println("GeMi_feederUUID_uuidString(1): " + uuidStringArray[1]); 42 | return session; 43 | }); 44 | 45 | { 46 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0011ProxyCommandLineParametersSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.*; 8 | import static io.gatling.javaapi.http.HttpDsl.Proxy; 9 | import static io.gatling.javaapi.http.HttpDsl.http; 10 | 11 | /** 12 | * HOW TO RUN: 13 | * mvnw gatling:test -Dgatling.simulationClass=pl.gemiusz.Case0011ProxyCommandLineParametersSimulation -Dfoo=10 -Dbar=GeMi -DuseProxy=true -DproxyHost=127.0.0.1 -DproxyPort=8080 14 | */ 15 | public class Case0011ProxyCommandLineParametersSimulation extends Simulation { 16 | 17 | int foo = Integer.getInteger("foo", 1); 18 | String bar = System.getProperty("bar"); 19 | 20 | 21 | static boolean useProxy = Boolean.getBoolean("useProxy"); 22 | static String proxyHost = System.getProperty("proxyHost"); 23 | static int proxyPort = Integer.getInteger("proxyPort", 8080); 24 | 25 | static HttpProtocolBuilder httpProtocol = httpProtocolCustom(); 26 | 27 | public static HttpProtocolBuilder httpProtocolCustom() { 28 | HttpProtocolBuilder httpProtocolB = 29 | http 30 | .baseUrl("https://postman-echo.com"); 31 | 32 | if (useProxy) { 33 | if (proxyHost.length() == 0) { 34 | proxyHost = "127.0.0.1"; 35 | } 36 | httpProtocolB = httpProtocolB.proxy(Proxy(proxyHost, proxyPort)); 37 | } 38 | return httpProtocolB; 39 | } 40 | 41 | ScenarioBuilder scn = 42 | scenario("GeMi_ProxyCommandLineParametersSimulation") 43 | .exec( 44 | http("GeMi_ProxyCommandLineParametersSimulation_get") 45 | .get("/get?foo=" + foo + "&bar=" + bar) 46 | .check(jmesPath("args.foo").is(String.valueOf(foo))) 47 | .check(jmesPath("args.bar").is(String.valueOf(bar))) 48 | ); 49 | 50 | { 51 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/BasicSimulation.java: -------------------------------------------------------------------------------- 1 | package computerdatabase; // 1 2 | 3 | // 2 4 | 5 | import io.gatling.javaapi.core.ScenarioBuilder; 6 | import io.gatling.javaapi.core.Simulation; 7 | import io.gatling.javaapi.http.HttpProtocolBuilder; 8 | 9 | import static io.gatling.javaapi.core.CoreDsl.atOnceUsers; 10 | import static io.gatling.javaapi.core.CoreDsl.scenario; 11 | import static io.gatling.javaapi.http.HttpDsl.http; 12 | 13 | /*** 14 | * What does it mean? 15 | * 16 | * 1. The optional package. 17 | * 2. The required imports. 18 | * 3. The class declaration. Note that it extends Simulation. 19 | * 4. The common configuration to all HTTP requests. 20 | * 5. The baseUrl that will be prepended to all relative urls. 21 | * 6. Common HTTP headers that will be sent with all the requests. 22 | * 7. The scenario definition. 23 | * 8. An HTTP request, named request_1. This name will be displayed in the final reports. 24 | * 9. The url this request targets with the GET method. 25 | * 10. Some pause/think time. 26 | * Duration units default to seconds, e.g. pause(5) is equivalent to java.time.Duration.ofSeconds(5) in Java or pause(5.seconds) in Scala. 27 | * 11. Where one sets up the scenarios that will be launched in this Simulation. 28 | * 12. Declaring that we will inject one single user into the scenario named scn. 29 | * 13. Attaching the HTTP configuration declared above. 30 | */ 31 | public class BasicSimulation extends Simulation { // 3 32 | 33 | HttpProtocolBuilder httpProtocol = http // 4 34 | .baseUrl("http://computer-database.gatling.io") // 5 35 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") // 6 36 | .doNotTrackHeader("1") 37 | .acceptLanguageHeader("en-US,en;q=0.5") 38 | .acceptEncodingHeader("gzip, deflate") 39 | .userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0"); 40 | 41 | ScenarioBuilder scn = scenario("BasicSimulation") // 7 42 | .exec(http("request_1") // 8 43 | .get("/")) // 9 44 | .pause(5); // 10 45 | 46 | { 47 | setUp( // 11 48 | scn.injectOpen(atOnceUsers(1)) // 12 49 | ).protocols(httpProtocol); // 13 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0027FilterFeederAndForeverLoopSameRecordByVU.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.FeederBuilder; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.time.Duration; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import static io.gatling.javaapi.core.CoreDsl.*; 13 | import static io.gatling.javaapi.http.HttpDsl.http; 14 | 15 | public class Case0027FilterFeederAndForeverLoopSameRecordByVU extends Simulation { 16 | 17 | HttpProtocolBuilder httpProtocol = 18 | http 19 | .baseUrl("https://postman-echo.com"); 20 | 21 | List> allRecords = csv("feeders/searchToFilter.csv").readRecords(); 22 | 23 | List> filterdRecords = allRecords.stream() 24 | .filter(n -> n.get("searchCriterion").equals("eee")) 25 | .toList(); 26 | 27 | FeederBuilder fedder = listFeeder(filterdRecords).circular(); 28 | 29 | ScenarioBuilder scn = 30 | scenario("GeMi_FilterFeederAndForeverLoopSameRecordByVU") 31 | .feed(fedder) 32 | .forever() 33 | .on( 34 | exec( 35 | http("GeMi_FilterFeederAndForeverLoopSameRecordByVU_get") 36 | .get("/get?foo=#{searchComputerName}") 37 | .check(jmesPath("args.foo").isEL("#{searchComputerName}")) 38 | ) 39 | .exec(session -> { 40 | System.out.println("GeMi_log: VU_id: "+ session.userId() + " | Fedder_record: " + session.get("searchCriterion").toString() + " " + session.get("searchComputerName").toString()); 41 | return session; 42 | }) 43 | .pause(Duration.ofSeconds(1)) 44 | ); 45 | 46 | { 47 | setUp(scn.injectOpen(constantUsersPerSec(1).during(4)).protocols(httpProtocol)).maxDuration(Duration.ofSeconds(15)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0009SessionValuesSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Session; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import static io.gatling.javaapi.core.CoreDsl.*; 9 | import static io.gatling.javaapi.http.HttpDsl.http; 10 | import static io.gatling.javaapi.http.HttpDsl.status; 11 | 12 | public class Case0009SessionValuesSimulation extends Simulation { 13 | 14 | HttpProtocolBuilder httpProtocol = 15 | http 16 | .baseUrl("https://postman-echo.com"); 17 | 18 | ScenarioBuilder scn = 19 | scenario("GeMi_SessionValuesSimulation") 20 | .exec( 21 | http("GeMi_SessionValuesSimulation_get_first") 22 | .get("/status/414") 23 | .check(status().is(414).saveAs("GeMi_Response_Code")) 24 | ).exec(session -> { 25 | System.out.println("GeMi_Response_Code: " + session.get("GeMi_Response_Code").toString()); 26 | Session session1 = session.set("GeMi_Response_Code_1", session.get("GeMi_Response_Code").toString() + "_1"); 27 | return session1; 28 | }).exec(session -> { 29 | System.out.println("GeMi_Response_Code_1: " + session.get("GeMi_Response_Code_1").toString()); 30 | Session session2 = session.set("GeMi_Response_Code_2", session.get("GeMi_Response_Code_1").toString() + "_2"); 31 | return session2; 32 | }).exec(session -> { 33 | System.out.println("GeMi_Response_Code_2: " + session.get("GeMi_Response_Code_2").toString()); 34 | return session; 35 | }).exec( 36 | http("GeMi_SessionValuesSimulation_get_later") 37 | .get("/get?foo=#{GeMi_Response_Code_2}") 38 | .check(jmesPath("args.foo").is("414_1_2"))); 39 | 40 | { 41 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0023foreachFromUUIDfeederFiveRecordsAtTheSameTimeSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Session; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.util.*; 9 | import java.util.function.Supplier; 10 | import java.util.stream.Stream; 11 | 12 | import static io.gatling.javaapi.core.CoreDsl.*; 13 | import static io.gatling.javaapi.http.HttpDsl.http; 14 | 15 | public class Case0023foreachFromUUIDfeederFiveRecordsAtTheSameTimeSimulation extends Simulation { 16 | 17 | HttpProtocolBuilder httpProtocol = 18 | http 19 | .baseUrl("https://postman-echo.com"); 20 | 21 | Iterator> feederUUID = 22 | Stream.generate((Supplier>) () -> { 23 | String uuidString = UUID.randomUUID().toString(); 24 | return Collections.singletonMap("uuidString", uuidString); 25 | } 26 | ).iterator(); 27 | 28 | ScenarioBuilder scn = 29 | scenario("GeMi_foreachFromUUIDfeederFiveRecordsAtTheSameTimeSimulation") 30 | .feed(feederUUID, 5) 31 | .exec(session -> { 32 | ArrayList uuidStringArrayList = session.get("uuidString"); 33 | Session session1 = session.set("uuidStringArrayList", uuidStringArrayList); 34 | return session1; 35 | }) 36 | .foreach("#{uuidStringArrayList}", "uuidStringEl", "counter").on( 37 | exec(session -> { 38 | System.out.println("counter: " + session.getString("counter")); 39 | System.out.println("uuidStringEl: " + session.getString("uuidStringEl")); 40 | return session; 41 | }) 42 | .exec( 43 | http("GeMi_UUIDfeederSimulation_get") 44 | .get("/get?foo=#{uuidStringEl}") 45 | .check(jmesPath("args.foo").isEL("#{uuidStringEl}")) 46 | ) 47 | ); 48 | 49 | { 50 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0013RequestBeforeSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.JsonNode; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import io.gatling.javaapi.core.ScenarioBuilder; 7 | import io.gatling.javaapi.core.Simulation; 8 | import io.gatling.javaapi.http.HttpProtocolBuilder; 9 | 10 | import java.io.IOException; 11 | import java.net.URI; 12 | import java.net.http.HttpClient; 13 | import java.net.http.HttpRequest; 14 | import java.net.http.HttpResponse; 15 | import java.time.Duration; 16 | 17 | import static io.gatling.javaapi.core.CoreDsl.*; 18 | import static io.gatling.javaapi.http.HttpDsl.http; 19 | 20 | public class Case0013RequestBeforeSimulation extends Simulation { 21 | 22 | final String JSONFOO = jsonValue(); 23 | 24 | public String jsonValue() { 25 | HttpClient httpClient = HttpClient.newBuilder() 26 | .version(HttpClient.Version.HTTP_1_1) 27 | .connectTimeout(Duration.ofSeconds(10)) 28 | .build(); 29 | 30 | HttpRequest request = HttpRequest.newBuilder() 31 | .GET() 32 | .uri(URI.create("https://postman-echo.com/get?foo=55555")) 33 | .setHeader("Accept", "application/json") 34 | .build(); 35 | 36 | HttpResponse response; 37 | try { 38 | response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); 39 | } catch (IOException | InterruptedException e) { 40 | throw new RuntimeException(e); 41 | } 42 | 43 | ObjectMapper mapper = new ObjectMapper(); 44 | JsonNode jsonNode; 45 | try { 46 | jsonNode = mapper.readTree(response.body()); 47 | } catch (JsonProcessingException e) { 48 | throw new RuntimeException(e); 49 | } 50 | 51 | //System.out.println(jsonNode.get("args").get("foo").asText()); 52 | return jsonNode.get("args").get("foo").asText(); 53 | } 54 | 55 | HttpProtocolBuilder httpProtocol = 56 | http 57 | .baseUrl("https://postman-echo.com"); 58 | 59 | ScenarioBuilder scn = 60 | scenario("GeMi_RequestBeforeSimulation") 61 | .exec( 62 | http("GeMi_RequestBeforeSimulation_get") 63 | .get("/get?foo=" + JSONFOO) 64 | .check(jmesPath("args.foo").is("55555")) 65 | ); 66 | 67 | { 68 | setUp(scn.injectOpen(atOnceUsers(5)).protocols(httpProtocol)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0006CommandLineParametersSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import static io.gatling.javaapi.core.CoreDsl.*; 8 | import static io.gatling.javaapi.http.HttpDsl.http; 9 | 10 | /** 11 | * HOW TO RUN: 12 | * mvnw gatling:test -Dgatling.simulationClass=pl.gemiusz.Case0006CommandLineParametersSimulation -Dfoo=10 -Dbar=GeMi -Dpercentile3responseTime=15 13 | */ 14 | public class Case0006CommandLineParametersSimulation extends Simulation { 15 | 16 | int foo = Integer.getInteger("foo", 1); 17 | String bar = System.getProperty("bar"); 18 | int percentile3responseTime = Integer.getInteger("percentile3responseTime", 2000); 19 | 20 | HttpProtocolBuilder httpProtocol = 21 | http 22 | .baseUrl("https://postman-echo.com"); 23 | 24 | ScenarioBuilder scn = 25 | scenario("GeMi_CommandLineParametersSimulation") 26 | .exec( 27 | http("GeMi_CommandLineParametersSimulation_get_1") 28 | .get("/get?foo=" + foo + "&bar=" + bar) 29 | .check(jmesPath("args.foo").is(String.valueOf(foo))) 30 | .check(jmesPath("args.bar").is(String.valueOf(bar))) 31 | ).exec( 32 | http("GeMi_CommandLineParametersSimulation_get_2") 33 | .get("/get?foo=" + foo + "&bar=" + bar) 34 | .check(jmesPath("args.foo").is(String.valueOf(foo))) 35 | .check(jmesPath("args.bar").is(String.valueOf(bar))) 36 | ); 37 | 38 | { 39 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)).assertions( 40 | global() 41 | .successfulRequests() 42 | .percent() 43 | .is(100.0) 44 | ) 45 | .assertions( 46 | details("GeMi_CommandLineParametersSimulation_get_1") 47 | .responseTime() 48 | .percentile3() 49 | .lt(percentile3responseTime), 50 | details("GeMi_CommandLineParametersSimulation_get_2") 51 | .responseTime() 52 | .percentile3() 53 | .lt(percentile3responseTime)); 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0001JMESPathSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import static io.gatling.javaapi.core.CoreDsl.*; 11 | import static io.gatling.javaapi.http.HttpDsl.http; 12 | import static io.gatling.javaapi.http.HttpDsl.status; 13 | 14 | public class Case0001JMESPathSimulation extends Simulation { 15 | 16 | HttpProtocolBuilder httpProtocol = 17 | http 18 | .baseUrl("https://postman-echo.com"); 19 | 20 | ScenarioBuilder scn = 21 | scenario("GeMi_JMESPathSimulation") 22 | .exec( 23 | http("GeMi_JMESPathSimulation_post") 24 | .post("/post") 25 | .body(StringBody("{\"status\":\"GOOD\",\"fruits\":[{\"name\":\"Apple\",\"details\":{\"size\":500}},{\"name\":\"Cherry\",\"details\":{\"size\":100}}]}")) 26 | .asJson() 27 | .check( 28 | jmesPath("json.fruits[?details.size >= `500`]") 29 | .ofList() 30 | .is( 31 | List.of( 32 | Map.of("name","Apple", 33 | "details",Map.of( 34 | "size",500 35 | ) 36 | ) 37 | ) 38 | 39 | ) 40 | .saveAs("GeMi_fruitObj") 41 | ) 42 | .check(status().saveAs("GeMi_Response_Code")) 43 | ).exec(session -> { 44 | System.out.println("GeMi_fruitObj: " + session.get("GeMi_fruitObj").toString()); 45 | System.out.println("GeMi_Response_Code: " + session.get("GeMi_Response_Code").toString()); 46 | return session; 47 | }); 48 | 49 | { 50 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/advanced/AdvancedSimulationStep04.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2022 GatlingCorp (https://gatling.io) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package computerdatabase.advanced; 18 | 19 | import static io.gatling.javaapi.core.CoreDsl.*; 20 | import static io.gatling.javaapi.http.HttpDsl.*; 21 | 22 | import io.gatling.javaapi.core.*; 23 | import io.gatling.javaapi.http.*; 24 | 25 | public class AdvancedSimulationStep04 extends Simulation { 26 | 27 | HttpProtocolBuilder httpProtocol = 28 | http.baseUrl("http://computer-database.gatling.io") 29 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") 30 | .doNotTrackHeader("1") 31 | .acceptLanguageHeader("en-US,en;q=0.5") 32 | .acceptEncodingHeader("gzip, deflate") 33 | .userAgentHeader( 34 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0" 35 | ); 36 | 37 | FeederBuilder feeder = csv("feeders/search.csv").random(); 38 | 39 | ChainBuilder search = 40 | exec(http("Home").get("/")) 41 | .pause(1) 42 | .feed(feeder) 43 | .exec( 44 | http("Search") 45 | .get("/computers?f=#{searchCriterion}") 46 | .check(css("a:contains('#{searchComputerName}')", "href").saveAs("computerUrl"))) 47 | .pause(1) 48 | .exec(http("Select").get("#{computerUrl}").check(status().is(200))) 49 | .pause(1); 50 | 51 | ChainBuilder browse = 52 | // Repeat is a loop resolved at RUNTIME 53 | // Note how we force the counter name so we can reuse it 54 | repeat(4, "i").on(exec(http("Page #{i}").get("/computers?p=#{i}")).pause(1)); 55 | 56 | ChainBuilder edit = 57 | exec(http("Form").get("/computers/new")) 58 | .pause(1) 59 | .exec( 60 | http("Post") 61 | .post("/computers") 62 | .formParam("name", "Beautiful Computer") 63 | .formParam("introduced", "2012-05-30") 64 | .formParam("discontinued", "") 65 | .formParam("company", "37")); 66 | 67 | ScenarioBuilder users = scenario("Users").exec(search, browse); 68 | ScenarioBuilder admins = scenario("Admins").exec(search, browse, edit); 69 | 70 | { 71 | setUp(users.injectOpen(rampUsers(10).during(10)), admins.injectOpen(rampUsers(2).during(10))) 72 | .protocols(httpProtocol); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0021CheckResourcesResponseTimeSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import java.time.Duration; 8 | 9 | import static io.gatling.javaapi.core.CoreDsl.*; 10 | import static io.gatling.javaapi.http.HttpDsl.http; 11 | 12 | public class Case0021CheckResourcesResponseTimeSimulation extends Simulation { 13 | 14 | HttpProtocolBuilder httpProtocol = 15 | http 16 | .baseUrl("https://postman-echo.com"); 17 | 18 | 19 | ScenarioBuilder scn = 20 | scenario("GeMi_CheckResourcesResponseTimeSimulation") 21 | .exec( 22 | http("GeMi_CheckResourcesResponseTimeSimulation_get") 23 | .get("/get?foo=01234") 24 | .check(jmesPath("args.foo").isEL("01234")) 25 | .resources( 26 | http("GeMi_CheckResourcesResponseTimeSimulation_async_0") 27 | .get("/get?foo=0") 28 | .check(jmesPath("args.foo").isEL("0")) 29 | .check(responseTimeInMillis().lte(630)), 30 | http("GeMi_CheckResourcesResponseTimeSimulation_async_1") 31 | .get("/get?foo=1") 32 | .check(jmesPath("args.foo").isEL("1")) 33 | .check(responseTimeInMillis().lte(630)), 34 | http("GeMi_CheckResourcesResponseTimeSimulation_async_2") 35 | .get("/get?foo=2") 36 | .check(jmesPath("args.foo").isEL("2")) 37 | .check(responseTimeInMillis().lte(630)), 38 | http("GeMi_CheckResourcesResponseTimeSimulation_async_3") 39 | .get("/get?foo=3") 40 | .check(jmesPath("args.foo").isEL("3")) 41 | .check(responseTimeInMillis().lte(630)), 42 | http("GeMi_CheckResourcesResponseTimeSimulation_async_4") 43 | .get("/get?foo=4") 44 | .check(jmesPath("args.foo").isEL("4")) 45 | .check(responseTimeInMillis().lte(630)) 46 | ) 47 | ); 48 | 49 | { 50 | setUp(scn.injectOpen(constantUsersPerSec(1).during(Duration.ofSeconds(30))).protocols(httpProtocol)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/advanced/AdvancedSimulationStep02.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2022 GatlingCorp (https://gatling.io) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package computerdatabase.advanced; 18 | 19 | import static io.gatling.javaapi.core.CoreDsl.*; 20 | import static io.gatling.javaapi.http.HttpDsl.*; 21 | 22 | import io.gatling.javaapi.core.*; 23 | import io.gatling.javaapi.http.*; 24 | import java.time.Duration; 25 | 26 | public class AdvancedSimulationStep02 extends Simulation { 27 | 28 | HttpProtocolBuilder httpProtocol = 29 | http.baseUrl("http://computer-database.gatling.io") 30 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") 31 | .doNotTrackHeader("1") 32 | .acceptLanguageHeader("en-US,en;q=0.5") 33 | .acceptEncodingHeader("gzip, deflate") 34 | .userAgentHeader( 35 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0" 36 | ); 37 | 38 | ChainBuilder search = 39 | exec(http("Home").get("/")) 40 | .pause(1) 41 | .exec(http("Search").get("/computers?f=macbook")) 42 | .pause(1) 43 | .exec(http("Select").get("/computers/6")) 44 | .pause(1); 45 | 46 | ChainBuilder browse = 47 | exec(http("Home").get("/")) 48 | .pause(2) 49 | .exec(http("Page 1").get("/computers?p=1")) 50 | .pause(Duration.ofMillis(670)) 51 | .exec(http("Page 2").get("/computers?p=2")) 52 | .pause(Duration.ofMillis(629)) 53 | .exec(http("Page 3").get("/computers?p=3")) 54 | .pause(Duration.ofMillis(734)) 55 | .exec(http("Page 4").get("/computers?p=4")) 56 | .pause(5); 57 | 58 | ChainBuilder edit = 59 | exec(http("Form").get("/computers/new")) 60 | .pause(1) 61 | .exec( 62 | http("Post") 63 | .post("/computers") 64 | .formParam("name", "Beautiful Computer") 65 | .formParam("introduced", "2012-05-30") 66 | .formParam("discontinued", "") 67 | .formParam("company", "37")); 68 | 69 | // Let's have multiple populations 70 | ScenarioBuilder users = scenario("Users").exec(search, browse); // regular users can't edit 71 | 72 | ScenarioBuilder admins = scenario("Admins").exec(search, browse, edit); 73 | 74 | { 75 | // Let's have 10 regular users and 2 admins, and ramp them over 10 seconds so we don't hammer 76 | // the server 77 | setUp(users.injectOpen(rampUsers(10).during(10)), admins.injectOpen(rampUsers(2).during(10))) 78 | .protocols(httpProtocol); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/advanced/AdvancedSimulationStep01.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2022 GatlingCorp (https://gatling.io) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package computerdatabase.advanced; 18 | 19 | import static io.gatling.javaapi.core.CoreDsl.*; 20 | import static io.gatling.javaapi.http.HttpDsl.*; 21 | 22 | import io.gatling.javaapi.core.*; 23 | import io.gatling.javaapi.http.*; 24 | import java.time.Duration; 25 | 26 | public class AdvancedSimulationStep01 extends Simulation { 27 | 28 | HttpProtocolBuilder httpProtocol = 29 | http.baseUrl("http://computer-database.gatling.io") 30 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") 31 | .doNotTrackHeader("1") 32 | .acceptLanguageHeader("en-US,en;q=0.5") 33 | .acceptEncodingHeader("gzip, deflate") 34 | .userAgentHeader( 35 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0" 36 | ); 37 | 38 | // Let's split this big scenario into composable business processes, like one would do with the 39 | // PageObject pattern with Selenium 40 | ChainBuilder search = 41 | exec( 42 | // Let's give proper names, they are displayed in the reports, and used as keys 43 | http("Home").get("/")) 44 | .pause(1) // Let's set the pauses to 1 sec for demo purpose 45 | .exec(http("Search").get("/computers?f=macbook")) 46 | .pause(1) 47 | .exec(http("Select").get("/computers/6")) 48 | .pause(1); 49 | 50 | ChainBuilder browse = 51 | exec(http("Home").get("/")) 52 | .pause(2) 53 | .exec(http("Page 1").get("/computers?p=1")) 54 | .pause(Duration.ofMillis(670)) 55 | .exec(http("Page 2").get("/computers?p=2")) 56 | .pause(Duration.ofMillis(629)) 57 | .exec(http("Page 3").get("/computers?p=3")) 58 | .pause(Duration.ofMillis(734)) 59 | .exec(http("Page 4").get("/computers?p=4")) 60 | .pause(5); 61 | 62 | ChainBuilder edit = 63 | exec(http("Form").get("/computers/new")) 64 | .pause(1) 65 | .exec( 66 | http("Post") 67 | .post("/computers") 68 | .formParam("name", "Beautiful Computer") 69 | .formParam("introduced", "2012-05-30") 70 | .formParam("discontinued", "") 71 | .formParam("company", "37")); 72 | 73 | 74 | // Now, we can write the scenario as a composition 75 | ScenarioBuilder scn = scenario("Scenario Name").exec(search, browse, edit); 76 | 77 | { 78 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0010JsonEditVariableSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Session; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.util.Map; 9 | 10 | import static io.gatling.javaapi.core.CoreDsl.*; 11 | import static io.gatling.javaapi.http.HttpDsl.http; 12 | 13 | public class Case0010JsonEditVariableSimulation extends Simulation { 14 | 15 | HttpProtocolBuilder httpProtocol = 16 | http 17 | .baseUrl("https://postman-echo.com"); 18 | 19 | ScenarioBuilder scn = 20 | scenario("GeMi_JsonEditVariableSimulation") 21 | .exec( 22 | http("GeMi_JsonEditVariableSimulation_post") 23 | .post("/post") 24 | .body(StringBody("{\"status\":\"GOOD\",\"fruit\":\"Apple\"}")) 25 | .asJson() 26 | .check( 27 | jmesPath("json") 28 | .ofObject() 29 | .is( 30 | Map.of("status", "GOOD", 31 | "fruit", "Apple" 32 | ) 33 | ) 34 | .saveAs("GeMi_Obj") 35 | ) 36 | ).exec(session -> { 37 | System.out.println("GeMi_Obj: " + session.get("GeMi_Obj").toString()); 38 | Map gemiObj = session.get("GeMi_Obj"); 39 | //changing value from GOOD to BAD 40 | gemiObj.put("status", "BAD"); 41 | Session sessionGeMiObj = session.set("changed_GeMi_Obj", gemiObj); 42 | return sessionGeMiObj; 43 | }).exec( 44 | http("GeMi_JsonEditVariableSimulation_post_changed") 45 | .post("/post") 46 | .body(StringBody("#{changed_GeMi_Obj.jsonStringify()}")) 47 | .asJson() 48 | .check( 49 | jmesPath("json") 50 | .ofObject() 51 | .is( 52 | Map.of("status", "BAD", 53 | "fruit", "Apple" 54 | ) 55 | ) 56 | .saveAs("GeMi_Obj_aftter_change") 57 | ) 58 | ).exec(session -> { 59 | System.out.println("GeMi_Obj_aftter_change: " + session.get("GeMi_Obj_aftter_change").toString()); 60 | return session; 61 | }); 62 | 63 | { 64 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | 6 | pl.gemiusz 7 | gatling-examples-maven-java 8 | 1.0-SNAPSHOT 9 | 10 | GeMi Gatling Examples in JAVA 11 | Gatling project in JAVA showing working examples and solutions - Inspired by Gatling Community 12 | https://github.com/gemiusz/gatling-examples-maven-java 13 | 2022 14 | 15 | 16 | 17 | gemiusz 18 | Gerard Mista 19 | https://github.com/gemiusz 20 | 21 | Author 22 | 23 | Europe/Warsaw 24 | 25 | https://www.linkedin.com/in/gmista 26 | 27 | 28 | 29 | 30 | 31 | scm:git:https://github.com/gemiusz/gatling-examples-maven-java.git 32 | https://github.com/gemiusz/gatling-examples-maven-java 33 | 34 | 35 | 36 | GitHub Issues 37 | https://github.com/gemiusz/gatling-examples-maven-java/issues 38 | 39 | 40 | 41 | 21 42 | UTF-8 43 | 3.14.3 44 | 4.19.0 45 | 3.14.0 46 | 3.4.2 47 | 3.3.2 48 | 49 | 50 | 51 | 52 | io.gatling.highcharts 53 | gatling-charts-highcharts 54 | ${gatling.version} 55 | test 56 | 57 | 58 | 59 | 60 | 61 | 62 | maven-compiler-plugin 63 | ${maven-compiler-plugin.version} 64 | 65 | 66 | maven-jar-plugin 67 | ${maven-jar-plugin.version} 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-wrapper-plugin 72 | ${maven-wrapper-plugin.version} 73 | 74 | 75 | io.gatling 76 | gatling-maven-plugin 77 | ${gatling-maven-plugin.version} 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0018GetTokenWhenStatus401Simulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Simulation; 5 | import io.gatling.javaapi.http.HttpProtocolBuilder; 6 | 7 | import java.util.*; 8 | import java.util.function.Supplier; 9 | import java.util.stream.Stream; 10 | 11 | import static io.gatling.javaapi.core.CoreDsl.*; 12 | import static io.gatling.javaapi.http.HttpDsl.http; 13 | import static io.gatling.javaapi.http.HttpDsl.status; 14 | 15 | public class Case0018GetTokenWhenStatus401Simulation extends Simulation { 16 | 17 | HttpProtocolBuilder httpProtocol = 18 | http 19 | .baseUrl("https://postman-echo.com"); 20 | 21 | Iterator> feeder200or401 = 22 | Stream.generate((Supplier>) () -> { 23 | int randomOfTwoInts = new Random().nextBoolean() ? 200 : 401; 24 | return Collections.singletonMap("statusHttp", randomOfTwoInts); 25 | } 26 | ).iterator(); 27 | 28 | Iterator> feederUUID = 29 | Stream.generate((Supplier>) () -> { 30 | String uuidString = UUID.randomUUID().toString(); 31 | return Collections.singletonMap("uuidString", uuidString); 32 | } 33 | ).iterator(); 34 | 35 | String globalToken = "StartingToken"; 36 | 37 | ScenarioBuilder scn = 38 | scenario("GeMi_GetTokenWhenStatus401") 39 | .feed(feeder200or401) 40 | .exec( 41 | http("GeMi_GetTokenWhenStatus401_get_status") 42 | .get("/status/#{statusHttp}") 43 | .header("Token", session -> this.globalToken) 44 | .check( 45 | status() 46 | .isEL("#{statusHttp}") 47 | .saveAs("GeMi_Status_Code") 48 | ) 49 | ) 50 | .doIfEquals("#{GeMi_Status_Code}", 401) 51 | .then( 52 | feed(feederUUID) 53 | .exec( 54 | http("GeMi_GetTokenWhenStatus401_get_token") 55 | .post("/post") 56 | .body(StringBody(""" 57 | { 58 | "UUIDasToken": "#{uuidString}" 59 | } 60 | """) 61 | ) 62 | .asJson() 63 | .check( 64 | jmesPath("json.UUIDasToken") 65 | .isEL("#{uuidString}") 66 | .saveAs("uuidAsToken") 67 | ) 68 | ) 69 | .exec(session -> { 70 | this.globalToken = session.getString("uuidAsToken"); 71 | return session; 72 | } 73 | ) 74 | ); 75 | 76 | { 77 | setUp(scn.injectOpen(constantUsersPerSec(1).during(3)).protocols(httpProtocol)); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/advanced/AdvancedSimulationStep05.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2022 GatlingCorp (https://gatling.io) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package computerdatabase.advanced; 18 | 19 | import static io.gatling.javaapi.core.CoreDsl.*; 20 | import static io.gatling.javaapi.http.HttpDsl.*; 21 | 22 | import io.gatling.javaapi.core.*; 23 | import io.gatling.javaapi.http.*; 24 | import java.util.concurrent.ThreadLocalRandom; 25 | 26 | public class AdvancedSimulationStep05 extends Simulation { 27 | 28 | HttpProtocolBuilder httpProtocol = 29 | http.baseUrl("http://computer-database.gatling.io") 30 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") 31 | .doNotTrackHeader("1") 32 | .acceptLanguageHeader("en-US,en;q=0.5") 33 | .acceptEncodingHeader("gzip, deflate") 34 | .userAgentHeader( 35 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0" 36 | ); 37 | 38 | FeederBuilder feeder = csv("feeders/search.csv").random(); 39 | 40 | ChainBuilder search = 41 | exec(http("Home").get("/")) 42 | .pause(1) 43 | .feed(feeder) 44 | .exec( 45 | http("Search") 46 | .get("/computers?f=#{searchCriterion}") 47 | .check(css("a:contains('#{searchComputerName}')", "href").saveAs("computerUrl"))) 48 | .pause(1) 49 | .exec(http("Select").get("#{computerUrl}").check(status().is(200))) 50 | .pause(1); 51 | 52 | ChainBuilder browse = 53 | // Repeat is a loop resolved at RUNTIME 54 | // Note how we force the counter name so we can reuse it 55 | repeat(4, "i").on(exec(http("Page #{i}").get("/computers?p=#{i}")).pause(1)); 56 | 57 | // Note we should be using a feeder here 58 | // Let's demonstrate how we can retry: let's make the request fail randomly and retry a given 59 | // number of times 60 | ChainBuilder edit = 61 | // Let's try at max 2 times 62 | tryMax(2) 63 | .on( 64 | exec(http("Form").get("/computers/new")) 65 | .pause(1) 66 | .exec( 67 | http("Post") 68 | .post("/computers") 69 | .formParam("name", "Beautiful Computer") 70 | .formParam("introduced", "2012-05-30") 71 | .formParam("discontinued", "") 72 | .formParam("company", "37") 73 | .check( 74 | status() 75 | .is( 76 | // We do a check on a condition that's been customized with 77 | // a lambda. It will be evaluated every time a user executes 78 | // the request. 79 | session -> 200 + ThreadLocalRandom.current().nextInt(2))))) 80 | // If the chain didn't finally succeed, have the user exit the whole scenario 81 | .exitHereIfFailed(); 82 | 83 | ScenarioBuilder users = scenario("Users").exec(search, browse); 84 | ScenarioBuilder admins = scenario("Admins").exec(search, browse, edit); 85 | 86 | { 87 | setUp(users.injectOpen(rampUsers(10).during(10)), admins.injectOpen(rampUsers(2).during(10))) 88 | .protocols(httpProtocol); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0016ScenarioDurationSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Session; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.time.Duration; 9 | import java.util.UUID; 10 | 11 | import static io.gatling.javaapi.core.CoreDsl.*; 12 | import static io.gatling.javaapi.http.HttpDsl.http; 13 | 14 | public class Case0016ScenarioDurationSimulation extends Simulation { 15 | 16 | HttpProtocolBuilder httpProtocol = 17 | http 18 | .baseUrl("https://postman-echo.com"); 19 | 20 | ScenarioBuilder scn1 = 21 | scenario("GeMi_ScenarioDurationSimulation_1") 22 | .exec(session -> { 23 | Session session1 = session 24 | .set("GeMi_ScenarioDurationSimulation_1_start", System.nanoTime()) 25 | .set("uuidString", UUID.randomUUID().toString()); 26 | return session1; 27 | }) 28 | .exec( 29 | http("GeMi_ScenarioDurationSimulation_get_1_1") 30 | .get("/get?foo=#{uuidString}") 31 | .check(jmesPath("args.foo").isEL("#{uuidString}")) 32 | ).exec( 33 | http("GeMi_ScenarioDurationSimulation_get_1_2") 34 | .get("/get?foo=#{uuidString}") 35 | .check(jmesPath("args.foo").isEL("#{uuidString}")) 36 | ) 37 | .pause(Duration.ofMillis(100)) 38 | .exec( 39 | http("GeMi_ScenarioDurationSimulation_get_1_3") 40 | .get("/get?foo=#{uuidString}") 41 | .check(jmesPath("args.foo").isEL("#{uuidString}")) 42 | ).exec(session -> { 43 | long howLong = System.nanoTime() - session.getLong("GeMi_ScenarioDurationSimulation_1_start"); 44 | System.out.println("Scenario GeMi_ScenarioDurationSimulation_1 take: " + howLong + " ns"); 45 | return session; 46 | }); 47 | 48 | ScenarioBuilder scn2 = 49 | scenario("GeMi_ScenarioDurationSimulation_2") 50 | .exec(session -> { 51 | Session session1 = session 52 | .set("GeMi_ScenarioDurationSimulation_2_start", System.nanoTime()) 53 | .set("uuidString", UUID.randomUUID().toString()); 54 | return session1; 55 | }) 56 | .exec( 57 | http("GeMi_ScenarioDurationSimulation_get_2_1") 58 | .get("/get?foo=#{uuidString}") 59 | .check(jmesPath("args.foo").isEL("#{uuidString}")) 60 | ) 61 | .pause(Duration.ofSeconds(1)) 62 | .exec( 63 | http("GeMi_ScenarioDurationSimulation_get_2_2") 64 | .get("/get?foo=#{uuidString}") 65 | .check(jmesPath("args.foo").isEL("#{uuidString}")) 66 | ).exec(session -> { 67 | long howLong = System.nanoTime() - session.getLong("GeMi_ScenarioDurationSimulation_2_start"); 68 | System.out.println("Scenario GeMi_ScenarioDurationSimulation_2 take: " + howLong + " ns"); 69 | return session; 70 | }); 71 | 72 | { 73 | setUp(scn1.injectOpen(constantUsersPerSec(1).during(Duration.ofSeconds(5))).protocols(httpProtocol), 74 | scn2.injectOpen(constantUsersPerSec(1).during(Duration.ofSeconds(5))).protocols(httpProtocol)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/advanced/AdvancedSimulationStep03.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2022 GatlingCorp (https://gatling.io) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package computerdatabase.advanced; 18 | 19 | import static io.gatling.javaapi.core.CoreDsl.*; 20 | import static io.gatling.javaapi.http.HttpDsl.*; 21 | 22 | import io.gatling.javaapi.core.*; 23 | import io.gatling.javaapi.http.*; 24 | import java.time.Duration; 25 | 26 | public class AdvancedSimulationStep03 extends Simulation { 27 | 28 | HttpProtocolBuilder httpProtocol = 29 | http.baseUrl("http://computer-database.gatling.io") 30 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") 31 | .doNotTrackHeader("1") 32 | .acceptLanguageHeader("en-US,en;q=0.5") 33 | .acceptEncodingHeader("gzip, deflate") 34 | .userAgentHeader( 35 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0" 36 | ); 37 | 38 | // We need dynamic data so that all users don't play the same and we end up with a behavior 39 | // completely different from the live system (caching, JIT...) 40 | // ==> Feeders! 41 | 42 | // Default is queue, so for this test, we use random to avoid feeder starvation 43 | FeederBuilder feeder = csv("feeders/search.csv").random(); 44 | 45 | ChainBuilder search = 46 | exec(http("Home").get("/")) 47 | .pause(1) 48 | // Every time a user passes here, a record is popped from the feeder and 49 | // injected into the user's session 50 | .feed(feeder) 51 | .exec( 52 | http("Search") 53 | // Use session data thanks to Gatling's EL 54 | .get("/computers?f=#{searchCriterion}") 55 | .check( 56 | // Use a CSS selector with an EL, save the result of the capture group 57 | css("a:contains('#{searchComputerName}')", "href").saveAs("computerUrl"))) 58 | .pause(1) 59 | .exec( 60 | http("Select") 61 | // Use the link previously saved 62 | .get("#{computerUrl}") 63 | .check(status().is(200))) 64 | .pause(1); 65 | 66 | ChainBuilder browse = 67 | exec(http("Home").get("/")) 68 | .pause(2) 69 | .exec(http("Page 1").get("/computers?p=1")) 70 | .pause(Duration.ofMillis(670)) 71 | .exec(http("Page 2").get("/computers?p=2")) 72 | .pause(Duration.ofMillis(629)) 73 | .exec(http("Page 3").get("/computers?p=3")) 74 | .pause(Duration.ofMillis(734)) 75 | .exec(http("Page 4").get("/computers?p=4")) 76 | .pause(5); 77 | 78 | ChainBuilder edit = 79 | exec(http("Form").get("/computers/new")) 80 | .pause(1) 81 | .exec( 82 | http("Post") 83 | .post("/computers") 84 | .formParam("name", "Beautiful Computer") 85 | .formParam("introduced", "2012-05-30") 86 | .formParam("discontinued", "") 87 | .formParam("company", "37")); 88 | 89 | ScenarioBuilder users = scenario("Users").exec(search, browse); 90 | ScenarioBuilder admins = scenario("Admins").exec(search, browse, edit); 91 | 92 | { 93 | setUp(users.injectOpen(rampUsers(10).during(10)), admins.injectOpen(rampUsers(2).during(10))) 94 | .protocols(httpProtocol); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/computerdatabase/ComputerDatabaseSimulation.java: -------------------------------------------------------------------------------- 1 | package computerdatabase; 2 | 3 | import io.gatling.javaapi.core.ChainBuilder; 4 | import io.gatling.javaapi.core.FeederBuilder; 5 | import io.gatling.javaapi.core.ScenarioBuilder; 6 | import io.gatling.javaapi.core.Simulation; 7 | import io.gatling.javaapi.http.HttpProtocolBuilder; 8 | 9 | import java.util.concurrent.ThreadLocalRandom; 10 | 11 | import static io.gatling.javaapi.core.CoreDsl.*; 12 | import static io.gatling.javaapi.http.HttpDsl.http; 13 | import static io.gatling.javaapi.http.HttpDsl.status; 14 | 15 | /** 16 | * This sample is based on our official tutorials: 17 | * 21 | */ 22 | public class ComputerDatabaseSimulation extends Simulation { 23 | HttpProtocolBuilder httpProtocol = 24 | http.baseUrl("https://computer-database.gatling.io") 25 | .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") 26 | .acceptLanguageHeader("en-US,en;q=0.5") 27 | .acceptEncodingHeader("gzip, deflate") 28 | .userAgentHeader( 29 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0" 30 | ); 31 | 32 | FeederBuilder feeder = csv("feeders/search.csv").random(); 33 | 34 | ChainBuilder search = exec( 35 | http("Home").get("/"), 36 | pause(1), 37 | feed(feeder), 38 | http("Search") 39 | .get("/computers?f=#{searchCriterion}") 40 | .check( 41 | css("a:contains('#{searchComputerName}')", "href").saveAs("computerUrl") 42 | ), 43 | pause(1), 44 | http("Select") 45 | .get("#{computerUrl}") 46 | .check(status().is(200)), 47 | pause(1) 48 | ); 49 | 50 | // repeat is a loop resolved at RUNTIME 51 | ChainBuilder browse = 52 | // Note how we force the counter name, so we can reuse it 53 | repeat(4, "i").on( 54 | http("Page #{i}").get("/computers?p=#{i}"), 55 | pause(1) 56 | ); 57 | 58 | // Note we should be using a feeder here 59 | // let's demonstrate how we can retry: let's make the request fail randomly and retry a given 60 | // number of times 61 | 62 | ChainBuilder edit = 63 | // let's try at max 2 times 64 | tryMax(2) 65 | .on( 66 | http("Form").get("/computers/new"), 67 | pause(1), 68 | http("Post") 69 | .post("/computers") 70 | .formParam("name", "Beautiful Computer") 71 | .formParam("introduced", "2012-05-30") 72 | .formParam("discontinued", "") 73 | .formParam("company", "37") 74 | .check( 75 | status().is( 76 | // we do a check on a condition that's been customized with 77 | // a lambda. It will be evaluated every time a user executes 78 | // the request 79 | session -> 200 + ThreadLocalRandom.current().nextInt(2) 80 | ) 81 | ) 82 | ) 83 | // if the chain didn't finally succeed, have the user exit the whole scenario 84 | .exitHereIfFailed(); 85 | 86 | 87 | ScenarioBuilder users = scenario("Users").exec(search, browse); 88 | ScenarioBuilder admins = scenario("Admins").exec(search, browse, edit); 89 | 90 | { 91 | setUp( 92 | users.injectOpen(rampUsers(10).during(10)), 93 | admins.injectOpen(rampUsers(2).during(10)) 94 | ).protocols(httpProtocol); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0024IterationLoopCondition.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.CoreDsl; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import static io.gatling.javaapi.core.CoreDsl.*; 12 | import static io.gatling.javaapi.http.HttpDsl.http; 13 | 14 | public class Case0024IterationLoopCondition extends Simulation { 15 | 16 | HttpProtocolBuilder httpProtocol = 17 | http 18 | .baseUrl("https://postman-echo.com"); 19 | 20 | ScenarioBuilder scn = 21 | scenario("GeMi_IterationLoopCondition") 22 | .exec( 23 | http("GeMi_IterationLoopCondition_post_to_get_accounts_list") 24 | .post("/post") 25 | .body(StringBody("{\"accounts\":[{\"accountID\":\"123\",\"status\":\"ACTIVE\",\"accountType\":\"X\"},{\"accountID\":\"456\",\"status\":\"ACTIVE\",\"accountType\":\"Y\"},{\"accountID\":\"789\",\"status\":\"ACTIVE\",\"accountType\":\"Z\"}]}")) 26 | .asJson() 27 | .check( 28 | jmesPath("json.accounts") 29 | .ofList() 30 | .is( 31 | List.of( 32 | Map.of("accountID","123", 33 | "status", "ACTIVE", 34 | "accountType", "X" 35 | ), 36 | Map.of("accountID","456", 37 | "status", "ACTIVE", 38 | "accountType", "Y" 39 | ), 40 | Map.of("accountID","789", 41 | "status", "ACTIVE", 42 | "accountType", "Z" 43 | ) 44 | ) 45 | ) 46 | .saveAs("GeMi_accountsObj") 47 | ) 48 | ) 49 | .foreach("#{GeMi_accountsObj}", "account").on( 50 | exec( 51 | doSwitch("#{account.accountType}").on( 52 | CoreDsl.onCase("X").then( 53 | exec( 54 | http("GeMi_IterationLoopCondition_get_account_X") 55 | .get("/get?foo=#{account.accountID}") 56 | .asJson() 57 | .check(jmesPath("args.foo").isEL("123")) 58 | ) 59 | ), 60 | CoreDsl.onCase("Y").then( 61 | exec( 62 | http("GeMi_IterationLoopCondition_get_account_Y") 63 | .get("/get?foo=#{account.accountID}") 64 | .asJson() 65 | .check(jmesPath("args.foo").isEL("456")) 66 | ) 67 | ), 68 | CoreDsl.onCase("Z").then( 69 | exec( 70 | http("GeMi_IterationLoopCondition_get_account_Z") 71 | .get("/get?foo=#{account.accountID}") 72 | .asJson() 73 | .check(jmesPath("args.foo").isEL("789")) 74 | ) 75 | ) 76 | ) 77 | ) 78 | ); 79 | 80 | { 81 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0022SetOrRefreshTokenSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ChainBuilder; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.time.Duration; 9 | import java.time.Instant; 10 | import java.util.Collections; 11 | import java.util.Iterator; 12 | import java.util.Map; 13 | import java.util.UUID; 14 | import java.util.function.Supplier; 15 | import java.util.stream.Stream; 16 | 17 | import static io.gatling.javaapi.core.CoreDsl.*; 18 | import static io.gatling.javaapi.http.HttpDsl.http; 19 | 20 | public class Case0022SetOrRefreshTokenSimulation extends Simulation { 21 | String tokenString = "NOT_SET"; 22 | boolean tokenRefreshContinue = true; 23 | Instant tokenRefreshInstant = Instant.now(); 24 | int refreshTokenEverySeconds = 10; 25 | 26 | HttpProtocolBuilder httpProtocol = 27 | http 28 | .baseUrl("https://postman-echo.com").shareConnections(); 29 | 30 | 31 | Iterator> feederUUID = 32 | Stream.generate((Supplier>) () -> { 33 | String uuidString = UUID.randomUUID().toString(); 34 | return Collections.singletonMap("uuidString", uuidString); 35 | } 36 | ).iterator(); 37 | 38 | ChainBuilder chainGenerateAndSetToken = 39 | feed(feederUUID) 40 | .exec( 41 | http("GeMi_GenerateAndSetToken_get") 42 | .get("/get") 43 | .queryParam("foo", "#{uuidString}") 44 | .silent() 45 | .check(jmesPath("args.foo").isEL("#{uuidString}").saveAs("tokenStringNew")) 46 | ).exec(session -> { 47 | System.out.println("GeMi_GenerateAndSetToken_uuidString: " + session.get("uuidString")); 48 | System.out.println("GeMi_GenerateAndSetToken_tokenStringNew: " + session.get("tokenStringNew")); 49 | tokenString = session.get("tokenStringNew"); 50 | return session; 51 | }); 52 | 53 | ScenarioBuilder scnForSetFirstToken = 54 | scenario("GeMi_SetFirstToken").exec(chainGenerateAndSetToken); 55 | 56 | ScenarioBuilder scnForRefreshToken = 57 | scenario("GeMi_RefreshToken") 58 | .asLongAs(session -> tokenRefreshContinue) 59 | .on( 60 | pause(Duration.ofSeconds(1)) 61 | .doIf(session -> tokenRefreshInstant.plusSeconds(refreshTokenEverySeconds).isBefore(Instant.now())) 62 | .then( 63 | exec(session -> { 64 | tokenRefreshInstant = Instant.now(); 65 | return session; 66 | }) 67 | .exec(chainGenerateAndSetToken) 68 | ) 69 | ); 70 | 71 | ScenarioBuilder scnForRefreshTokenAbort = 72 | scenario("GeMi_RefreshTokenAbort").exec(session -> { 73 | tokenRefreshContinue = false; 74 | return session; 75 | }); 76 | 77 | ScenarioBuilder scn = 78 | scenario("GeMi_SomeRequestWithToken") 79 | // Don't forget to set the uptodate token for every request 80 | .exec(session -> session.set("tokenStringSession", tokenString)) 81 | .exec( 82 | http("GeMi_SomeRequestWithToken_get") 83 | .get("/get") 84 | .queryParam("foo", "#{tokenStringSession}") 85 | .check(jmesPath("args.foo").saveAs("tokenString4Print")) 86 | .check(jmesPath("args.foo").not("NOT_SET")) 87 | //.check(jmesPath("args.foo").is(session -> tokenString)) 88 | ).exec(session -> { 89 | System.out.println("----------------------------------------------------------"); 90 | System.out.println("GeMi_SomeRequestWithToken_tokenString: " + tokenString); 91 | System.out.println("GeMi_SomeRequestWithToken_tokenStringSession: " + session.getString("tokenStringSession")); 92 | System.out.println("GeMi_SomeRequestWithToken_tokenString4Print: " + session.getString("tokenString4Print")); 93 | System.out.println("----------------------------------------------------------"); 94 | return session; 95 | }); 96 | 97 | 98 | { 99 | setUp(scnForSetFirstToken.injectOpen(atOnceUsers(1)) 100 | .andThen( 101 | scnForRefreshToken.injectOpen(atOnceUsers(1)), 102 | //-------------------------------- 103 | scn.injectOpen( 104 | constantUsersPerSec(10).during(30) 105 | ) 106 | //-------------------------------- 107 | .andThen(scnForRefreshTokenAbort.injectOpen(atOnceUsers(1))) 108 | ) 109 | ).protocols(httpProtocol); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0008AsyncReqResourcesSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.CoreDsl; 4 | import io.gatling.javaapi.core.ScenarioBuilder; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | import io.netty.util.internal.ThreadLocalRandom; 8 | 9 | import java.util.Collections; 10 | import java.util.Iterator; 11 | import java.util.Map; 12 | import java.util.function.Supplier; 13 | import java.util.stream.Stream; 14 | 15 | import static io.gatling.javaapi.core.CoreDsl.*; 16 | import static io.gatling.javaapi.http.HttpDsl.http; 17 | 18 | public class Case0008AsyncReqResourcesSimulation extends Simulation { 19 | 20 | HttpProtocolBuilder httpProtocol = 21 | http 22 | .baseUrl("https://postman-echo.com"); 23 | 24 | Iterator> feederInt = 25 | Stream.generate((Supplier>) () -> { 26 | int min = 3; 27 | int max = 6; 28 | int randomInt = ThreadLocalRandom.current().nextInt(min, max); 29 | return Collections.singletonMap("randomInt", randomInt); 30 | } 31 | ).iterator(); 32 | 33 | ScenarioBuilder scn = 34 | scenario("GeMi_AsyncReqResourcesSimulation") 35 | .feed(feederInt) 36 | .doSwitch("#{randomInt}").on( 37 | CoreDsl.onCase(3).then( 38 | exec( 39 | http("GeMi_AsyncReqResourcesSimulation_get") 40 | .get("/get?foo=#{randomInt}") 41 | .check(jmesPath("args.foo").isEL("#{randomInt}")) 42 | .resources( 43 | http("GeMi_AsyncReqResourcesSimulation_async_0") 44 | .get("/get?foo=0") 45 | .check(jmesPath("args.foo").isEL("0")), 46 | http("GeMi_AsyncReqResourcesSimulation_async_1") 47 | .get("/get?foo=1") 48 | .check(jmesPath("args.foo").isEL("1")), 49 | http("GeMi_AsyncReqResourcesSimulation_async_2") 50 | .get("/get?foo=2") 51 | .check(jmesPath("args.foo").isEL("2")) 52 | ) 53 | ) 54 | ), 55 | CoreDsl.onCase(4).then( 56 | exec( 57 | http("GeMi_AsyncReqResourcesSimulation_get") 58 | .get("/get?foo=#{randomInt}") 59 | .check(jmesPath("args.foo").isEL("#{randomInt}")) 60 | .resources( 61 | http("GeMi_AsyncReqResourcesSimulation_async_0") 62 | .get("/get?foo=0") 63 | .check(jmesPath("args.foo").isEL("0")), 64 | http("GeMi_AsyncReqResourcesSimulation_async_1") 65 | .get("/get?foo=1") 66 | .check(jmesPath("args.foo").isEL("1")), 67 | http("GeMi_AsyncReqResourcesSimulation_async_2") 68 | .get("/get?foo=2") 69 | .check(jmesPath("args.foo").isEL("2")), 70 | http("GeMi_AsyncReqResourcesSimulation_async_3") 71 | .get("/get?foo=3") 72 | .check(jmesPath("args.foo").isEL("3")) 73 | ) 74 | ) 75 | ), 76 | CoreDsl.onCase(5).then( 77 | exec( 78 | http("GeMi_AsyncReqResourcesSimulation_get") 79 | .get("/get?foo=#{randomInt}") 80 | .check(jmesPath("args.foo").isEL("#{randomInt}")) 81 | .resources( 82 | http("GeMi_AsyncReqResourcesSimulation_async_0") 83 | .get("/get?foo=0") 84 | .check(jmesPath("args.foo").isEL("0")), 85 | http("GeMi_AsyncReqResourcesSimulation_async_1") 86 | .get("/get?foo=1") 87 | .check(jmesPath("args.foo").isEL("1")), 88 | http("GeMi_AsyncReqResourcesSimulation_async_2") 89 | .get("/get?foo=2") 90 | .check(jmesPath("args.foo").isEL("2")), 91 | http("GeMi_AsyncReqResourcesSimulation_async_3") 92 | .get("/get?foo=3") 93 | .check(jmesPath("args.foo").isEL("3")), 94 | http("GeMi_AsyncReqResourcesSimulation_async_4") 95 | .get("/get?foo=4") 96 | .check(jmesPath("args.foo").isEL("4")) 97 | ) 98 | ) 99 | ) 100 | ); 101 | 102 | { 103 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM http://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | if ($env:MAVEN_USER_HOME) { 83 | $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" 84 | } 85 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 86 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 87 | 88 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 89 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 90 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 91 | exit $? 92 | } 93 | 94 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 95 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 96 | } 97 | 98 | # prepare tmp dir 99 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 100 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 101 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 102 | trap { 103 | if ($TMP_DOWNLOAD_DIR.Exists) { 104 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 105 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 106 | } 107 | } 108 | 109 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 110 | 111 | # Download and Install Apache Maven 112 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 113 | Write-Verbose "Downloading from: $distributionUrl" 114 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 115 | 116 | $webclient = New-Object System.Net.WebClient 117 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 118 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 119 | } 120 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 121 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 122 | 123 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 124 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 125 | if ($distributionSha256Sum) { 126 | if ($USE_MVND) { 127 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 128 | } 129 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 130 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 131 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 132 | } 133 | } 134 | 135 | # unzip and move 136 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 137 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 138 | try { 139 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 140 | } catch { 141 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 142 | Write-Error "fail to move MAVEN_HOME" 143 | } 144 | } finally { 145 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 146 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 147 | } 148 | 149 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 150 | -------------------------------------------------------------------------------- /src/test/java/pl/gemiusz/Case0017ForeachAfterForeachSimulation.java: -------------------------------------------------------------------------------- 1 | package pl.gemiusz; 2 | 3 | import io.gatling.javaapi.core.ScenarioBuilder; 4 | import io.gatling.javaapi.core.Session; 5 | import io.gatling.javaapi.core.Simulation; 6 | import io.gatling.javaapi.http.HttpProtocolBuilder; 7 | 8 | import java.util.Map; 9 | 10 | import static io.gatling.javaapi.core.CoreDsl.*; 11 | import static io.gatling.javaapi.http.HttpDsl.http; 12 | 13 | public class Case0017ForeachAfterForeachSimulation extends Simulation { 14 | 15 | HttpProtocolBuilder httpProtocol = 16 | http 17 | .baseUrl("https://postman-echo.com"); 18 | 19 | ScenarioBuilder scn = 20 | scenario("GeMi_ForeachAfterForeachSimulation") 21 | .exec( 22 | http("GeMi_ForeachAfterForeachSimulation_langs_post") 23 | .post("/post") 24 | .body(StringBody(""" 25 | { 26 | "langs": [ 27 | "pl", 28 | "fr", 29 | "en" 30 | ] 31 | } 32 | """) 33 | ) 34 | .asJson() 35 | .check( 36 | jmesPath("json.langs") 37 | .ofList() 38 | .saveAs("GeMi_langs") 39 | ) 40 | ).exec(session -> { 41 | System.out.println("GeMi_langs: " + session.getString("GeMi_langs")); 42 | return session; 43 | }).foreach("#{GeMi_langs}", "GeMi_langs_el").on( 44 | exec(session -> { 45 | System.out.println("GeMi_langs_el: " + session.getString("GeMi_langs_el")); 46 | return session; 47 | }) 48 | ).exec( 49 | http("GeMi_ForeachAfterForeachSimulation_curses_post") 50 | .post("/post") 51 | .body(StringBody(""" 52 | { 53 | "curses": [ 54 | { 55 | "pictureId": 1, 56 | "language": "pl" 57 | }, 58 | { 59 | "pictureId": 3, 60 | "language": "en" 61 | }, 62 | { 63 | "pictureId": 2, 64 | "language": "fr" 65 | }, 66 | { 67 | "pictureId": 5, 68 | "language": "pl" 69 | } 70 | ] 71 | } 72 | """) 73 | ) 74 | .asJson() 75 | .check( 76 | jmesPath("json.curses") 77 | .ofList() 78 | .saveAs("GeMi_curses") 79 | ) 80 | ).exec(session -> { 81 | System.out.println("GeMi_curses: " + session.getString("GeMi_curses")); 82 | return session; 83 | }).foreach("#{GeMi_curses}", "GeMi_curses_el").on( 84 | exec(session -> { 85 | System.out.println("GeMi_curses_el: " + session.getString("GeMi_curses_el")); 86 | return session; 87 | }) 88 | ).foreach("#{GeMi_langs}", "GeMi_langs_el").on( 89 | exec(session -> { 90 | System.out.println("------------------------------------------------------------------------------"); 91 | System.out.println("- GeMi_langs_el: " + session.getString("GeMi_langs_el")); 92 | return session; 93 | }).foreach("#{GeMi_curses}", "GeMi_curses_el").on( 94 | exec(session -> { 95 | System.out.println("-- GeMi_curses_el: " + session.getString("GeMi_curses_el")); 96 | Map gemiCursesElObj = session.getMap("GeMi_curses_el"); 97 | if (session.getString("GeMi_langs_el").equals(gemiCursesElObj.get("language").toString())) { 98 | System.out.println("--- GeMi_langs_el EQ GeMi_curses_el_language -> " + session.getString("GeMi_langs_el") + " " + session.getString("GeMi_curses_el")); 99 | Session sessionTrue = session.set("GeMi_pictureId", gemiCursesElObj.get("pictureId")).set("GeMi_isThisLang", true); 100 | return sessionTrue; 101 | } 102 | System.out.println("--- GeMi_langs_el NE GeMi_curses_el_language -> " + session.getString("GeMi_langs_el") + " " + session.getString("GeMi_curses_el")); 103 | Session sessionFalse = session.set("GeMi_isThisLang", false); 104 | return sessionFalse; 105 | }).doIf("#{GeMi_isThisLang}").then( 106 | exec(session -> { 107 | System.out.println("---- Do something using GeMi_pictureId: " + session.getString("GeMi_pictureId")); 108 | return session; 109 | }).exec( 110 | http("GeMi_ForeachAfterForeachSimulation_pictureId_#{GeMi_pictureId}_get") 111 | .get("/get?pictureId=#{GeMi_pictureId}") 112 | .check(jmesPath("args.pictureId").isEL("#{GeMi_pictureId}")) 113 | ) 114 | ) 115 | ) 116 | ); 117 | 118 | { 119 | setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol)); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/test/resources/gatling.conf: -------------------------------------------------------------------------------- 1 | ######################### 2 | # Gatling Configuration # 3 | ######################### 4 | 5 | # This file contains all the settings configurable for Gatling with their default values 6 | 7 | gatling { 8 | core { 9 | #encoding = "utf-8" # Encoding to use throughout Gatling for file and string manipulation 10 | #elFileBodiesCacheMaxCapacity = 200 # Cache size for request body EL templates, set to 0 to disable 11 | #rawFileBodiesCacheMaxCapacity = 200 # Cache size for request body raw files, set to 0 to disable 12 | #rawFileBodiesInMemoryMaxSize = 10240 # Max bite size of raw files to be cached in memory 13 | #pebbleFileBodiesCacheMaxCapacity = 200 # Cache size for request body Pebble templates, set to 0 to disable 14 | #feederAdaptiveLoadModeThreshold = 100 # File size threshold (in MB). Below load eagerly in memory, above use batch mode with default buffer size 15 | #shutdownTimeout = 10000 # Milliseconds to wait for the actor system to shutdown 16 | extract { 17 | regex { 18 | #cacheMaxCapacity = 200 # Cache size for the compiled regexes, set to 0 to disable caching 19 | } 20 | xpath { 21 | #cacheMaxCapacity = 200 # Cache size for the compiled XPath queries, set to 0 to disable caching 22 | } 23 | jsonPath { 24 | #cacheMaxCapacity = 200 # Cache size for the compiled jsonPath queries, set to 0 to disable caching 25 | } 26 | css { 27 | #cacheMaxCapacity = 200 # Cache size for the compiled CSS selectors queries, set to 0 to disable caching 28 | } 29 | } 30 | } 31 | socket { 32 | #connectTimeout = 10000 # Timeout in millis for establishing a TCP socket 33 | #tcpNoDelay = true 34 | #soKeepAlive = false # if TCP keepalive configured at OS level should be used 35 | #soReuseAddress = false 36 | } 37 | netty { 38 | #useNativeTransport = true # if Netty Linux native transport should be used instead of Java NIO 39 | #useIoUring = false # if io_uring should be used instead of epoll if available 40 | #allocator = "pooled" # switch to unpooled for unpooled ByteBufAllocator 41 | #maxThreadLocalCharBufferSize = 200000 # Netty's default is 16k 42 | } 43 | ssl { 44 | #useOpenSsl = true # if OpenSSL should be used instead of JSSE (only the latter can be debugged with -Djavax.net.debug=ssl) 45 | #useOpenSslFinalizers = false # if OpenSSL contexts should be freed with Finalizer or if using RefCounted is fine 46 | #handshakeTimeout = 10000 # TLS handshake timeout in millis 47 | #useInsecureTrustManager = true # Use an insecure TrustManager that trusts all server certificates 48 | #enabledProtocols = [] # Array of enabled protocols for HTTPS, if empty use Netty's defaults 49 | #enabledCipherSuites = [] # Array of enabled cipher suites for HTTPS, if empty enable all available ciphers 50 | #sessionCacheSize = 0 # SSLSession cache size, set to 0 to use JDK's default 51 | #sessionTimeout = 0 # SSLSession timeout in seconds, set to 0 to use JDK's default (24h) 52 | #enableSni = true # When set to true, enable Server Name indication (SNI) 53 | keyStore { 54 | #type = "" # Type of SSLContext's KeyManagers store, possible values are jks and p12 55 | #file = "" # Location of SSLContext's KeyManagers store 56 | #password = "" # Password for SSLContext's KeyManagers store 57 | #algorithm = "" # Algorithm used SSLContext's KeyManagers store, typically RSA 58 | } 59 | trustStore { 60 | #type = "" # Type of SSLContext's TrustManagers store, possible values are jks and p12 61 | #file = "" # Location of SSLContext's TrustManagers store 62 | #password = "" # Password for SSLContext's TrustManagers store 63 | #algorithm = "" # Algorithm used by SSLContext's TrustManagers store, typically RSA 64 | } 65 | } 66 | charting { 67 | #maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports 68 | #useGroupDurationMetric = false # Switch group timings from cumulated response time to group duration. 69 | indicators { 70 | #lowerBound = 800 # Lower bound for the requests' response time to track in the reports and the console summary 71 | #higherBound = 1200 # Higher bound for the requests' response time to track in the reports and the console summary 72 | #percentile1 = 50 # Value for the 1st percentile to track in the reports, the console summary and Graphite 73 | #percentile2 = 75 # Value for the 2nd percentile to track in the reports, the console summary and Graphite 74 | #percentile3 = 95 # Value for the 3rd percentile to track in the reports, the console summary and Graphite 75 | #percentile4 = 99 # Value for the 4th percentile to track in the reports, the console summary and Graphite 76 | } 77 | } 78 | http { 79 | #fetchedCssCacheMaxCapacity = 200 # Cache size for CSS parsed content, set to 0 to disable 80 | #fetchedHtmlCacheMaxCapacity = 200 # Cache size for HTML parsed content, set to 0 to disable 81 | #perUserCacheMaxCapacity = 200 # Per virtual user cache size, set to 0 to disable 82 | #warmUpUrl = "https://gatling.io" # The URL to use to warm-up the HTTP stack (blank means disabled) 83 | #pooledConnectionIdleTimeout = 60000 # Timeout in millis for a connection to stay idle in the pool 84 | #requestTimeout = 60000 # Timeout in millis for performing an HTTP request 85 | #enableHostnameVerification = false # When set to true, enable hostname verification: SSLEngine.setHttpsEndpointIdentificationAlgorithm("HTTPS") 86 | dns { 87 | #queryTimeout = 5000 # Timeout in millis of each DNS query in millis 88 | #maxQueriesPerResolve = 6 # Maximum allowed number of DNS queries for a given name resolution 89 | } 90 | } 91 | jms { 92 | #replyTimeoutScanPeriod = 1000 # scan period for timed out reply messages 93 | } 94 | data { 95 | #writers = [console, file] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite) 96 | #utcDateTime = true # Print date-times with the UTC zone instead of the System's default 97 | console { 98 | #light = false # When set to true, displays a light version without detailed request stats 99 | #writePeriod = 5 # Write interval, in seconds 100 | } 101 | file { 102 | #bufferSize = 8192 # FileDataWriter's internal data buffer size, in bytes 103 | } 104 | leak { 105 | #noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening 106 | } 107 | graphite { 108 | #light = false # only send the all* stats 109 | #host = "localhost" # The host where the Carbon server is located 110 | #port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle) 111 | #protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp") 112 | #rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite 113 | #bufferSize = 8192 # Internal data buffer size, in bytes 114 | #writePeriod = 1 # Write period, in seconds 115 | } 116 | #enableAnalytics = true # Anonymous Usage Analytics (no tracking), please support 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GeMi Gatling Examples in JAVA [![Build Status](https://github.com/gemiusz/gatling-examples-maven-java/actions/workflows//gatling_test_all_mine_after_push.yml/badge.svg?branch=master)](https://github.com/gemiusz/gatling-examples-maven-java/actions/workflows/gatling_test_all_mine_after_push.yml?query=branch%3Amaster) 2 | ============================================ 3 | 4 | Gatling project in JAVA 21 showing working examples and solutions - Inspired by [Gatling Community](https://community.gatling.io) 5 |

6 | 7 | It includes: 8 | * [Maven Wrapper](https://maven.apache.org/wrapper/), so that you can immediately run Maven with `./mvnw` without having 9 | to install it on your computer 10 | * minimal `pom.xml` 11 | * latest version of `io.gatling.highcharts:gatling-charts-highcharts`applied - [Maven Central Repository Search](https://search.maven.org/artifact/io.gatling.highcharts/gatling-charts-highcharts) 12 | * latest version of `io.gatling:gatling-maven-plugin` applied - [Maven Central Repository Search](https://search.maven.org/artifact/io.gatling/gatling-maven-plugin) 13 | * official examples: [ComputerDatabaseSimulation](src/test/java/computerdatabase/ComputerDatabaseSimulation.java), [BasicSimulation](src/test/java/computerdatabase/BasicSimulation.java), [AdvancedSimulationStep01](src/test/java/computerdatabase/advanced/AdvancedSimulationStep01.java), [AdvancedSimulationStep02](src/test/java/computerdatabase/advanced/AdvancedSimulationStep02.java), [AdvancedSimulationStep03](src/test/java/computerdatabase/advanced/AdvancedSimulationStep03.java), [AdvancedSimulationStep04](src/test/java/computerdatabase/advanced/AdvancedSimulationStep04.java), [AdvancedSimulationStep05](src/test/java/computerdatabase/advanced/AdvancedSimulationStep05.java) 14 | * mine examples and solutions mostly based on cases from [Gatling Community](https://community.gatling.io) 15 | * auto run using GitHub Actions ([push](https://github.com/gemiusz/gatling-examples-maven-java/actions/workflows/gatling_test_all_mine_after_push.yml), [pull](https://github.com/gemiusz/gatling-examples-maven-java/actions/workflows/gatling_test_all_mine_after_pull_request.yml)) of all mine examples after `push` and during `pull_request` 16 |


17 | 18 | ### Mine examples and solutions divided into cases: 19 | * [**Case0001JMESPathSimulation**](src/test/java/pl/gemiusz/Case0001JMESPathSimulation.java) => [JmesPath is not finding a JSON Object](https://community.gatling.io/t/jmespath-is-not-finding-a-json-object/6995) 20 | * [**Case0002PDFdownloadSimulation**](src/test/java/pl/gemiusz/Case0002PDFdownloadSimulation.java) => [How to ensure a pdf is downloaded during a loadtest?](https://community.gatling.io/t/how-to-ensure-a-pdf-is-downloaded-during-a-loadtest/3927) 21 | * [**Case0003UnzipJsonForFeederSimulation**](src/test/java/pl/gemiusz/Case0003UnzipJsonForFeederSimulation.java) => [Unzipping json file for feeders](https://community.gatling.io/t/unzipping-json-file-for-feeders/6996) 22 | * [**Case0004StatusCodeSimulation**](src/test/java/pl/gemiusz/Case0004StatusCodeSimulation.java) => [withDefault Check Transforming feature](https://community.gatling.io/t/withdefault-check-transforming-feature/7008) 23 | * [**Case0005UUIDfeederSimulation**](src/test/java/pl/gemiusz/Case0005UUIDfeederSimulation.java) => [Is there an EL function to generate uuid using java in gatling](https://community.gatling.io/t/is-there-an-el-function-to-generate-uuid-using-java-in-gatling/7028) 24 | * [**Case0006CommandLineParametersSimulation**](src/test/java/pl/gemiusz/Case0006CommandLineParametersSimulation.java) => [Cannot Grab Command Line Arguments](https://community.gatling.io/t/cannot-grab-command-line-arguments/7025) & [Assertion in parameter](https://community.gatling.io/t/assertion-in-parameter/7970) 25 | * [**Case0007AsyncReqSimulation**](src/test/java/pl/gemiusz/Case0007AsyncReqSimulation.java) - using `repeat` => [How to simulate an asynchronous request executing many times?](https://community.gatling.io/t/how-to-simulate-an-asynchronous-request-executing-many-times/7031) 26 | * [**Case0008AsyncReqResourcesSimulation**](src/test/java/pl/gemiusz/Case0008AsyncReqResourcesSimulation.java) - using `resources` => [How to simulate an asynchronous request executing many times?](https://community.gatling.io/t/how-to-simulate-an-asynchronous-request-executing-many-times/7031) 27 | * [**Case0009SessionValuesSimulation**](src/test/java/pl/gemiusz/Case0009SessionValuesSimulation.java) => [Dynamically generating param values for an API and setting it using session](https://community.gatling.io/t/dynamically-generating-param-values-for-an-api-and-setting-it-using-session/7041) 28 | * [**Case0010JsonEditVariableSimulation**](src/test/java/pl/gemiusz/Case0010JsonEditVariableSimulation.java) => [Java - edit variable received in JSON](https://community.gatling.io/t/java-edit-variable-received-in-json/7046) 29 | * [**Case0011ProxyCommandLineParametersSimulation**](src/test/java/pl/gemiusz/Case0011ProxyCommandLineParametersSimulation.java) => [Gatling proxy configuration from command line](https://community.gatling.io/t/gatling-proxy-configuration-from-command-line/7072) 30 | * [**Case0012DenySomeResourcesSimulation**](src/test/java/pl/gemiusz/Case0012DenySomeResourcesSimulation.java) => [Gatling Java - HttpProtocolBuilder DenyList](https://community.gatling.io/t/gatling-java-httpprotocolbuilder-denylist/7099) 31 | * [**Case0013RequestBeforeSimulation**](src/test/java/pl/gemiusz/Case0013RequestBeforeSimulation.java) => [Best way of calling another API before the performance test](https://community.gatling.io/t/best-way-of-calling-another-api-before-the-performance-test/7116) 32 | * [**Case0014Loop5times1RPSand3sPauseSimulation**](src/test/java/pl/gemiusz/Case0014Loop5times1RPSand3sPauseSimulation.java) => [Emulate load with few requests simultaneously that repeated after some period of time](https://community.gatling.io/t/emulate-load-with-few-requests-simultaneously-that-repeated-after-some-period-of-time/7155) 33 | * [**Case0015UUIDfeederTwoRecordsAtTheSameTimeSimulation**](src/test/java/pl/gemiusz/Case0015UUIDfeederTwoRecordsAtTheSameTimeSimulation.java) => [Feed multiple n-rows from CSV to json payload](https://community.gatling.io/t/feed-multiple-n-rows-from-csv-to-json-payload/7160) 34 | * [**Case0016ScenarioDurationSimulation**](src/test/java/pl/gemiusz/Case0016ScenarioDurationSimulation.java) => [How to get the duration of a specific scnario?](https://community.gatling.io/t/how-to-get-the-duration-of-a-specific-scnario/7220) 35 | * [**Case0017ForeachAfterForeachSimulation**](src/test/java/pl/gemiusz/Case0017ForeachAfterForeachSimulation.java) => [Foreach loop after a foreach loop does not execute](https://community.gatling.io/t/foreach-loop-after-a-foreach-loop-does-not-execute/7277) 36 | * [**Case0018GetTokenWhenStatus401Simulation**](src/test/java/pl/gemiusz/Case0018GetTokenWhenStatus401Simulation.java) => [Using a .doIf when token expired and need refresh](https://community.gatling.io/t/using-a-doif-when-token-expired-and-need-refresh/7303) 37 | * [**Case0019WhenStatusCode400ThenFailSimulation**](src/test/java/pl/gemiusz/Case0019WhenStatusCode400ThenFailSimulation.java) => [Assertion on the HTTP status code](https://community.gatling.io/t/assertion-on-the-http-status-code/7355) 38 | * [**Case0020ExitBlockOnFailSimulation**](src/test/java/pl/gemiusz/Case0020ExitBlockOnFailSimulation.java) => [Stop the current Iteration/loop and start the next Iteration/loop when request failed](https://community.gatling.io/t/stop-the-current-iteration-loop-and-start-the-next-iteration-loop-when-request-failed/7492) 39 | * [**Case0021CheckResourcesResponseTimeSimulation**](src/test/java/pl/gemiusz/Case0021CheckResourcesResponseTimeSimulation.java) => [Track which queries are executed within specified time frame and which outside it](https://community.gatling.io/t/track-which-queries-are-executed-within-specified-time-frame-and-which-outside-it/7910) 40 | * [**Case0022SetOrRefreshTokenSimulation**](src/test/java/pl/gemiusz/Case0022SetOrRefreshTokenSimulation.java) => [Token Refresh - Java - Example](https://community.gatling.io/t/token-refresh-java-example/7935) 41 | * [**Case0023foreachFromUUIDfeederFiveRecordsAtTheSameTimeSimulation**](src/test/java/pl/gemiusz/Case0023foreachFromUUIDfeederFiveRecordsAtTheSameTimeSimulation.java) => [Feeder reading multiple lines and foreach](https://community.gatling.io/t/feeder-reading-multiple-lines-and-foreach/7947) 42 | * [**Case0024IterationLoopCondition**](src/test/java/pl/gemiusz/Case0024IterationLoopCondition.java) => [Iteration and Looping conditions](https://community.gatling.io/t/iteration-and-looping-conditions/7984) 43 | * [**Case0025JSONfeederRandomSimulation**](src/test/java/pl/gemiusz/Case0025JSONfeederRandomSimulation.java) => [JSON feeder with nested arrays; how to randomly select a record from the parent](https://community.gatling.io/t/json-feeder-with-nested-arrays-how-to-randomly-select-a-record-from-the-parent/8059) 44 | * [**Case0026ResponseHeaderRegexSimulation**](src/test/java/pl/gemiusz/Case0026ResponseHeaderRegexSimulation.java) => [How to capture request params generated dynamically from GET request to correlate next POST request](https://community.gatling.io/t/how-to-capture-request-params-generated-dynamically-from-get-request-to-correlate-next-post-request/8276) 45 | * [**Case0027FilterFeederAndForeverLoopSameRecordByVU**](src/test/java/pl/gemiusz/Case0027FilterFeederAndForeverLoopSameRecordByVU.java) => [Custom csv feeder by from and to](https://community.gatling.io/t/custom-csv-feeder-by-from-and-to/9431) 46 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.2 23 | # 24 | # Optional ENV vars 25 | # ----------------- 26 | # JAVA_HOME - location of a JDK home dir, required when download maven via java source 27 | # MVNW_REPOURL - repo url base for downloading maven distribution 28 | # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 29 | # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output 30 | # ---------------------------------------------------------------------------- 31 | 32 | set -euf 33 | [ "${MVNW_VERBOSE-}" != debug ] || set -x 34 | 35 | # OS specific support. 36 | native_path() { printf %s\\n "$1"; } 37 | case "$(uname)" in 38 | CYGWIN* | MINGW*) 39 | [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" 40 | native_path() { cygpath --path --windows "$1"; } 41 | ;; 42 | esac 43 | 44 | # set JAVACMD and JAVACCMD 45 | set_java_home() { 46 | # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched 47 | if [ -n "${JAVA_HOME-}" ]; then 48 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 49 | # IBM's JDK on AIX uses strange locations for the executables 50 | JAVACMD="$JAVA_HOME/jre/sh/java" 51 | JAVACCMD="$JAVA_HOME/jre/sh/javac" 52 | else 53 | JAVACMD="$JAVA_HOME/bin/java" 54 | JAVACCMD="$JAVA_HOME/bin/javac" 55 | 56 | if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then 57 | echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 58 | echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 59 | return 1 60 | fi 61 | fi 62 | else 63 | JAVACMD="$( 64 | 'set' +e 65 | 'unset' -f command 2>/dev/null 66 | 'command' -v java 67 | )" || : 68 | JAVACCMD="$( 69 | 'set' +e 70 | 'unset' -f command 2>/dev/null 71 | 'command' -v javac 72 | )" || : 73 | 74 | if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then 75 | echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 76 | return 1 77 | fi 78 | fi 79 | } 80 | 81 | # hash string like Java String::hashCode 82 | hash_string() { 83 | str="${1:-}" h=0 84 | while [ -n "$str" ]; do 85 | char="${str%"${str#?}"}" 86 | h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) 87 | str="${str#?}" 88 | done 89 | printf %x\\n $h 90 | } 91 | 92 | verbose() { :; } 93 | [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } 94 | 95 | die() { 96 | printf %s\\n "$1" >&2 97 | exit 1 98 | } 99 | 100 | trim() { 101 | # MWRAPPER-139: 102 | # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. 103 | # Needed for removing poorly interpreted newline sequences when running in more 104 | # exotic environments such as mingw bash on Windows. 105 | printf "%s" "${1}" | tr -d '[:space:]' 106 | } 107 | 108 | # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties 109 | while IFS="=" read -r key value; do 110 | case "${key-}" in 111 | distributionUrl) distributionUrl=$(trim "${value-}") ;; 112 | distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; 113 | esac 114 | done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" 115 | [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" 116 | 117 | case "${distributionUrl##*/}" in 118 | maven-mvnd-*bin.*) 119 | MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ 120 | case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in 121 | *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; 122 | :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; 123 | :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; 124 | :Linux*x86_64*) distributionPlatform=linux-amd64 ;; 125 | *) 126 | echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 127 | distributionPlatform=linux-amd64 128 | ;; 129 | esac 130 | distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" 131 | ;; 132 | maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; 133 | *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; 134 | esac 135 | 136 | # apply MVNW_REPOURL and calculate MAVEN_HOME 137 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 138 | [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" 139 | distributionUrlName="${distributionUrl##*/}" 140 | distributionUrlNameMain="${distributionUrlName%.*}" 141 | distributionUrlNameMain="${distributionUrlNameMain%-bin}" 142 | MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" 143 | MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" 144 | 145 | exec_maven() { 146 | unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : 147 | exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" 148 | } 149 | 150 | if [ -d "$MAVEN_HOME" ]; then 151 | verbose "found existing MAVEN_HOME at $MAVEN_HOME" 152 | exec_maven "$@" 153 | fi 154 | 155 | case "${distributionUrl-}" in 156 | *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; 157 | *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; 158 | esac 159 | 160 | # prepare tmp dir 161 | if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then 162 | clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } 163 | trap clean HUP INT TERM EXIT 164 | else 165 | die "cannot create temp dir" 166 | fi 167 | 168 | mkdir -p -- "${MAVEN_HOME%/*}" 169 | 170 | # Download and Install Apache Maven 171 | verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 172 | verbose "Downloading from: $distributionUrl" 173 | verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 174 | 175 | # select .zip or .tar.gz 176 | if ! command -v unzip >/dev/null; then 177 | distributionUrl="${distributionUrl%.zip}.tar.gz" 178 | distributionUrlName="${distributionUrl##*/}" 179 | fi 180 | 181 | # verbose opt 182 | __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' 183 | [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v 184 | 185 | # normalize http auth 186 | case "${MVNW_PASSWORD:+has-password}" in 187 | '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; 188 | has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; 189 | esac 190 | 191 | if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then 192 | verbose "Found wget ... using wget" 193 | wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" 194 | elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then 195 | verbose "Found curl ... using curl" 196 | curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" 197 | elif set_java_home; then 198 | verbose "Falling back to use Java to download" 199 | javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" 200 | targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" 201 | cat >"$javaSource" <<-END 202 | public class Downloader extends java.net.Authenticator 203 | { 204 | protected java.net.PasswordAuthentication getPasswordAuthentication() 205 | { 206 | return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); 207 | } 208 | public static void main( String[] args ) throws Exception 209 | { 210 | setDefault( new Downloader() ); 211 | java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); 212 | } 213 | } 214 | END 215 | # For Cygwin/MinGW, switch paths to Windows format before running javac and java 216 | verbose " - Compiling Downloader.java ..." 217 | "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" 218 | verbose " - Running Downloader.java ..." 219 | "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" 220 | fi 221 | 222 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 223 | if [ -n "${distributionSha256Sum-}" ]; then 224 | distributionSha256Result=false 225 | if [ "$MVN_CMD" = mvnd.sh ]; then 226 | echo "Checksum validation is not supported for maven-mvnd." >&2 227 | echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 228 | exit 1 229 | elif command -v sha256sum >/dev/null; then 230 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then 231 | distributionSha256Result=true 232 | fi 233 | elif command -v shasum >/dev/null; then 234 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then 235 | distributionSha256Result=true 236 | fi 237 | else 238 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 239 | echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 240 | exit 1 241 | fi 242 | if [ $distributionSha256Result = false ]; then 243 | echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 244 | echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 245 | exit 1 246 | fi 247 | fi 248 | 249 | # unzip and move 250 | if command -v unzip >/dev/null; then 251 | unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" 252 | else 253 | tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" 254 | fi 255 | printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" 256 | mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" 257 | 258 | clean || : 259 | exec_maven "$@" 260 | --------------------------------------------------------------------------------