Skip to content

Commit 43c6f25

Browse files
Initial performance test infrastructure (#3110)
This PR adds the start of performance test infrastructure for the Rust SDK. This support is not complete, but it does provide a mechanism to measure the performance of SDK client operations. It also defines a performance test for the KeyVault get_secrets API and the Storage Blobs list_blobs API which match the tests which exist for the C++ SDK.
1 parent cc72614 commit 43c6f25

File tree

17 files changed

+1908
-10
lines changed

17 files changed

+1908
-10
lines changed

sdk/core/azure_core/CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939

4040
### Breaking Changes
4141

42-
4342
- Changed `ClientOptions::retry` from `Option<RetryOptions>` to `RetryOptions`.
4443
- Changed `DeserializeWith::deserialize_with()` to be sync.
4544
- Changed `Pipeline::send()` to return a `Result<RawResponse>`.

sdk/core/azure_core_test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ async-trait.workspace = true
2323
azure_core = { workspace = true, features = ["test"] }
2424
azure_core_test_macros.workspace = true
2525
azure_identity.workspace = true
26+
clap.workspace = true
2627
dotenvy = "0.15.7"
2728
futures.workspace = true
2829
rand.workspace = true

sdk/core/azure_core_test/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ pub mod credentials;
77
#[cfg(doctest)]
88
mod docs;
99
pub mod http;
10+
pub mod perf;
1011
pub mod proxy;
1112
pub mod recorded;
1213
mod recording;
1314
#[cfg(doctest)]
1415
mod root_readme;
1516
pub mod stream;
1617
pub mod tracing;
17-
1818
use azure_core::Error;
1919
pub use azure_core::{error::ErrorKind, test::TestMode};
2020
pub use proxy::{matchers::*, sanitizers::*};
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Performance Tests
2+
3+
The Azure SDK defines a standardized set of performance tests which use a test framework defined by the [PerfAutomation tool](https://github.com/Azure/azure-sdk-tools/tree/main/tools/perf-automation).
4+
5+
Performance tests are defined in a "perf" directory under the package root.
6+
7+
By convention, all performance tests are named "perf" and are invoked via:
8+
9+
```bash
10+
cargo test --package <package name> --test perf -- {perf test name} {perf test arguments}
11+
```
12+
13+
where `package name` is the name of the rust package, `perf test name` is the name of the test you want to run, and `perf test arguments` is the arguments to that test.
14+
15+
Each performance test has the following standardized parameters:
16+
17+
* `--iterations <count>` - the number of iterations to run the test for. Default: 1
18+
* `--sync` - Run only synchronous tests. (ignored)
19+
* `--parallel <count>` - the number of concurrent tasks to use when running each test. Default: 1
20+
* `--no-progress` - disable the once per second progress report.
21+
* `--duration <seconds>` - the duration of each test in seconds. Default: 30
22+
* `--warmup <seconds>` - the duration of the warmup period in seconds. Default: 5
23+
* `--test-results <file>` - the file to write test results to (Default: tests/results.json)
24+
* `--help` - show help.
25+
26+
Each test has its own set of parameters which are specific to the test.
27+
28+
## Test authoring
29+
30+
Performance tests have three phases:
31+
32+
1.. Setup - Establish any resources needed to run the test.
33+
2.. Run - Actually perform the test.
34+
3.. Cleanup - Cleanup any resources used by the test.
35+
36+
Each is defined by functions on the `PerfTest` trait.
37+
38+
### Test Metadata
39+
40+
Tests are defined by an instance of a `PerfTestMetadata` structure, which defines the name of the test, and other information about the test.
41+
42+
A perf test has a name (`get_secret`, `list_blobs`, `upload_blob`, etc), a short description, a set of test options, and a pointer to a function which returns an instance of the test.
43+
44+
Each perf test also has a set of command line options that are specific to the individual test, these are defined by a `PerfTestOptions` structure. It contains fields like help text for the option, activators
45+
46+
Here is an example of test metadata for a performance test:
47+
48+
```rust
49+
PerfTestMetadata {
50+
name: "get_secret",
51+
description: "Get a secret from Key Vault",
52+
options: vec![PerfTestOption {
53+
name: "vault_url",
54+
display_message: "The URL of the Key Vault to use in the test",
55+
mandatory: true,
56+
short_activator: 'u',
57+
long_activator: "vault-url",
58+
expected_args_len: 1,
59+
..Default::default()
60+
}],
61+
create_test: Self::create_new_test,
62+
}
63+
```
64+
65+
This defines a test named `get_secret` with a single required "vault_url" option.
66+
67+
For this test, the `create_new_test` function looks like:
68+
69+
```rust
70+
fn create_new_test(runner: PerfRunner) -> CreatePerfTestReturn {
71+
async move {
72+
let vault_url_ref: Option<&String> = runner.try_get_test_arg("vault_url")?;
73+
let vault_url = vault_url_ref
74+
.expect("vault_url argument is mandatory")
75+
.clone();
76+
Ok(Box::new(GetSecrets {
77+
vault_url,
78+
random_key_name: OnceLock::new(),
79+
client: OnceLock::new(),
80+
}) as Box<dyn PerfTest>)
81+
}
82+
.boxed()
83+
}
84+
```
85+
86+
### Test invocation
87+
88+
The final piece of code which is necessary to run the performance tests is logic to hook up the tests with a test runner.
89+
90+
```rust
91+
#[tokio::main]
92+
async fn main() -> azure_core::Result<()> {
93+
let runner = PerfRunner::new(
94+
env!("CARGO_MANIFEST_DIR"),
95+
file!(),
96+
vec![GetSecrets::test_metadata()],
97+
)?;
98+
99+
runner.run().await?;
100+
101+
Ok(())
102+
}
103+
```
104+
105+
This declares a perf test runner with a set of defined test metadata and runs the performance test. If your performance test suite has more than one performance test, then it should be added to the final parameter to the `PerfRunner::new()` function.
106+
107+
### Declaring Tests
108+
109+
The process of authoring tests starts with the cargo.toml file for your package.
110+
111+
Add the following to the `cargo.toml` file:
112+
113+
```toml
114+
[[test]]
115+
name = "perf"
116+
path = "perf/get_secret.rs"
117+
harness = false
118+
```
119+
120+
This declares a test named `perf` (which is required for the perf automation tests) located in a directory named `perf` in a module named `get_secret.rs`. It also declares the test as *not* requiring the standard test harness - that's because the test defines its own test harness.
121+
122+
After this, to invoke your perf test, you simply use:
123+
124+
```bash
125+
cargo test --package azure_storage_blob --test perf -- <performance test command line>
126+
```
127+
128+
For example,
129+
130+
```bash
131+
cargo test --package azure_storage_blob --test perf -- list_blob --help
132+
```
133+
134+
returns the help text for the `list_blob`test:
135+
136+
```text
137+
List blobs in a container
138+
139+
Usage: perf-070114707c71388a.exe list_blob [OPTIONS] --count <count>
140+
141+
Options:
142+
-c, --count <count> The number of blobs to list
143+
-e, --endpoint <endpoint> The endpoint of the blob storage
144+
--sync
145+
--parallel <COUNT> The number of concurrent tasks to use when running each test [default: 1]
146+
--duration <SECONDS> The duration of each test in seconds [default: 30]
147+
--warmup <SECONDS> The duration of the warmup period in seconds [default: 5]
148+
--no-cleanup Disable test cleanup
149+
-h, --help Print help
150+
```
151+
152+
Note that some of these test options are not specific to the `list_blobs` test. This is to allow test options to be provided in any order in the command line.

0 commit comments

Comments
 (0)