GerritSimulation: Support reusable step wait times
Add support for relative runtime weights to scenarios. This way, each scenario can either weight like any other by default, or override that default with a greater weight value compared to siblings that are lighter on the execution time. Document that in GerritSimulation, where the abstraction and default are implemented. Define the default scenario weight unit (equal to 1). Allow scenarios heavier on the runtime to override that default. Define one single unit of weight as 2 seconds. This weight idea handily gets automatically factored in how long a scenario (step) needs to finish affecting the SUT. That step n-1 impact is assumed by the following step n (or next delegate scenario), in the aggregating scenario. Reuse this, hence unhardcode wait times in every core scenario step. Change-Id: I24e392b5ee1883225a77544c42608d8e49beee52
This commit is contained in:
@@ -23,6 +23,7 @@ import scala.concurrent.duration._
|
||||
class CloneUsingBothProtocols extends GitSimulation {
|
||||
private val data: FileBasedFeederBuilder[Any]#F#F = jsonFile(resource).convert(keys).queue
|
||||
private val default: String = name
|
||||
private val duration: Int = 2
|
||||
|
||||
override def replaceOverride(in: String): String = {
|
||||
replaceKeyWith("_project", default, in)
|
||||
@@ -37,14 +38,15 @@ class CloneUsingBothProtocols extends GitSimulation {
|
||||
|
||||
setUp(
|
||||
createProject.test.inject(
|
||||
nothingFor(stepWaitTime(createProject) seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
test.inject(
|
||||
nothingFor(2 seconds),
|
||||
constantUsersPerSec(1) during (2 seconds)
|
||||
nothingFor(stepWaitTime(this) seconds),
|
||||
constantUsersPerSec(1) during (duration seconds)
|
||||
),
|
||||
deleteProject.test.inject(
|
||||
nothingFor(6 seconds),
|
||||
nothingFor(stepWaitTime(deleteProject) + duration seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
).protocols(gitProtocol, httpProtocol)
|
||||
|
@@ -26,6 +26,8 @@ class CreateChange extends GerritSimulation {
|
||||
private val default: String = name
|
||||
private val numberKey = "_number"
|
||||
|
||||
override def relativeRuntimeWeight = 2
|
||||
|
||||
val test: ScenarioBuilder = scenario(unique)
|
||||
.feed(data)
|
||||
.exec(httpRequest
|
||||
@@ -42,18 +44,19 @@ class CreateChange extends GerritSimulation {
|
||||
|
||||
setUp(
|
||||
createProject.test.inject(
|
||||
nothingFor(stepWaitTime(createProject) seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
test.inject(
|
||||
nothingFor(2 seconds),
|
||||
nothingFor(stepWaitTime(this) seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
deleteChange.test.inject(
|
||||
nothingFor(6 seconds),
|
||||
nothingFor(stepWaitTime(deleteChange) seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
deleteProject.test.inject(
|
||||
nothingFor(8 seconds),
|
||||
nothingFor(stepWaitTime(deleteProject) seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
).protocols(httpProtocol)
|
||||
|
@@ -23,6 +23,8 @@ class DeleteChange extends GerritSimulation {
|
||||
private val data: FileBasedFeederBuilder[Any]#F#F = jsonFile(resource).convert(keys).queue
|
||||
var number: Option[Int] = None
|
||||
|
||||
override def relativeRuntimeWeight = 2
|
||||
|
||||
val test: ScenarioBuilder = scenario(unique)
|
||||
.feed(data)
|
||||
.exec(session => {
|
||||
|
@@ -31,6 +31,25 @@ class GerritSimulation extends Simulation {
|
||||
protected val body: String = s"$pathName-body.json"
|
||||
protected val unique: String = name + "-" + this.hashCode()
|
||||
|
||||
private val SecondsPerWeightUnit: Int = 2
|
||||
val maxExecutionTime: Int = SecondsPerWeightUnit * relativeRuntimeWeight
|
||||
private var cumulativeWaitTime: Int = 0
|
||||
|
||||
/**
|
||||
* How long a scenario step should wait before starting to execute.
|
||||
* This is also registering that step's resulting wait time, so that time
|
||||
* can be reused cumulatively by a potentially following scenario step.
|
||||
* (Otherwise, the Gatling set-up scenario steps execute all at once.)
|
||||
*
|
||||
* @param scenario for which to return a wait time.
|
||||
* @return that step's wait time as an Int.
|
||||
*/
|
||||
protected def stepWaitTime(scenario: GerritSimulation): Int = {
|
||||
val currentWaitTime = cumulativeWaitTime
|
||||
cumulativeWaitTime += scenario.maxExecutionTime
|
||||
currentWaitTime
|
||||
}
|
||||
|
||||
protected val httpRequest: HttpRequestBuilder = http(unique).post("${url}")
|
||||
protected val httpProtocol: HttpProtocolBuilder = http.basicAuth(
|
||||
conf.httpConfiguration.userName,
|
||||
@@ -88,4 +107,19 @@ class GerritSimulation extends Simulation {
|
||||
def replaceOverride(in: String): String = {
|
||||
in
|
||||
}
|
||||
|
||||
/**
|
||||
* Meant to be optionally overridden by (heavier) scenarios.
|
||||
* This is the relative runtime weight of the scenario class or type,
|
||||
* compared to other scenarios' own runtime weights.
|
||||
*
|
||||
* The default weight or unit of weight is the pre-assigned value below.
|
||||
* This default applies to any scenario class that is not overriding it
|
||||
* with a greater, relative runtime weight value. Overriding scenarios
|
||||
* happen to relatively require more run time than siblings, prior to
|
||||
* being expected as completed.
|
||||
*
|
||||
* @return the relative runtime weight of this scenario as an Int.
|
||||
*/
|
||||
def relativeRuntimeWeight = 1
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@ class ReplayRecordsFromFeeder extends GitSimulation {
|
||||
private val data: FileBasedFeederBuilder[Any]#F#F = jsonFile(resource).convert(keys).circular
|
||||
private val default: String = name
|
||||
|
||||
override def relativeRuntimeWeight = 30
|
||||
|
||||
override def replaceOverride(in: String): String = {
|
||||
replaceKeyWith("_project", default, in)
|
||||
}
|
||||
@@ -36,22 +38,24 @@ class ReplayRecordsFromFeeder extends GitSimulation {
|
||||
|
||||
private val createProject = new CreateProject(default)
|
||||
private val deleteProject = new DeleteProject(default)
|
||||
private val maxBeforeDelete: Int = maxExecutionTime - deleteProject.maxExecutionTime
|
||||
|
||||
setUp(
|
||||
createProject.test.inject(
|
||||
nothingFor(stepWaitTime(createProject) seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
test.inject(
|
||||
nothingFor(4 seconds),
|
||||
nothingFor(stepWaitTime(this) seconds),
|
||||
atOnceUsers(10),
|
||||
rampUsers(10) during (5 seconds),
|
||||
constantUsersPerSec(20) during (15 seconds),
|
||||
constantUsersPerSec(20) during (15 seconds) randomized
|
||||
),
|
||||
deleteProject.test.inject(
|
||||
nothingFor(59 seconds),
|
||||
nothingFor(maxBeforeDelete seconds),
|
||||
atOnceUsers(1)
|
||||
),
|
||||
).protocols(gitProtocol, httpProtocol)
|
||||
.maxDuration(61 seconds)
|
||||
.maxDuration(maxExecutionTime seconds)
|
||||
}
|
||||
|
Reference in New Issue
Block a user