Skip to content

Commit 3cf0fa7

Browse files
Harshan01Harshan B
andauthored
Loadtestservice - SDK initial version (Azure#30706)
* Initial java generation with minor fixes * Add examples in README.md, update versions in pom * DPG with pageable, and updated README/samples * Add multipart file upload Add troubleshooting and next steps in README Fix SDK path in CODEOWNERS * Add test recordings and update README * Add LoadTesting and Administration clients With swagger directives and accessors * Prepend LoadTest to subclients accessor methods Update samples and test cases * Add TestRun opId rename directive * Remove Administration and TestRun builders * Add simple methods without response Add doc for multipart utils Fix CODEOWNERS formatting * Main version_client.txt from main * Fix version_client.txt merge conflict * Revert "Add simple methods without response" This reverts commit 8cca1c4. * Correct casing of session records, dependencies and links * Make autogen uploadTest API package private * Rename getAll API to list * Change subclient getter method Update session-records and README.md * Final cleanup Rename test run createAndUpdate to createOrUpdate Co-authored-by: Harshan B <harshanb@microsoft.com>
1 parent 78c6516 commit 3cf0fa7

35 files changed

+12355
-1
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@
9292
# PRLabel: %azure-spring
9393
/sdk/cosmos/azure-spring-data-cosmos-test/ @kushagraThapar @FabianMeiswinkel @backwind1233 @chenrujun @hui1110 @netyyyy @saragluna @stliu @yiliuTo @xinlian12 @moarychan @aayush3011 @simorenoh @fangjian0423
9494

95+
# PRLabel: %Load Testing
96+
/sdk/loadtestservice/ @Harshan01 @abranj1219
97+
9598
# ServiceLabel: %Device Update for IoT Hub %Service Attention
9699
/sdk/deviceupdate/ @dpokluda
97100

eng/versioning/version_client.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ com.azure:azure-verticals-agrifood-farming;1.0.0-beta.2;1.0.0-beta.3
169169
com.azure:azure-xml;1.0.0-beta.1;1.0.0-beta.2
170170
com.azure:perf-test-core;1.0.0-beta.1;1.0.0-beta.1
171171
com.azure:azure-communication-email;1.0.0-beta.1;1.0.0-beta.2
172+
com.azure:azure-developer-loadtesting;1.0.0-beta.1;1.0.0-beta.1
172173
com.azure:azure-identity-providers-core;1.0.0-beta.1;1.0.0-beta.2
173174
com.azure:azure-identity-providers-jdbc-mysql;1.0.0-beta.1;1.0.0-beta.2
174175
com.azure:azure-identity-providers-jdbc-postgresql;1.0.0-beta.1;1.0.0-beta.2
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Release History
2+
3+
## 1.0.0-beta.1 (Unreleased)
4+
5+
- Initial preview release of Azure LoadTestingClient client library for Java. This package contains Microsoft Azure LoadTestingClient client library.
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
# Azure Load Testing client library for Java
2+
3+
Azure Load Testing provides client library in Java to the user by which they can interact natively with Azure Load Testing service. Azure Load Testing is a fully managed load-testing service that enables you to generate high-scale load. The service simulates traffic for your applications, regardless of where they're hosted. Developers, testers, and quality assurance (QA) engineers can use it to optimize application performance, scalability, or capacity
4+
5+
This package contains Microsoft Azure Developer LoadTesting client library.
6+
7+
## Documentation
8+
9+
Various documentation is available to help you get started
10+
11+
<!-- - [Source code][source_code] -->
12+
- [API reference documentation][api_reference_doc]
13+
- [Product Documentation][product_documentation]
14+
15+
## Getting started
16+
17+
### Prerequisites
18+
19+
- [Java Development Kit (JDK)][jdk] with version 8 or above
20+
- [Azure Subscription][azure_subscription]
21+
- Azure Load Testing resource
22+
23+
### Adding the package to your product
24+
25+
[//]: # ({x-version-update-start;com.azure:azure-developer-loadtesting;current})
26+
```xml
27+
<dependency>
28+
<groupId>com.azure</groupId>
29+
<artifactId>azure-developer-loadtesting</artifactId>
30+
<version>1.0.0-beta.1</version>
31+
</dependency>
32+
```
33+
[//]: # ({x-version-update-end})
34+
35+
### Authentication
36+
37+
[Azure Identity][azure_identity] package provides the default implementation for authenticating the client.
38+
39+
By default, Azure Active Directory token authentication depends on correct configure of following environment variables.
40+
41+
- `AZURE_CLIENT_ID` for Azure client ID.
42+
- `AZURE_TENANT_ID` for Azure tenant ID.
43+
- `AZURE_CLIENT_SECRET` or `AZURE_CLIENT_CERTIFICATE_PATH` for client secret or client certificate.
44+
45+
In addition, Azure subscription ID can be configured via environment variable `AZURE_SUBSCRIPTION_ID`.
46+
47+
With above configuration, `azure` client can be authenticated by following code:
48+
49+
```java java-readme-sample-auth
50+
// ensure the user, service principal or managed identity used has Loadtesting Contributor role for the resource
51+
TokenCredential credential = new DefaultAzureCredentialBuilder()
52+
.build();
53+
// create client using DefaultAzureCredential
54+
LoadTestingClient client = new LoadTestingClientBuilder()
55+
.credential(credential)
56+
.endpoint("<Enter Azure Load Testing Data-Plane URL>")
57+
.buildClient();
58+
LoadTestAdministrationClient adminClient = client.getLoadTestAdministrationClient();
59+
TestRunClient testRunClient = client.getLoadTestRunClient();
60+
```
61+
62+
## Key concepts
63+
64+
The following components make up the Azure Load Testing service. The Azure Load Test client library for Java allows you to interact with each of these components through the use of clients. There are two top-level clients which are the main entry points for the library
65+
66+
- `LoadTestingClient`
67+
68+
- `LoadTestingAsyncClient`
69+
70+
The two clients have similar methods in them except the methods in the async client are async as well.
71+
72+
The top-level clients have two sub-clients
73+
74+
- `LoadTestAdministration`
75+
76+
- `TestRun`
77+
78+
These sub-clients are used for managing and using different components of the service.
79+
80+
### Load Test Administration Client
81+
82+
The `LoadTestAdministration` sub-clients is used to administer and configure the load tests, app components and metrics.
83+
84+
#### Test
85+
86+
A test specifies the test script, and configuration settings for running a load test. You can create one or more tests in an Azure Load Testing resource.
87+
88+
#### App Component
89+
90+
When you run a load test for an Azure-hosted application, you can monitor resource metrics for the different Azure application components (server-side metrics). While the load test runs, and after completion of the test, you can monitor and analyze the resource metrics in the Azure Load Testing dashboard.
91+
92+
#### Metrics
93+
94+
During a load test, Azure Load Testing collects metrics about the test execution. There are two types of metrics:
95+
96+
1. Client-side metrics give you details reported by the test engine. These metrics include the number of virtual users, the request response time, the number of failed requests, or the number of requests per second.
97+
98+
2. Server-side metrics are available for Azure-hosted applications and provide information about your Azure application components. Metrics can be for the number of database reads, the type of HTTP responses, or container resource consumption.
99+
100+
### Test Run Client
101+
102+
The `TestRun` sub-clients is used to start and stop test runs corresponding to a load test. A test run represents one execution of a load test. It collects the logs associated with running the Apache JMeter script, the load test YAML configuration, the list of app components to monitor, and the results of the test.
103+
104+
### Data-Plane Endpoint
105+
106+
Data-plane of Azure Load Testing resources is addressable using the following URL format:
107+
108+
`00000000-0000-0000-0000-000000000000.aaa.cnt-prod.loadtesting.azure.com`
109+
110+
The first GUID `00000000-0000-0000-0000-000000000000` is the unique identifier used for accessing the Azure Load Testing resource. This is followed by `aaa` which is the Azure region of the resource.
111+
112+
The data-plane endpoint is obtained from Control Plane APIs.
113+
114+
**Example:** `1234abcd-12ab-12ab-12ab-123456abcdef.eus.cnt-prod.loadtesting.azure.com`
115+
116+
In the above example, `eus` represents the Azure region `East US`.
117+
118+
## Examples
119+
120+
### Creating a Load Test
121+
122+
```java java-readme-sample-createTest
123+
LoadTestingClient client = new LoadTestingClientBuilder()
124+
.credential(new DefaultAzureCredentialBuilder().build())
125+
.endpoint("<endpoint>")
126+
.buildClient();
127+
128+
// construct Test object using nested String:Object Maps
129+
Map<String, Object> testMap = new HashMap<String, Object>();
130+
testMap.put("displayName", "Sample Display Name");
131+
testMap.put("description", "Sample Description");
132+
133+
// loadTestConfig describes the number of test engines to generate load
134+
Map<String, Object> loadTestConfigMap = new HashMap<String, Object>();
135+
loadTestConfigMap.put("engineInstances", 1);
136+
testMap.put("loadTestConfig", loadTestConfigMap);
137+
138+
// environmentVariables are plain-text data passed to test engines
139+
Map<String, Object> envVarMap = new HashMap<String, Object>();
140+
envVarMap.put("a", "b");
141+
envVarMap.put("x", "y");
142+
testMap.put("environmentVariables", envVarMap);
143+
144+
// secrets are secure data sent using Azure Key Vault
145+
Map<String, Object> secretMap = new HashMap<String, Object>();
146+
Map<String, Object> sampleSecretMap = new HashMap<String, Object>();
147+
sampleSecretMap.put("value", "https://samplevault.vault.azure.net/secrets/samplesecret/f113f91fd4c44a368049849c164db827");
148+
sampleSecretMap.put("type", "AKV_SECRET_URI");
149+
secretMap.put("sampleSecret", sampleSecretMap);
150+
testMap.put("secrets", secretMap);
151+
152+
// passFailCriteria define the conditions to conclude the test as success
153+
Map<String, Object> passFailMap = new HashMap<String, Object>();
154+
Map<String, Object> passFailMetrics = new HashMap<String, Object>();
155+
Map<String, Object> samplePassFailMetric = new HashMap<String, Object>();
156+
samplePassFailMetric.put("clientmetric", "response_time_ms");
157+
samplePassFailMetric.put("aggregate", "percentage");
158+
samplePassFailMetric.put("condition", ">");
159+
samplePassFailMetric.put("value", "20");
160+
samplePassFailMetric.put("action", "continue");
161+
passFailMetrics.put("fefd759d-7fe8-4f83-8b6d-aeebe0f491fe", samplePassFailMetric);
162+
passFailMap.put("passFailMetrics", passFailMetrics);
163+
testMap.put("passFailCriteria", passFailMap);
164+
165+
// convert the object Map to JSON BinaryData
166+
BinaryData test = BinaryData.fromObject(testMap);
167+
168+
// receive response with BinaryData content
169+
Response<BinaryData> testOutResponse = client.getLoadTestAdministrationClient().createOrUpdateTestWithResponse("test12345", test, null);
170+
System.out.println(testOutResponse.getValue().toString());
171+
```
172+
173+
### Uploading .jmx file to a Load Test
174+
175+
```java java-readme-sample-uploadTestFile
176+
LoadTestingClient client = new LoadTestingClientBuilder()
177+
.credential(new DefaultAzureCredentialBuilder().build())
178+
.endpoint("<endpoint>")
179+
.buildClient();
180+
181+
// extract file contents to BinaryData
182+
BinaryData fileData = BinaryData.fromFile(new File("path/to/file").toPath());
183+
184+
// receive response with BinaryData content
185+
Response<BinaryData> fileUrlOut = client.getLoadTestAdministrationClient().uploadTestFileWithResponse("test12345", "file12345", "sample-file.jmx", fileData, null);
186+
System.out.println(fileUrlOut.getValue().toString());
187+
```
188+
189+
### Running a Load Test
190+
191+
```java java-readme-sample-runTest
192+
LoadTestingClient client = new LoadTestingClientBuilder()
193+
.credential(new DefaultAzureCredentialBuilder().build())
194+
.endpoint("<endpoint>")
195+
.buildClient();
196+
197+
// construct Test Run object using nested String:Object Maps
198+
Map<String, Object> testRunMap = new HashMap<String, Object>();
199+
testRunMap.put("testId", "test12345");
200+
testRunMap.put("displayName", "SDK-Created-TestRun");
201+
202+
// convert the object Map to JSON BinaryData
203+
BinaryData testRun = BinaryData.fromObject(testRunMap);
204+
205+
// receive response with BinaryData content
206+
Response<BinaryData> testRunOut = client.getLoadTestRunClient().createOrUpdateTestRunWithResponse("testrun12345", testRun, null);
207+
System.out.println(testRunOut.getValue().toString());
208+
209+
// wait for test to reach terminal state
210+
JsonNode testRunJson = null;
211+
String testStatus = null, startDateTime = null, endDateTime = null;
212+
while (testStatus == null || (testStatus != "DONE" && testStatus != "CANCELLED" && testStatus != "FAILED")) {
213+
testRunOut = client.getLoadTestRunClient().getTestRunWithResponse("testrun12345", null);
214+
// parse JSON and read status value
215+
try {
216+
testRunJson = new ObjectMapper().readTree(testRunOut.getValue().toString());
217+
testStatus = testRunJson.get("status").asText();
218+
} catch (JsonProcessingException e) {
219+
System.out.println("Error processing JSON response");
220+
// handle error condition
221+
}
222+
223+
// wait and check test status every 5 seconds
224+
try {
225+
Thread.sleep(5000);
226+
} catch (InterruptedException e) {
227+
// handle interruption
228+
}
229+
}
230+
231+
startDateTime = testRunJson.get("startDateTime").asText();
232+
endDateTime = testRunJson.get("endDateTime").asText();
233+
234+
// construct Test Run Client Metrics object using nested String:Object Maps
235+
Map<String, Object> clientMetricsMap = new HashMap<String, Object>();
236+
List<String> requestSamplersList = new ArrayList<String>();
237+
requestSamplersList.add("Homepage");
238+
clientMetricsMap.put("requestSamplers", requestSamplersList);
239+
240+
List<String> errorsList = new ArrayList<String>();
241+
errorsList.add("500");
242+
clientMetricsMap.put("errors", errorsList);
243+
244+
List<String> percentilesList = new ArrayList<String>();
245+
percentilesList.add("95");
246+
clientMetricsMap.put("percentiles", percentilesList);
247+
248+
clientMetricsMap.put("groupByInterval", "10s");
249+
clientMetricsMap.put("startTime", startDateTime);
250+
clientMetricsMap.put("endTime", endDateTime);
251+
252+
// convert the object Map to JSON BinaryData
253+
BinaryData clientMetrics = BinaryData.fromObject(clientMetricsMap);
254+
255+
// fetch client metrics
256+
Response<BinaryData> clientMetricsOut = client.getLoadTestRunClient().getTestRunClientMetricsWithResponse("testrun12345", clientMetrics, null);
257+
System.out.println(clientMetricsOut.getValue().toString());
258+
```
259+
260+
## Troubleshooting
261+
262+
Azure SDKs for Java offer a consistent logging story to help aid in troubleshooting application errors and expedite
263+
their resolution. The logs produced will capture the flow of an application before reaching the terminal state to help
264+
locate the root issue. View the [logging][logging] wiki for guidance about enabling logging.
265+
266+
## Next steps
267+
268+
Azure Loading Testing Java SDK samples are available to you in the SDK's GitHub repository. These samples provide example code for additional scenarios commonly encountered.
269+
<!-- See [Azure Load Testing samples][sample_code]. -->
270+
271+
## Contributing
272+
273+
For details on contributing to this repository, see the [contributing guide](https://github.com/Azure/azure-sdk-for-java/blob/main/CONTRIBUTING.md).
274+
275+
1. Fork it
276+
1. Create your feature branch (`git checkout -b my-new-feature`)
277+
1. Commit your changes (`git commit -am 'Add some feature'`)
278+
1. Push to the branch (`git push origin my-new-feature`)
279+
1. Create new Pull Request
280+
281+
<!-- LINKS -->
282+
<!-- [source_code]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/loadtesting/azure-developer-loadtesting/src -->
283+
<!-- [sample_code]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/loadtesting/azure-developer-loadtesting/src/samples -->
284+
[api_reference_doc]: https://docs.microsoft.com/rest/api/loadtesting/
285+
[product_documentation]: https://azure.microsoft.com/services/load-testing/
286+
[jdk]: https://docs.microsoft.com/java/azure/jdk/
287+
[azure_subscription]: https://azure.microsoft.com/free/
288+
[azure_identity]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/identity/azure-identity
289+
[logging]: https://github.com/Azure/azure-sdk-for-java/wiki/Logging-in-Azure-SDK
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2+
<modelVersion>4.0.0</modelVersion>
3+
<parent>
4+
<groupId>com.azure</groupId>
5+
<artifactId>azure-client-sdk-parent</artifactId>
6+
<version>1.7.0</version> <!-- {x-version-update;com.azure:azure-client-sdk-parent;current} -->
7+
<relativePath>../../parents/azure-client-sdk-parent</relativePath>
8+
</parent>
9+
10+
<groupId>com.azure</groupId>
11+
<artifactId>azure-developer-loadtesting</artifactId>
12+
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-developer-loadtesting;current} -->
13+
<packaging>jar</packaging>
14+
15+
<name>Microsoft Azure SDK for LoadTestingClient Management</name>
16+
<description>This package contains Microsoft Azure LoadTestingClient client library.</description>
17+
<url>https://github.com/Azure/azure-sdk-for-java</url>
18+
19+
<licenses>
20+
<license>
21+
<name>The MIT License (MIT)</name>
22+
<url>http://opensource.org/licenses/MIT</url>
23+
<distribution>repo</distribution>
24+
</license>
25+
</licenses>
26+
27+
<scm>
28+
<url>https://github.com/Azure/azure-sdk-for-java</url>
29+
<connection>scm:git:git@github.com:Azure/azure-sdk-for-java.git</connection>
30+
<developerConnection>scm:git:git@github.com:Azure/azure-sdk-for-java.git</developerConnection>
31+
<tag>HEAD</tag>
32+
</scm>
33+
<developers>
34+
<developer>
35+
<id>microsoft</id>
36+
<name>Microsoft</name>
37+
</developer>
38+
</developers>
39+
<properties>
40+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
41+
<jacoco.skip>true</jacoco.skip>
42+
</properties>
43+
<dependencies>
44+
<dependency>
45+
<groupId>com.azure</groupId>
46+
<artifactId>azure-core</artifactId>
47+
<version>1.33.0</version> <!-- {x-version-update;com.azure:azure-core;dependency} -->
48+
</dependency>
49+
<dependency>
50+
<groupId>com.azure</groupId>
51+
<artifactId>azure-core-http-netty</artifactId>
52+
<version>1.12.6</version> <!-- {x-version-update;com.azure:azure-core-http-netty;dependency} -->
53+
</dependency>
54+
<dependency>
55+
<groupId>org.junit.jupiter</groupId>
56+
<artifactId>junit-jupiter-engine</artifactId>
57+
<version>5.8.2</version> <!-- {x-version-update;org.junit.jupiter:junit-jupiter-engine;external_dependency} -->
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.mockito</groupId>
62+
<artifactId>mockito-core</artifactId>
63+
<version>4.5.1</version> <!-- {x-version-update;org.mockito:mockito-core;external_dependency} -->
64+
<scope>test</scope>
65+
</dependency>
66+
<dependency>
67+
<groupId>com.azure</groupId>
68+
<artifactId>azure-core-test</artifactId>
69+
<version>1.12.1</version> <!-- {x-version-update;com.azure:azure-core-test;dependency} -->
70+
<scope>test</scope>
71+
</dependency>
72+
<dependency>
73+
<groupId>com.azure</groupId>
74+
<artifactId>azure-identity</artifactId>
75+
<version>1.6.1</version> <!-- {x-version-update;com.azure:azure-identity;dependency} -->
76+
<scope>test</scope>
77+
</dependency>
78+
</dependencies>
79+
</project>

0 commit comments

Comments
 (0)