Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/run-performance-tests.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Performance test workflow to compare a baseline against a candidate DHIS2 version
# You can run the workflow using the GitHub CLI like so
# gh workflow run run-performance-tests.yml \
# --field simulation_class="org.hisp.dhis.test.tracker.EnrollmentsTest" \
# --field simulation_class="org.hisp.dhis.test.tracker.TrackerTest" \
# --field dhis2_image_baseline="dhis2/core:2.42.1" \
# --field dhis2_image_candidate="dhis2/core-dev:latest"
#
Expand All @@ -16,7 +16,7 @@ on:
workflow_dispatch:
inputs:
simulation_class:
description: 'Fully qualified Gatling simulation class to run (e.g., org.hisp.dhis.test.EnrollmentsTest)'
description: 'Fully qualified Gatling simulation class to run (e.g., org.hisp.dhis.test.TrackerTest)'
Comment thread
teleivo marked this conversation as resolved.
required: true
type: string
mvn_args:
Expand Down Expand Up @@ -74,9 +74,10 @@ jobs:

- name: Run performance tests - baseline
run: |
# Skip baseline assertion failures to allow tightening performance thresholds based on candidate improvements
DHIS2_IMAGE="${{ inputs.dhis2_image_baseline }}" \
SIMULATION_CLASS="${{ inputs.simulation_class }}" \
MVN_ARGS="${{ inputs.mvn_args }}" \
MVN_ARGS="${{ inputs.mvn_args }} -Dgatling.failOnError=false" \
DHIS2_DB_DUMP_URL="${{ inputs.dhis2_db_dump_url }}" \
DHIS2_DB_IMAGE_SUFFIX="${{ inputs.dhis2_db_image_suffix }}" \
./run-simulation.sh
Expand All @@ -97,12 +98,13 @@ jobs:
# binary simulation.log into a simulation.csv. CLI releases can be downloaded from
# https://github.com/dhis2/gatling/releases. The CLI is installed on the self-hosted runner.
- name: Convert binary simulation.log to simulation.csv
id: convert-logs
if: always()
run: |
glog --config ./src/test/resources/gatling.conf --scan-subdirs target/gatling

- name: Upload Gatling report
if: always() # reports should always be uploaded as tests can fail due to our performance assertions
if: steps.convert-logs.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: gatling-report-${{ github.run_id }}-${{ github.sha }}
Expand Down
2 changes: 1 addition & 1 deletion dhis-2/dhis-test-e2e/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<jackson.version.annotation>2.20</jackson.version.annotation>
<guava.version>33.5.0-jre</guava.version>
<json-tree.version>1.8.1</json-tree.version>
<epam-reportportal.version>5.4.0</epam-reportportal.version>
<epam-reportportal.version>5.3.0</epam-reportportal.version>
<javafaker.version>1.0.2</javafaker.version>
<opencsv.version>5.12.0</opencsv.version>
<owner.version>1.0.12</owner.version>
Expand Down
43 changes: 43 additions & 0 deletions dhis-2/dhis-test-performance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# DHIS2 Performance Tests

Run Gatling performance tests against DHIS2 Docker instances locally and in CI.

## Quick Start

```sh
DHIS2_IMAGE=dhis2/core-dev:latest \
SIMULATION_CLASS=org.hisp.dhis.test.tracker.TrackerTest \
./run-simulation.sh
```

Run `./run-simulation.sh` for full usage including profiling and database options.

## Results

Test results are saved to `target/gatling/<simulation-class>-<timestamp>/`:

* `index.html` - Gatling HTML report
* `simulation.log` - Binary response times
* `simulation.csv` - Response times (automated in CI only, [see below](#simulationcsv))
* `simulation-run.txt` - Run metadata
* `profile.html` - Flamegraph (when profiling enabled)
* `profile.jfr` - JFR (Java flight recorder) profiling data (when profiling enabled)

### simulation.csv

If `index.html` doesn't provide the analysis you need, convert `simulation.log` to `simulation.csv`
for advanced analysis with [gatling-statistics](https://github.com/dhis2/gatling-statistics).

Since Gatling 3.12, test results are written in binary format. Use
[glog](https://github.com/dhis2/gatling/releases) (a CLI from our Gatling fork) to convert:

```sh
glog --config ./src/test/resources/gatling.conf --scan-subdirs target/gatling
```

## CI Usage

`./run-simulation.sh` is used in
[`../../.github/workflows/run-performance-tests.yml`](../../.github/workflows/run-performance-tests.yml)
to compare performance between baseline and candidate DHIS2 versions.

49 changes: 49 additions & 0 deletions dhis-2/dhis-test-performance/docker-compose.profile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
services:
web:
# Required for async-profiler to access perf_events
# See: https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilingInContainer.md
cap_add:
- SYS_ADMIN # Access to performance counters
security_opt:
- seccomp:unconfined # Allow profiling syscalls
environment:
JAVA_OPTS:
"-Dlog4j2.configurationFile=/opt/dhis2/log4j2.xml \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8081 \
-XX:+UnlockDiagnosticVMOptions \
-XX:+DebugNonSafepoints" # Accurate profiling at all code locations
volumes:
- async-profiler:/usr/local
- async-profiler-output:/profiler-output
ports:
- "127.0.0.1:8081:8081" # Debugger: connect using commandline flag -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8081
depends_on:
async-profiler-setup:
condition: service_completed_successfully

async-profiler-setup:
image: busybox
command: |
sh -c '
if [ ! -f /usr/local/bin/asprof ]; then
echo "Downloading async-profiler..."
wget -O /tmp/async-profiler.tar.gz https://github.com/async-profiler/async-profiler/releases/download/v4.0/async-profiler-4.0-linux-x64.tar.gz &&
mkdir -p /usr/local/bin /usr/local/lib &&
tar -xzf /tmp/async-profiler.tar.gz -C /tmp &&
cp /tmp/async-profiler-4.0-linux-x64/bin/* /usr/local/bin/ &&
cp /tmp/async-profiler-4.0-linux-x64/lib/* /usr/local/lib/ &&
chmod +x /usr/local/bin/asprof &&
chmod +x /usr/local/bin/jfrconv &&
echo "async-profiler installed to /usr/local"
else
echo "async-profiler already installed"
fi &&
chmod 777 /profiler-output
'
volumes:
- async-profiler:/usr/local
- async-profiler-output:/profiler-output

volumes:
async-profiler: {}
async-profiler-output: {}
13 changes: 12 additions & 1 deletion dhis-2/dhis-test-performance/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>

<groupId>org.dhis</groupId>
<artifactId>performance-tests-gatling</artifactId>
<artifactId>dhis-test-performance</artifactId>
<version>1.0</version>
<description>Performance tests for DHIS2 using Gatling framework</description>

Expand All @@ -16,6 +16,7 @@
<gatling.version>3.14.3</gatling.version>
<gatling-maven-plugin.version>4.19.0</gatling-maven-plugin.version>
<spotless.version>2.46.1</spotless.version>
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
</properties>

<dependencies>
Expand All @@ -33,6 +34,15 @@

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>17</release>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
Expand Down Expand Up @@ -73,5 +83,6 @@
</configuration>
</plugin>
</plugins>
<testSourceDirectory>src/test</testSourceDirectory>
</build>
</project>
Loading
Loading