Merge branch 'stable-3.1'

* stable-3.1:
  e2e-tests: Introduce example to test local setups
  e2e-tests: Foster IntelliJ for Scala and build.sbt
  e2e-tests: Sort and update some .gitignore entries
  e2e-tests: Expand ssh key generation documentation
  e2e-tests: Document example test project existence
  Highlight WORKSPACE as python
  Highlight BUILD.bazel as python
  e2e-tests: Remove the note after sbt website fixed

Change-Id: I5c856f9c650e2d44655519b6b318ef41f6d71815
This commit is contained in:
David Pursehouse 2020-02-03 08:33:49 +09:00
commit 9b020576bf
6 changed files with 118 additions and 35 deletions

View File

@ -20,7 +20,10 @@ to run tests at Git protocol level.
Gatling is written in Scala, but the abstraction provided by the Gatling DSL makes the scenarios
implementation easy even without any Scala knowledge.
Examples of scenarios can be found in the `e2e-tests` directory.
Examples of scenarios can be found in the `e2e-tests` directory. The files in that directory
should be formatted using the mainstream
link:https://plugins.jetbrains.com/plugin/1347-scala[Scala plugin for IntelliJ,role=external,window=_blank].
The latter is not mandatory but preferred for `sbt` and Scala IDE purposes in this project.
== How to build the tests
@ -36,9 +39,7 @@ sbt compile
The following warning, if present when executing `sbt` commands, can be removed by creating the
link:https://www.scala-sbt.org/1.x/docs/Using-Sonatype.html#step+3%3A+Credentials[related credentials file,role=external,window=_blank]
locally. Dummy values for `user` and `password` in that file can be used initially. Notice the
plural form for the file name, expected by the warning (below), compared to the one from that linked
example which is singular.
locally. Dummy values for `user` and `password` in that file can be used initially.
----
[warn] Credentials file ~/.sbt/sonatype_credentials does not exist
@ -67,26 +68,36 @@ If you are running SSH commands, the private keys of the users used for testing
link:https://stackoverflow.com/questions/53134212/invalid-privatekey-when-using-jsch[otherwise,role=external,window=_blank]):
----
mkdir /tmp/ssh-keys
ssh-keygen -m PEM -t rsa -C "test@mail.com" -f /tmp/ssh-keys/id_rsa
----
*NOTE*: Don't forget to add the public keys for the testing user(s) to your git server.
The public key in `/tmp/ssh-keys/id_rsa.pub` has to be added to the test user(s) `SSH Keys` in
Gerrit. Now, the host from which the latter runs may need public key scanning to become known.
This applies to the local user that runs the forthcoming `sbt` testing commands. An example
assuming `localhost` follows:
----
ssh-keyscan -t rsa -p 29418 localhost > ~/.ssh/known_hosts
----
=== Input file
The `ReplayRecordsFromFeederScenario` is fed with the data coming from the
`src/test/resources/data/requests.json` file. Such a file contains the commands and repo used
during the load test. Example below:
The `CloneUsingBothProtocols` scenario is fed with the data coming from the
`src/test/resources/data/CloneUsingBothProtocols.json` file. Such a file contains the commands and
repository used during the load 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.
----
[
{
"url": "ssh://admin@localhost:29418/loadtest-repo.git",
"url": "ssh://admin@localhost:29418/loadtest-repo",
"cmd": "clone"
},
{
"url": "http://localhost:8080/loadtest-repo.git",
"cmd": "fetch"
"url": "http://localhost:8080/loadtest-repo",
"cmd": "clone"
}
]
----
@ -98,6 +109,8 @@ Valid commands are:
* `push`
* `clone`
The example above assumes that the `loadtest-repo` project exists in the Gerrit under test.
== How to run tests
Run all tests:
@ -107,7 +120,7 @@ sbt "gatling:test"
Run a single test:
----
sbt "gatling:testOnly com.google.gerrit.scenarios.ReplayRecordsFromFeederScenario"
sbt "gatling:testOnly com.google.gerrit.scenarios.CloneUsingBothProtocols"
----
Generate the last report:
@ -122,7 +135,7 @@ Gatling's logging level.
=== How to run using Docker
----
docker run -it e2e-tests -s com.google.gerrit.scenarios.ReplayRecordsFromFeederScenario
docker run -it e2e-tests -s com.google.gerrit.scenarios.CloneUsingBothProtocols
----
GERRIT

