Merge branch 'stable-3.1' into stable-3.2
* stable-3.1: BatchUpdateTest: Extend GerritBaseTests dev-bazel: Fix package name in example test invocation ReviewDbBatchUpdate: Fix typo in member name Enable to run online noteDb migration using multiple threads GerritSimulation: Support runtime factor property GerritSimulation: Add replaceOverride javadoc tags GerritSimulation: Support reusable step wait times Change-Id: Ifdb0007187a3d772e0398c07aed3b4836e4a97a0
This commit is contained in:
@@ -387,7 +387,7 @@ In IDE, set `-Dgerrit.logLevel=debug` as a VM argument. With `bazel`, pass
|
||||
`GERRIT_LOG_LEVEL=debug` environment variable:
|
||||
|
||||
----
|
||||
bazel test --test_filter=com.gerrit.server.notedb.ChangeNotesTest \
|
||||
bazel test --test_filter=com.google.gerrit.server.notedb.ChangeNotesTest \
|
||||
--test_env=GERRIT_LOG_LEVEL=debug \
|
||||
javatests/com/google/gerrit/server:server_tests
|
||||
----
|
||||
|
||||
@@ -170,6 +170,17 @@ Further above, the `_PROJECT` keyword is prefixed with an underscore, which mean
|
||||
gets automatically generated by the scenario. Any property setting for it is therefore not
|
||||
applicable. Its usage differs from the non-prefixed `PROJECT` keyword, in that sense.
|
||||
|
||||
The following core property can be optionally set depending on the runtime environment. The test
|
||||
environments used as reference for scenarios development assume its default value, `1.0`. For
|
||||
slower or more complex execution environments, the value can be increased this way for example:
|
||||
|
||||
* `-Dcom.google.gerrit.scenarios.power_factor=1.5`
|
||||
|
||||
This will make the scenario steps take half more time to expect proper completion. A value smaller
|
||||
than the default, say `0.8`, will make scenarios wait somewhat less than how they were developed.
|
||||
Scenario development is often done using locally running Gerrit systems under test, which are
|
||||
sometimes dockerized.
|
||||
|
||||
== How to run tests
|
||||
|
||||
Run all tests:
|
||||
|
||||
@@ -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,26 @@ class GerritSimulation extends Simulation {
|
||||
protected val body: String = s"$pathName-body.json"
|
||||
protected val unique: String = name + "-" + this.hashCode()
|
||||
|
||||
private val powerFactor: Double = replaceProperty("power_factor", 1.0).toDouble
|
||||
private val SecondsPerWeightUnit: Int = 2
|
||||
val maxExecutionTime: Int = (SecondsPerWeightUnit * relativeRuntimeWeight * powerFactor).toInt
|
||||
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,
|
||||
@@ -54,11 +74,15 @@ class GerritSimulation extends Simulation {
|
||||
replaceProperty(term, term, in)
|
||||
}
|
||||
|
||||
private def replaceProperty(term: String, default: Any): String = {
|
||||
replaceProperty(term, default, term.toUpperCase)
|
||||
}
|
||||
|
||||
protected def replaceProperty(term: String, default: Any, in: String): String = {
|
||||
val property = pack + "." + term
|
||||
var value = default
|
||||
default match {
|
||||
case _: String =>
|
||||
case _: String | _: Double =>
|
||||
val propertyValue = Option(System.getProperty(property))
|
||||
if (propertyValue.nonEmpty) {
|
||||
value = propertyValue.get
|
||||
@@ -84,8 +108,26 @@ class GerritSimulation extends Simulation {
|
||||
* override def replaceOverride(in: String): String = {
|
||||
* // Simple e.g., replaceProperty("EXTENSION_JSON_KEY", "default", in)
|
||||
* </pre>
|
||||
*
|
||||
* @param in which string to perform the replacements.
|
||||
* @return the resulting String.
|
||||
*/
|
||||
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