blob: b9f62df803d8f1ce5d9de5fdb17fe1ab56a2fef1 [file] [log] [blame] [view] [edit]
# Gerrit Load Testing
This project provides a tool to load test Gerrit by running a set of actions
typically used by Gerrit users.
The test relies heavily on randomness. The script will for the duration of the
tests loop through all possible actions that are defined. For each action it will
calculate a random number between 0 and 1 and execute the action if the number
is higher than a configured threshold. Thus, depending on the configuration, not
all actions will be executed in each cycle of the loop, thereby simulating that
users will not always do the same series of actions. By adjusting the probability
thresholds different scenarios based on statistics can be simulated.
## Requirements
- Python 3
- Pipenv [1]
## Contribute
The python scripts are formatted using `black` [2]. The code style is further
checked by `pylint` [3].
To install the tools, run:
```sh
pipenv install --dev
```
To lint the files, run:
```sh
pipenv run black $(find . -name '*.py') && pipenv run pylint $(find . -name '*.py')
```
Black will automatically format all python-files. Pylint, however, will not
automatically fix issues in the code. Please fix the issues pylint is showing or
in reasonable cases disable the respective rules in a reasonable scope.
## Build
The tool is meant to be run in a container. To build this container, run:
```sh
docker build -t gerrit/loadtester ./container
```
## Configuration
A configuration file in yaml-format can be used to configure the test run. The
`config.sample.yaml`-file gives an example-configuration.
The single configuration values are listed here:
| key | description | default value |
|-------------------------------------------------|---------------------------------------------------------------------------------------|-------------------------|
| `gerrit.url` | URL of the Gerrit test server | `http://localhost:8080` |
| `gerrit.user` | Gerrit user used for tests | `admin` |
| `gerrit.password` | Password of Gerrit user | `secret` |
| `testrun.duration` | Duration for which to run the tests | `null` (indefinitely) |
| `testrun.initialization.delay.enabled` | Whether to delay execution of a test run | `true` |
| `testrun.initialization.delay.min` | Minimum initial delay in seconds | `0` |
| `testrun.initialization.delay.max` | Maximum initial delay in seconds | `300` |
| `testrun.initialization.createProjects.enabled` | Whether to create new projects during initialization | `true` |
| `testrun.initialization.createProjects.number` | How many new projects to create during initialization | `1` |
| `testrun.initialization.knownProjects` | List of projects that the simulated user knows of from the beginning | `nil` |
| `testrun.waitBetweenCycles.enabled` | Whether to pause between test cycles | `true` |
| `testrun.waitBetweenCycles.min` | Minimum time of pause | `1` |
| `testrun.waitBetweenCycles.max` | Maximum time of pause | `10` |
| `actions.*` | Probability with which an action is performed in each cycle (`0`: never, `1`: always) | `1` |
### Available actions
The following actions can be performed by the tests:
| key | description |
|------------------------------|------------------------------------------------------------------------------------------|
| `clone_project` | Test performs a clone of a project, that is assigned to the simulated user |
| `create_project` | Test creates a new project via REST |
| `fetch_project` | Test fetches a project, that is assigned to the simulated user and was already cloned |
| `push_for_review` | Test creates random commits in a cloned project and pushes them to `refs/for/master` |
| `push_head_to_master` | Test creates random commits in a cloned project and pushes them to the remote's `master` |
| `query_hundred_open_changes` | Queries changes via REST |
| `query_projects` | Queries projects via REST |
| `review_change` | Reviews a change via REST |
## Run
### Docker
To run an instance of the load tester. run:
```sh
docker run -it gerrit/loadtester \
--config $CONFIG_FILE \
--duration $TEST_DURATION \
--password $GERRIT_PWD \
--url $GERRIT_URL \
--user $GERRIT_USER
```
The options are:
- `--config` (default: `None`): Path to a config file (optional). The config file
has to be present in the container, either by building it in or by mounting it.
Parameters will overwrite configuration from file.
- `--duration` (default: `None`): Duration, for which to run the tests in
seconds (optional; if not set, test runs until stopped)
- `--password` (default: `secret`): Password of Gerrit user used for executing
actions
- `--url`: URL of Gerrit (REQUIRED; e.g. `https://gerrit.example.com`)
- `--user` (default: `admin`): User to be used for executing actions
If the target Gerrit server is using the HTTPS-protocol, the load test requires
a valid not self-signed CA. Certificates that are mounted to the
`/var/loadtest/certs` will be used to that perpose. This can be done like this:
```sh
docker run -it gerrit/loadtester \
-v <certificate dir>:/var/loadtest/certs
```
### Kubernetes
The docker containers may be used to run the load tests in Kubernetes to simulate
multiple users (each instance acts as a single user). This project provides an
example deployment yaml: `./kubernetes/load-tester/load-tester.*.yaml`.
To install the Kubernetes setup, adjust the configuration in the yaml-files.
- Configure the Gerrit user data and add certificates for HTTPS-connections
in `./kubernetes/load-tester/load-tester.secret.yaml`.
The values have to be base64-encoded.
- Adjust the configuration file in `./kubernetes/load-tester/load-tester.configmap.yaml`.
The config-file structure is the same as described above.
- Adjust the number of replica-pods and the location of the docker image in
`./kubernetes/load-tester/load-tester.deployment.yaml`.
Afterwards, create all resources on the cluster:
```sh
Kubectl apply ./kubernetes/load-tester/load-tester.secret.yaml
Kubectl apply ./kubernetes/load-tester/load-tester.configmap.yaml
Kubectl apply ./kubernetes/load-tester/load-tester.deployment.yaml
```
Further, an example deployment for a logging stack based on ElasticSearch,
FluentBit and Kibana to collect the logs created by the load testing scripts is
provided in `./efk/`.
To install the EFK-stack, run:
```sh
helm install stable/elasticsearch \
-n elasticsearch \
-f ./kubernetes/efk/elasticsearch.yaml \
--namespace logging
helm install stable/fluent-bit \
-n fluentbit \
-f ./kubernetes/efk/fluentbit.yaml \
--namespace logging
helm install stable/kibana \
-f kubernetes/efk/kibana.yaml \
-n kibana \
--namespace logging
```
## Links
[1] https://github.com/pypa/pipenv
[2] https://github.com/psf/black
[3] https://www.pylint.org/