View File

@ -1,16 +1,13 @@
.idea/
/.idea/
# mpeltonen/sbt-idea plugin
/.idea_modules/
# File-based project format
*.iws
# IntelliJ
out/
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
### Scala ###
*.class
*.log
target
project/target
# Scala sbt
target/

View File

@ -4,15 +4,15 @@ enablePlugins(GatlingPlugin)
lazy val gatlingGitExtension = RootProject(uri("git://github.com/GerritForge/gatling-git.git"))
lazy val root = (project in file("."))
.settings(
inThisBuild(List(
organization := "com.google.gerrit",
scalaVersion := "2.12.8",
version := "0.1.0-SNAPSHOT"
)),
name := "gerrit",
libraryDependencies ++=
gatling ++
Seq("io.gatling" % "gatling-core" % "3.1.1" ) ++
Seq("io.gatling" % "gatling-app" % "3.1.1" )
) dependsOn(gatlingGitExtension)
.settings(
inThisBuild(List(
organization := "com.google.gerrit",
scalaVersion := "2.12.8",
version := "0.1.0-SNAPSHOT"
)),
name := "gerrit",
libraryDependencies ++=
gatling ++
Seq("io.gatling" % "gatling-core" % "3.1.1") ++
Seq("io.gatling" % "gatling-app" % "3.1.1")
) dependsOn gatlingGitExtension

View File

@ -0,0 +1,10 @@
[
{
"url": "ssh://admin@localhost:29418/loadtest-repo",
"cmd": "clone"
},
{
"url": "http://localhost:8080/loadtest-repo",
"cmd": "clone"
}
]

View File

@ -0,0 +1,61 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.scenarios
import java.io._
import com.github.barbasa.gatling.git.protocol.GitProtocol
import com.github.barbasa.gatling.git.request.builder.GitRequestBuilder
import com.github.barbasa.gatling.git.{GatlingGitConfiguration, GitRequestSession}
import io.gatling.core.Predef._
import io.gatling.core.feeder.FileBasedFeederBuilder
import io.gatling.core.structure.ScenarioBuilder
import org.apache.commons.io.FileUtils
import org.eclipse.jgit.hooks._
import scala.concurrent.duration._
class CloneUsingBothProtocols extends Simulation {
implicit val conf: GatlingGitConfiguration = GatlingGitConfiguration()
implicit val postMessageHook: Option[String] = Some(s"hooks/${CommitMsgHook.NAME}")
private val name: String = this.getClass.getSimpleName
private val file = s"data/$name.json"
private val data: FileBasedFeederBuilder[Any]#F = jsonFile(file).circular
private val request = new GitRequestBuilder(GitRequestSession("${cmd}", "${url}"))
private val protocol: GitProtocol = GitProtocol()
private val test: ScenarioBuilder = scenario(name)
.feed(data)
.exec(request)
setUp(
test.inject(
constantUsersPerSec(1) during (2 seconds))
).protocols(protocol)
after {
Thread.sleep(5000)
val path = conf.tmpBasePath
try {
FileUtils.deleteDirectory(new File(path))
} catch {
case e: IOException =>
System.err.println("Unable to delete temporary directory " + path)
e.printStackTrace()
}
}
}

View File

@ -13,6 +13,7 @@ bucklet = text/x-python
bzl = text/x-python
BUCK = text/x-python
BUILD = text/x-python
BUILD.bazel = text/x-python
c = text/x-csrc
cfg = text/x-ttcn-cfg
cl = text/x-common-lisp
@ -247,6 +248,7 @@ vm = text/velocity
vtl = text/velocity
webidl = text/x-webidl
wsdl = application/xml
WORKSPACE = text/x-python
xaml = application/xml
xhtml = text/html
xml = application/xml