From 5495d9cc5b591866cbc9818b86b9b5b0cfced48d Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Thu, 2 Apr 2020 22:35:07 +0900 Subject: [PATCH 1/2] ElasticV{6,7}QueryChangesTest: Add comment about issue 10120 Add a comment to clarify that the index close operation is done to prevent issue 10120. Change-Id: Id8d5b4e922674404351ac9a5a7a281283485fdb1 --- .../google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java | 2 ++ .../google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java index f1dcbaf63c..3f59d30573 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java @@ -57,6 +57,8 @@ public class ElasticV6QueryChangesTest extends AbstractQueryChangesTest { @After public void closeIndex() { + // Close the index after each test to prevent exceeding Elasticsearch's + // shard limit (see Issue 10120). client.execute( new HttpPost( String.format( diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java index 704f2f1284..979a7f65dd 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java @@ -57,6 +57,8 @@ public class ElasticV7QueryChangesTest extends AbstractQueryChangesTest { @After public void closeIndex() { + // Close the index after each test to prevent exceeding Elasticsearch's + // shard limit (see Issue 10120). client.execute( new HttpPost( String.format( From 6ba23762ae6d9ec3b12ac270380e6ae4454d2ccc Mon Sep 17 00:00:00 2001 From: Marco Miller Date: Thu, 2 Apr 2020 14:07:29 -0400 Subject: [PATCH 2/2] e2e-tests: Add JAVA_OPTS support to the framework Unhardcode hostname and port values to start with, which typically vary across test execution environments or deployments. This allows for less json scenario data file duplication and proliferation. Base this JAVA_OPTS solution on [1] below. If no JAVA_OPTS property|ies gets defined in the scenario execution shell environment, use the well-known default value(s) coded in. Document how to use JAVA_OPTS. Adapt the showcase core CloneUsingBothProtocols and aggregated project scenarios accordingly. Make them reuse core's amended GerritSimulation. [1] https://gatling.io/docs/current/cookbook/passing_parameters Change-Id: I45cf4b7ccf5cc51c8bd31fedbac99ae4bed053bb --- Documentation/dev-e2e-tests.txt | 21 ++++++++++++--- .../scenarios/CloneUsingBothProtocols.json | 4 +-- .../gerrit/scenarios/CreateProject.json | 2 +- .../gerrit/scenarios/DeleteProject.json | 2 +- .../scenarios/CloneUsingBothProtocols.scala | 2 +- .../gerrit/scenarios/CreateProject.scala | 2 +- .../gerrit/scenarios/DeleteProject.scala | 2 +- .../gerrit/scenarios/GerritSimulation.scala | 26 ++++++++++++++++++- 8 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Documentation/dev-e2e-tests.txt b/Documentation/dev-e2e-tests.txt index 17334e32d2..56668c74d9 100644 --- a/Documentation/dev-e2e-tests.txt +++ b/Documentation/dev-e2e-tests.txt @@ -105,16 +105,16 @@ The `CloneUsingBothProtocols` scenario is fed with the data coming from the file contains the commands and repository used during the e2e test. That file currently looks like below. This scenario serves as a simple example with no actual load in it. It can be used to test or validate the local setup. More complex scenarios can be further developed, under the -`com.google.gerrit.scenarios` package. +`com.google.gerrit.scenarios` package. The uppercase keywords are discussed further below. ---- [ { - "url": "ssh://admin@localhost:29418/loadtest-repo", + "url": "ssh://admin@HOSTNAME:SSH_PORT/loadtest-repo", "cmd": "clone" }, { - "url": "http://localhost:8080/loadtest-repo", + "url": "http://HOSTNAME:HTTP_PORT/loadtest-repo", "cmd": "clone" } ] @@ -141,6 +141,21 @@ file's `http` section shows which shell environment variables can be used to set Executing the `CloneUsingBothProtocols` scenario, as is, does require setting the http credentials. That is because of the aforementioned create/delete project (http) scenarios composed within it. +=== Environment properties + +The `JAVA_OPTS` environment variable +link:https://gatling.io/docs/current/cookbook/passing_parameters[can optionally be used] to define +non-default values for keys found in scenario `json` data files. That variable can currently be set +with either one or many of these supported properties, from the core framework: + +* `-Dcom.google.gerrit.scenarios.hostname=localhost` +* `-Dcom.google.gerrit.scenarios.ssh_port=29418` +* `-Dcom.google.gerrit.scenarios.http_port=8080` + +Above, the properties can be set with values matching specific deployment topologies under test. +The example values shown above are the currently coded default ones. The framework could support +differing or more properties over time. Plugin (non-core) scenarios may do so just as well. + == How to run tests Run all tests: diff --git a/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CloneUsingBothProtocols.json b/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CloneUsingBothProtocols.json index 0335b2f0f1..11256873b4 100644 --- a/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CloneUsingBothProtocols.json +++ b/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CloneUsingBothProtocols.json @@ -1,10 +1,10 @@ [ { - "url": "ssh://admin@localhost:29418/loadtest-repo", + "url": "ssh://admin@HOSTNAME:SSH_PORT/loadtest-repo", "cmd": "clone" }, { - "url": "http://localhost:8080/loadtest-repo", + "url": "http://HOSTNAME:HTTP_PORT/loadtest-repo", "cmd": "clone" } ] diff --git a/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CreateProject.json b/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CreateProject.json index 2e54de55c2..f1a38ae788 100644 --- a/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CreateProject.json +++ b/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/CreateProject.json @@ -1,5 +1,5 @@ [ { - "url": "http://localhost:8080/a/projects/loadtest-repo" + "url": "http://HOSTNAME:HTTP_PORT/a/projects/loadtest-repo" } ] diff --git a/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/DeleteProject.json b/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/DeleteProject.json index 9312fb47a0..e5167b5ddd 100644 --- a/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/DeleteProject.json +++ b/e2e-tests/src/test/resources/data/com/google/gerrit/scenarios/DeleteProject.json @@ -1,5 +1,5 @@ [ { - "url": "http://localhost:8080/a/projects/loadtest-repo/delete-project~delete" + "url": "http://HOSTNAME:HTTP_PORT/a/projects/loadtest-repo/delete-project~delete" } ] diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CloneUsingBothProtocols.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CloneUsingBothProtocols.scala index 19fbf1bb27..182ac4853f 100644 --- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CloneUsingBothProtocols.scala +++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CloneUsingBothProtocols.scala @@ -21,7 +21,7 @@ import io.gatling.core.structure.ScenarioBuilder import scala.concurrent.duration._ class CloneUsingBothProtocols extends GitSimulation { - private val data: FileBasedFeederBuilder[Any]#F = jsonFile(resource).queue + private val data: FileBasedFeederBuilder[Any]#F#F = jsonFile(resource).convert(url).queue private val test: ScenarioBuilder = scenario(name) .feed(data) diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateProject.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateProject.scala index 58c8994d8c..13d3519c88 100644 --- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateProject.scala +++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateProject.scala @@ -19,7 +19,7 @@ import io.gatling.core.feeder.FileBasedFeederBuilder import io.gatling.core.structure.ScenarioBuilder class CreateProject extends GerritSimulation { - private val data: FileBasedFeederBuilder[Any]#F = jsonFile(resource).queue + private val data: FileBasedFeederBuilder[Any]#F#F = jsonFile(resource).convert(url).queue val test: ScenarioBuilder = scenario(name) .feed(data) diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteProject.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteProject.scala index 4b723cb0b8..70b901da97 100644 --- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteProject.scala +++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteProject.scala @@ -19,7 +19,7 @@ import io.gatling.core.feeder.FileBasedFeederBuilder import io.gatling.core.structure.ScenarioBuilder class DeleteProject extends GerritSimulation { - private val data: FileBasedFeederBuilder[Any]#F = jsonFile(resource).queue + private val data: FileBasedFeederBuilder[Any]#F#F = jsonFile(resource).convert(url).queue val test: ScenarioBuilder = scenario(name) .feed(data) diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala index b628bc7924..a159977edf 100644 --- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala +++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala @@ -23,7 +23,8 @@ import io.gatling.http.request.builder.HttpRequestBuilder class GerritSimulation extends Simulation { implicit val conf: GatlingGitConfiguration = GatlingGitConfiguration() - private val path: String = this.getClass.getPackage.getName.replaceAllLiterally(".", "/") + private val pack: String = this.getClass.getPackage.getName + private val path: String = pack.replaceAllLiterally(".", "/") protected val name: String = this.getClass.getSimpleName protected val resource: String = s"data/$path/$name.json" @@ -31,4 +32,27 @@ class GerritSimulation extends Simulation { protected val httpProtocol: HttpProtocolBuilder = http.basicAuth( conf.httpConfiguration.userName, conf.httpConfiguration.password) + + protected val url: PartialFunction[(String, Any), Any] = { + case ("url", url) => + var in = replaceProperty("hostname", "localhost", url.toString) + in = replaceProperty("http_port", 8080, in) + replaceProperty("ssh_port", 29418, in) + } + + private def replaceProperty(term: String, default: Any, in: String): String = { + val key: String = term.toUpperCase + val property = pack + "." + term + var value = default + default match { + case _: String => + val propertyValue = Option(System.getProperty(property)) + if (propertyValue.nonEmpty) { + value = propertyValue.get + } + case _: Integer => + value = Integer.getInteger(property, default.asInstanceOf[Integer]) + } + in.replaceAllLiterally(key, value.toString) + } }