feat(Gatlin): Rework of test behaviour
Added realistic user behaviour
This commit is contained in:
@@ -0,0 +1,61 @@
|
|||||||
|
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,8 +1,9 @@
|
|||||||
package simulations
|
package simulations
|
||||||
|
|
||||||
import base.BaseSimulation
|
import base.BaseSimulation
|
||||||
import endpoints.BoardEndpoints
|
import scenarios.ChessUserScenario
|
||||||
import io.gatling.core.Predef._
|
import io.gatling.core.Predef._
|
||||||
|
import io.gatling.http.Predef._
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
@@ -11,12 +12,15 @@ 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(
|
||||||
BoardEndpoints.all.map { endpoint =>
|
ChessUserScenario.play
|
||||||
scenarioFromEndpoint(endpoint)
|
.inject(
|
||||||
.inject(
|
constantConcurrentUsers(concurrentUsers).during(duration.seconds)
|
||||||
constantConcurrentUsers(concurrentUsers).during(duration.seconds)
|
)
|
||||||
)
|
|
||||||
}: _*
|
|
||||||
).protocols(httpProtocol)
|
).protocols(httpProtocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,25 @@
|
|||||||
package simulations
|
package simulations
|
||||||
|
|
||||||
import base.BaseSimulation
|
import base.BaseSimulation
|
||||||
import endpoints.BoardEndpoints
|
import scenarios.ChessUserScenario
|
||||||
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", "5").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(
|
||||||
BoardEndpoints.all.map { endpoint =>
|
ChessUserScenario.play
|
||||||
scenarioFromEndpoint(endpoint)
|
.inject(rampUsers(maxUsers).during(rampDuration.seconds))
|
||||||
.inject(rampUsers(maxUsers).during(rampDuration.seconds))
|
|
||||||
}: _*
|
|
||||||
).protocols(httpProtocol)
|
).protocols(httpProtocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package simulations
|
package simulations
|
||||||
|
|
||||||
import base.BaseSimulation
|
import base.BaseSimulation
|
||||||
import endpoints.BoardEndpoints
|
import scenarios.ChessUserScenario
|
||||||
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(
|
||||||
scenarioFromEndpoint(BoardEndpoints.createGame)
|
ChessUserScenario.play
|
||||||
.inject(atOnceUsers(1))
|
.inject(atOnceUsers(1))
|
||||||
).protocols(httpProtocol)
|
).protocols(httpProtocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package simulations
|
package simulations
|
||||||
|
|
||||||
import base.BaseSimulation
|
import base.BaseSimulation
|
||||||
import endpoints.BoardEndpoints
|
import scenarios.ChessUserScenario
|
||||||
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 +13,18 @@ class SpikeTestSimulation extends BaseSimulation {
|
|||||||
private val baselineDuration = sys.props.getOrElse("baselineDuration", "20").toInt
|
private val baselineDuration = sys.props.getOrElse("baselineDuration", "20").toInt
|
||||||
private val spikeUsers = sys.props.getOrElse("spikeUsers", "15").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(
|
setUp(
|
||||||
BoardEndpoints.all.map { endpoint =>
|
ChessUserScenario.play
|
||||||
scenarioFromEndpoint(endpoint)
|
.inject(
|
||||||
.inject(
|
constantUsersPerSec(baselineUsers).during(baselineDuration.seconds),
|
||||||
constantUsersPerSec(baselineUsers).during(baselineDuration.seconds),
|
atOnceUsers(spikeUsers),
|
||||||
atOnceUsers(spikeUsers),
|
nothingFor(5.seconds),
|
||||||
nothingFor(5.seconds),
|
constantUsersPerSec(baselineUsers).during(baselineDuration.seconds)
|
||||||
constantUsersPerSec(baselineUsers).during(baselineDuration.seconds)
|
)
|
||||||
)
|
|
||||||
}: _*
|
|
||||||
).protocols(httpProtocol)
|
).protocols(httpProtocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package simulations
|
package simulations
|
||||||
|
|
||||||
import base.BaseSimulation
|
import base.BaseSimulation
|
||||||
import endpoints.BoardEndpoints
|
import scenarios.ChessUserScenario
|
||||||
import io.gatling.core.Predef._
|
import io.gatling.core.Predef._
|
||||||
|
import io.gatling.http.Predef._
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
@@ -14,16 +15,19 @@ class StressTestSimulation extends BaseSimulation {
|
|||||||
private val stepDuration = sys.props.getOrElse("stepDuration", "30").toInt
|
private val stepDuration = sys.props.getOrElse("stepDuration", "30").toInt
|
||||||
private val rampDuration = sys.props.getOrElse("rampDuration", "10").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(
|
setUp(
|
||||||
BoardEndpoints.all.map { endpoint =>
|
ChessUserScenario.play
|
||||||
scenarioFromEndpoint(endpoint)
|
.inject(
|
||||||
.inject(
|
incrementConcurrentUsers(usersIncrement)
|
||||||
incrementConcurrentUsers(usersIncrement)
|
.times(steps)
|
||||||
.times(steps)
|
.eachLevelLasting(stepDuration.seconds)
|
||||||
.eachLevelLasting(stepDuration.seconds)
|
.separatedByRampsLasting(rampDuration.seconds)
|
||||||
.separatedByRampsLasting(rampDuration.seconds)
|
.startingFrom(startUsers)
|
||||||
.startingFrom(startUsers)
|
)
|
||||||
)
|
|
||||||
}: _*
|
|
||||||
).protocols(httpProtocol)
|
).protocols(httpProtocol)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user