1 Commits

Author SHA1 Message Date
LQ63 9b97fa6e34 feat(Gatlin): Endurance Test
Added an endurance test and changed endpoint to a more stable one
2026-05-04 15:45:44 +02:00
7 changed files with 17 additions and 163 deletions
+1 -8
View File
@@ -23,15 +23,8 @@ tasks.withType(io.gatling.gradle.GatlingRunTask) {
"-Dhealthz.path=${findProperty('healthzPath') ?: '/health'}", "-Dhealthz.path=${findProperty('healthzPath') ?: '/health'}",
"-DmaxUsers=${findProperty('maxUsers') ?: '10'}", "-DmaxUsers=${findProperty('maxUsers') ?: '10'}",
"-DrampDuration=${findProperty('rampDuration') ?: '60'}", "-DrampDuration=${findProperty('rampDuration') ?: '60'}",
"-DstartUsers=${findProperty('startUsers') ?: '2'}",
"-DusersIncrement=${findProperty('usersIncrement') ?: '2'}",
"-Dsteps=${findProperty('steps') ?: '2'}",
"-DstepDuration=${findProperty('stepDuration') ?: '30'}",
"-DconcurrentUsers=${findProperty('concurrentUsers') ?: '3'}", "-DconcurrentUsers=${findProperty('concurrentUsers') ?: '3'}",
"-Dduration=${findProperty('duration') ?: '300'}", "-Dduration=${findProperty('duration') ?: '300'}"
"-DbaselineUsers=${findProperty('baselineUsers') ?: '2'}",
"-DbaselineDuration=${findProperty('baselineDuration') ?: '20'}",
"-DspikeUsers=${findProperty('spikeUsers') ?: '15'}"
] ]
} }
@@ -1,61 +0,0 @@
package scenarios
import io.gatling.core.Predef._
import io.gatling.core.structure.ScenarioBuilder
import io.gatling.http.Predef._
import scala.concurrent.duration._
object ChessUserScenario {
private def makeMove(uci: String) =
http(s"Move $uci")
.post(session => s"/api/board/game/${session("gameId").as[String]}/move/$uci")
.header("Authorization", "${jwt}")
.check(status.in(200, 201))
val play: ScenarioBuilder = scenario("Chess User Journey")
.exec(session => session.set("username", s"user_${System.currentTimeMillis()}_${session.userId}_${java.util.UUID.randomUUID().toString.take(8)}"))
.exec(
http("Register")
.post("/api/account")
.body(StringBody(session =>
s"""{"username":"${session("username").as[String]}","email":"${session("username").as[String]}@test.com","password":"Password123!"}"""
))
.check(status.is(200))
)
.exec(
http("Login")
.post("/api/account/login")
.body(StringBody(session =>
s"""{"username":"${session("username").as[String]}","password":"Password123!"}"""
))
.check(status.is(200))
.check(jsonPath("$.token").saveAs("jwt"))
)
.exec(
http("Import Game")
.post("/api/board/game/import/fen")
.header("Authorization", "${jwt}")
.body(StringBody(session => {
val username = session("username").as[String]
s"""{
| "fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
| "white": {"id": "$username", "displayName": "$username"},
| "black": {"id": "opponent_${session.userId}", "displayName": "Opponent"},
| "timeControl": {"limitSeconds": 300, "incrementSeconds": 3}
|}""".stripMargin
}))
.check(status.in(200, 201))
.check(jsonPath("$.gameId").saveAs("gameId"))
)
.exec(makeMove("e2e4"))
.exec(makeMove("e7e5"))
.exec(makeMove("g1f3"))
.exec(
http("Resign")
.post(session => s"/api/board/game/${session("gameId").as[String]}/resign")
.header("Authorization", "${jwt}")
.check(status.in(200, 201, 204))
)
}
@@ -1,9 +1,8 @@
package simulations package simulations
import base.BaseSimulation import base.BaseSimulation
import scenarios.ChessUserScenario import endpoints.BoardEndpoints
import io.gatling.core.Predef._ import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._ import scala.concurrent.duration._
@@ -12,15 +11,12 @@ class EnduranceTestSimulation extends BaseSimulation {
private val concurrentUsers = sys.props.getOrElse("concurrentUsers", "3").toInt private val concurrentUsers = sys.props.getOrElse("concurrentUsers", "3").toInt
private val duration = sys.props.getOrElse("duration", "300").toInt private val duration = sys.props.getOrElse("duration", "300").toInt
override protected val httpProtocol = http
.baseUrl(baseUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
setUp( setUp(
ChessUserScenario.play BoardEndpoints.all.map { endpoint =>
.inject( scenarioFromEndpoint(endpoint)
constantConcurrentUsers(concurrentUsers).during(duration.seconds) .inject(
) constantConcurrentUsers(concurrentUsers).during(duration.seconds)
)
}: _*
).protocols(httpProtocol) ).protocols(httpProtocol)
} }
@@ -1,25 +1,20 @@
package simulations package simulations
import base.BaseSimulation import base.BaseSimulation
import scenarios.ChessUserScenario import endpoints.BoardEndpoints
import io.gatling.core.Predef._ import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._ import scala.concurrent.duration._
class LoadTestSimulation extends BaseSimulation { class LoadTestSimulation extends BaseSimulation {
private val maxUsers = sys.props.getOrElse("maxUsers", "5").toInt private val maxUsers = sys.props.getOrElse("maxUsers", "10").toInt
private val rampDuration = sys.props.getOrElse("rampDuration", "60").toInt private val rampDuration = sys.props.getOrElse("rampDuration", "60").toInt
// Each virtual user authenticates individually, so no global Bearer token
override protected val httpProtocol = http
.baseUrl(baseUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
setUp( setUp(
ChessUserScenario.play BoardEndpoints.all.map { endpoint =>
.inject(rampUsers(maxUsers).during(rampDuration.seconds)) scenarioFromEndpoint(endpoint)
.inject(rampUsers(maxUsers).during(rampDuration.seconds))
}: _*
).protocols(httpProtocol) ).protocols(httpProtocol)
} }
@@ -1,19 +1,13 @@
package simulations package simulations
import base.BaseSimulation import base.BaseSimulation
import scenarios.ChessUserScenario import endpoints.BoardEndpoints
import io.gatling.core.Predef._ import io.gatling.core.Predef._
import io.gatling.http.Predef._
class SmokeTestSimulation extends BaseSimulation { class SmokeTestSimulation extends BaseSimulation {
override protected val httpProtocol = http
.baseUrl(baseUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
setUp( setUp(
ChessUserScenario.play scenarioFromEndpoint(BoardEndpoints.createGame)
.inject(atOnceUsers(1)) .inject(atOnceUsers(1))
).protocols(httpProtocol) ).protocols(httpProtocol)
} }
@@ -1,30 +0,0 @@
package simulations
import base.BaseSimulation
import scenarios.ChessUserScenario
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class SpikeTestSimulation extends BaseSimulation {
private val baselineUsers = sys.props.getOrElse("baselineUsers", "2").toInt
private val baselineDuration = sys.props.getOrElse("baselineDuration", "20").toInt
private val spikeUsers = sys.props.getOrElse("spikeUsers", "15").toInt
override protected val httpProtocol = http
.baseUrl(baseUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
setUp(
ChessUserScenario.play
.inject(
constantUsersPerSec(baselineUsers).during(baselineDuration.seconds),
atOnceUsers(spikeUsers),
nothingFor(5.seconds),
constantUsersPerSec(baselineUsers).during(baselineDuration.seconds)
)
).protocols(httpProtocol)
}
@@ -1,33 +0,0 @@
package simulations
import base.BaseSimulation
import scenarios.ChessUserScenario
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class StressTestSimulation extends BaseSimulation {
private val startUsers = sys.props.getOrElse("startUsers", "2").toInt
private val usersIncrement = sys.props.getOrElse("usersIncrement", "2").toInt
private val steps = sys.props.getOrElse("steps", "2").toInt
private val stepDuration = sys.props.getOrElse("stepDuration", "30").toInt
private val rampDuration = sys.props.getOrElse("rampDuration", "10").toInt
override protected val httpProtocol = http
.baseUrl(baseUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
setUp(
ChessUserScenario.play
.inject(
incrementConcurrentUsers(usersIncrement)
.times(steps)
.eachLevelLasting(stepDuration.seconds)
.separatedByRampsLasting(rampDuration.seconds)
.startingFrom(startUsers)
)
).protocols(httpProtocol)
}