Skip to content

Commit 6ab2b37

Browse files
authored
Add stress tests module for Event Hubs (Azure#28958)
* Add stress tests for Event Hubs * Update README and pom.xml * Update configuration to solve bean circular dependency issue * Update version text * Clean blank line * Add stress test module in ci.yml * Update pom.xml * Update pom.xml * Update java doc * Update links in README * Update java code base on comments * Add application insights into dockerfile and update README * Fix link verification failure issue * Update class naming and add guid() for bicep file * Update bicep file * Rename constants * Change logger to clientLogger * Change dependency to alphabet order * Use spring to inject env variables as scenario options * Update README * Set string default value as null * Change auth rule to namespace level to avoid being created for each EH * Add parent project in pom.xml * Update pom.xml version format * Update pom.xml * Update dependency version * Update pom.xml and external_dependencies * Update pom.xml version * Update pom.xml and applicationinsights version
1 parent ee4032a commit 6ab2b37

22 files changed

+1183
-0
lines changed

eng/versioning/external_dependencies.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ com.github.spotbugs:spotbugs-maven-plugin;4.2.2
2323
com.google.code.gson:gson;2.9.1
2424
com.google.guava:guava;30.1.1-jre
2525
com.h3xstream.findsecbugs:findsecbugs-plugin;1.9.0
26+
com.microsoft.azure:applicationinsights-core;3.4.1
2627
com.microsoft.azure:azure-annotations;1.7.0
2728
com.microsoft.azure:azure-arm-client-runtime;1.7.14
2829
com.microsoft.azure:azure-client-authentication;1.7.14
@@ -128,6 +129,7 @@ org.springframework.boot:spring-boot-autoconfigure-processor;2.7.4
128129
org.springframework.boot:spring-boot-autoconfigure;2.7.4
129130
org.springframework.boot:spring-boot-configuration-metadata;2.7.4
130131
org.springframework.boot:spring-boot-configuration-processor;2.7.4
132+
org.springframework.boot:spring-boot-maven-plugin;2.7.4
131133
org.springframework.boot:spring-boot-starter-actuator;2.7.4
132134
org.springframework.boot:spring-boot-starter-aop;2.7.4
133135
org.springframework.boot:spring-boot-starter-cache;2.7.4

eng/versioning/version_client.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ com.azure:azure-messaging-eventgrid-cloudnative-cloudevents;1.0.0-beta.1;1.0.0-b
118118
com.azure:azure-messaging-eventhubs;5.13.1;5.14.0-beta.1
119119
com.azure:azure-messaging-eventhubs-checkpointstore-blob;1.15.1;1.16.0-beta.1
120120
com.azure:azure-messaging-eventhubs-checkpointstore-jedis;1.0.0-beta.1;1.0.0-beta.1
121+
com.azure:azure-messaging-eventhubs-stress;1.0.0-beta.1;1.0.0-beta.1
121122
com.azure:azure-messaging-eventhubs-track1-perf;1.0.0-beta.1;1.0.0-beta.1
122123
com.azure:azure-messaging-eventhubs-track2-perf;1.0.0-beta.1;1.0.0-beta.1
123124
com.azure:azure-messaging-servicebus;7.11.0;7.12.0-beta.1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target/
2+
src/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Release History
2+
3+
## 1.0.0-beta.1 (Unreleased)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: v2
2+
name: java-eventhubs-stress-test
3+
description: stress test for azure event hubs client in java
4+
version: 0.1.1
5+
appVersion: v0.1
6+
annotations:
7+
stressTest: 'true' # enable auto-discovery of this test via `find-all-stress-packages.ps1`
8+
example: 'true' # enable auto-discovery filtering `find-all-stress-packages.ps1 -filters @{example='true'}`
9+
namespace: 'java-eh' # kubernetes namespace that stress test package will be installed
10+
11+
dependencies:
12+
- name: stress-test-addons
13+
version: 0.1.20
14+
repository: https://stresstestcharts.blob.core.windows.net/helm/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM mcr.microsoft.com/java/jdk:11-zulu-alpine as builder
2+
WORKDIR application
3+
ARG JAR_FILE=target/*.jar
4+
COPY ${JAR_FILE} application.jar
5+
RUN java -Djarmode=layertools -jar application.jar extract
6+
7+
FROM mcr.microsoft.com/java/jdk:11-zulu-alpine
8+
WORKDIR application
9+
COPY --from=builder application/dependencies/ ./
10+
COPY --from=builder application/spring-boot-loader/ ./
11+
COPY --from=builder application/snapshot-dependencies/ ./
12+
COPY --from=builder application/application/ ./
13+
ARG AGENT_URL=https://github.com/microsoft/ApplicationInsights-Java/releases/download/3.4.1/applicationinsights-agent-3.4.1.jar
14+
ADD ${AGENT_URL} ./BOOT-INF/classes/
15+
ENTRYPOINT ["java","org.springframework.boot.loader.JarLauncher", \
16+
"-javaagent:BOOT-INF/classes/applicationinsights-agent-3.4.1.jar", \
17+
"--TEST_CLASS=EventSender"]
18+
Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
# Azure Event Hubs Stress test client library for Java
2+
3+
Represents stress tests for Event Hubs client.
4+
5+
## Getting started
6+
7+
The stress tests for event hubs client is developed from [azure-sdk-chaos][azure_sdk_chaos].
8+
9+
### Prerequisites
10+
11+
- [Java Development Kit (JDK)][jdk_link], version 8 or later.
12+
- [Maven][maven]
13+
- [Docker][docker]
14+
- [Kubectl][kubectl]
15+
- [Helm][helm]
16+
- [Azure CLI][azure_cli]
17+
- [Powershell 7.0+][powershell]
18+
19+
### Deploy Stress Test
20+
21+
Build out the jar package:
22+
23+
```shell
24+
cd <current project path>
25+
mvn clean install
26+
```
27+
28+
Run command to deploy the package to cluster:
29+
30+
```shell
31+
..\..\..\eng\common\scripts\stress-testing\deploy-stress-tests.ps1 -Login -PushImage
32+
```
33+
34+
### Validate Status
35+
36+
Only the most frequently used commands are listed below. See [Deploying A Stress Test][deploy_stress_test] for more details.
37+
38+
List deployed packages:
39+
40+
```shell
41+
helm list -n <stress test namespace>
42+
```
43+
44+
Get stress test pods and status:
45+
46+
```shell
47+
kubectl get pods -n <stress test namespace>
48+
```
49+
50+
Get stress test pod logs:
51+
52+
```shell
53+
kubectl logs -n <stress test namespace> <stress test pod name>
54+
# Note that we may define multiple containers (for example, sender and receiver)
55+
kubectl logs -n <stress test namespace> <stress test pod name> -c <container name>
56+
```
57+
58+
If stress test pod is in `Error` status, check logs from init container:
59+
60+
```shell
61+
kubectl logs -n <stress test namespace> <stress test pod name> -c init-azure-deployer
62+
```
63+
64+
If above command output is empty, there may have been startup failures:
65+
66+
```shell
67+
kubectl describe pod -n <stress test namespace> <stress test pod name>
68+
```
69+
70+
Stop and remove deployed package:
71+
72+
```shell
73+
helm uninstall <stress test name> -n <stress test namespace>
74+
```
75+
76+
### Configure Faults
77+
78+
See [Config Faults][config_faults] section for details.
79+
80+
### Configure Monitor
81+
82+
We have configured Application Insights on cluster. The telemetry data can be monitored on the Application Insights provided by cluster.
83+
84+
For local test, you can follow the [steps][enable_application_insights] to enable application insights. Make sure you have added below JVM parameters when you start the test.
85+
86+
```yaml
87+
java -javaagent:<path to the downloaded jar>/applicationinsights-agent-3.2.11.jar
88+
```
89+
90+
## Key concepts
91+
92+
### Project Structure
93+
94+
See [Layout][stress_test_layout] section for details.
95+
96+
Below is the current structure of project:
97+
```
98+
.
99+
├── src/ # Test code
100+
├── templates/ # A directory of helm templates that will generate Kubernetes manifest files.
101+
├── Chart.yaml # A YAML file containing information about the helm chart and its dependencies
102+
├── Dockerfile # A Dockerfile for building the stress test image
103+
├── stress-test-resouce.bicep # An Azure Bicep for deploying stress test azure resources
104+
├── values.yaml # Any default helm template values for this chart, e.g. a `scenarios` list
105+
├── pom.xml
106+
└── README.md
107+
```
108+
109+
### Cluster Namespace
110+
111+
The cluster namespace is defined in `Chart.yaml`. The default value we set is `java-eh`.
112+
113+
```yaml
114+
name: <stress test name>
115+
...
116+
annotations:
117+
namespace: <stress test namespace>
118+
```
119+
120+
For local deployment with script, if the namespace option is not specified, the value will be overridden by the shell username.
121+
122+
```shell
123+
..\..\..\eng\common\scripts\stress-testing\deploy-stress-tests.ps1 -Namespace <stress test namespace>
124+
```
125+
126+
## Examples
127+
128+
### Update EventSender
129+
130+
Change `SEND_TIMES` and `EVENT_NUMBER` to the number of events you want to send.
131+
132+
### Run EventProcessorWithOptions
133+
134+
Modify receiver command in `job.yaml` to run stress test in different scenarios:
135+
136+
Scenario 1: receiver does not checkpoint and not write to another new event hub.
137+
138+
```yaml
139+
- name: receiver
140+
image: {{ .Values.image }}
141+
imagePullPolicy: Always
142+
command: ['sh', '-c']
143+
args:
144+
- |
145+
set -a &&
146+
source $ENV_FILE &&
147+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
148+
"org.springframework.boot.loader.JarLauncher" \
149+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=false --NEED_SEND_EVENT_HUB=false
150+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
151+
```
152+
Scenario 2: receiver does checkpoint and not write to another new event hub.
153+
154+
```yaml
155+
- name: receiver
156+
image: {{ .Values.image }}
157+
imagePullPolicy: Always
158+
command: ['sh', '-c']
159+
args:
160+
- |
161+
set -a &&
162+
source $ENV_FILE &&
163+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
164+
"org.springframework.boot.loader.JarLauncher" \
165+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=true --NEED_SEND_EVENT_HUB=false
166+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
167+
```
168+
169+
Scenario 3: receiver does checkpoint and write to another event hub.
170+
171+
```yaml
172+
- name: receiver
173+
image: {{ .Values.image }}
174+
imagePullPolicy: Always
175+
command: ['sh', '-c']
176+
args:
177+
- |
178+
set -a &&
179+
source $ENV_FILE &&
180+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
181+
"org.springframework.boot.loader.JarLauncher" \
182+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=true --NEED_SEND_EVENT_HUB=true
183+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
184+
```
185+
186+
Scenario 4: Four receiver does checkpoint and not write to another new event hub.
187+
188+
```yaml
189+
- name: receiver1
190+
image: {{ .Values.image }}
191+
imagePullPolicy: Always
192+
command: ['sh', '-c']
193+
args:
194+
- |
195+
set -a &&
196+
source $ENV_FILE &&
197+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
198+
"org.springframework.boot.loader.JarLauncher" \
199+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=true --NEED_SEND_EVENT_HUB=false
200+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
201+
- name: receiver2
202+
image: {{ .Values.image }}
203+
imagePullPolicy: Always
204+
command: ['sh', '-c']
205+
args:
206+
- |
207+
set -a &&
208+
source $ENV_FILE &&
209+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
210+
"org.springframework.boot.loader.JarLauncher" \
211+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=true --NEED_SEND_EVENT_HUB=false
212+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
213+
- name: receiver3
214+
image: {{ .Values.image }}
215+
imagePullPolicy: Always
216+
command: ['sh', '-c']
217+
args:
218+
- |
219+
set -a &&
220+
source $ENV_FILE &&
221+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
222+
"org.springframework.boot.loader.JarLauncher" \
223+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=true --NEED_SEND_EVENT_HUB=false
224+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
225+
- name: receiver4
226+
image: {{ .Values.image }}
227+
imagePullPolicy: Always
228+
command: ['sh', '-c']
229+
args:
230+
- |
231+
set -a &&
232+
source $ENV_FILE &&
233+
java -javaagent:BOOT-INF/classes/applicationinsights-agent-3.2.11.jar \
234+
"org.springframework.boot.loader.JarLauncher" \
235+
--TEST_CLASS=EventProcessorWithOptions --UPDATE_CHECKPOINT=true --NEED_SEND_EVENT_HUB=false
236+
{{- include "stress-test-addons.container-env" . | nindent 6 }}
237+
```
238+
239+
### Add New Test Scenario
240+
241+
Add a new test class under `\scenarios`.
242+
243+
Extend `EventHubsScenarios` and implement test logic in `run()` method.
244+
245+
Configure new class as bean and use class name as its bean name.
246+
247+
Update `args` field in `job.yaml` to execute the new test class.
248+
249+
Build out jar package and redeploy to cluster.
250+
251+
### Add New Scenario Option
252+
253+
We use [Spring][spring_configuration] to inject environment variable or
254+
command line arguments as the scenario options.
255+
256+
You can add new scenario option in [ScenarioOptions][ScenarioOptions] with below format:
257+
258+
```java
259+
@Value("NEW_OPTION: default value")
260+
private Type newOption;
261+
262+
public Type getNewOption() {
263+
return newOption;
264+
}
265+
```
266+
267+
It is recommended to provide a default value for the new option, as it will not have any impact
268+
on the existing job configuration.
269+
270+
## Troubleshooting
271+
272+
## Next steps
273+
274+
## Contributing
275+
276+
For details on contributing to this repository, see the [contributing guide](https://github.com/Azure/azure-sdk-for-java/blob/main/CONTRIBUTING.md).
277+
278+
1. Fork it
279+
1. Create your feature branch (`git checkout -b my-new-feature`)
280+
1. Commit your changes (`git commit -am 'Add some feature'`)
281+
1. Push to the branch (`git push origin my-new-feature`)
282+
1. Create new Pull Request
283+
284+
<!-- links -->
285+
[event_hubs_create]: https://docs.microsoft.com/azure/event-hubs/event-hubs-create
286+
[jdk_link]: https://docs.microsoft.com/java/azure/jdk/?view=azure-java-stable
287+
[maven]: https://maven.apache.org/
288+
[docker]: https://docs.docker.com/get-docker/
289+
[kubectl]: https://kubernetes.io/docs/tasks/tools/#kubectl
290+
[helm]: https://helm.sh/docs/intro/install/
291+
[azure_cli]: https://docs.microsoft.com/cli/azure/install-azure-cli
292+
[powershell]: https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-7
293+
[azure_sdk_chaos]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/stress-cluster/chaos/README.md
294+
[enable_application_insights]: https://docs.microsoft.com/azure/azure-monitor/app/java-in-process-agent#enable-azure-monitor-application-insights
295+
[deploy_stress_test]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/stress-cluster/chaos/README.md#deploying-a-stress-test
296+
[config_faults]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/stress-cluster/chaos/README.md#configuring-faults
297+
[stress_test_layout]: https://github.com/Azure/azure-sdk-tools/blob/main/tools/stress-cluster/chaos/README.md#layout
298+
[spring_configuration]: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config
299+
[ScenarioOptions]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/eventhubs/azure-messaging-eventhubs-stress/src/main/java/com/azure/messaging/eventhubs/stress/util/ScenarioOptions.java

0 commit comments

Comments
 (0)