Skip to content

Commit 1495413

Browse files
First cut at EH perf tests (#2602)
* First cut at EH perf tests * Skip EH benchmarks if we're not running live tests
1 parent fb547ae commit 1495413

File tree

5 files changed

+197
-0
lines changed

5 files changed

+197
-0
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/eventhubs/azure_messaging_eventhubs/Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ azure_identity.workspace = true
3939
azure_messaging_eventhubs = { path = ".", features = [
4040
"test",
4141
] }
42+
criterion.workspace = true
4243
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
4344
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
4445

4546
[features]
4647
test = []
4748
blob_checkpoint_store = []
4849

50+
[[bench]]
51+
name = "benchmarks"
52+
harness = false
53+
4954
[lints]
5055
workspace = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
use azure_identity::DefaultAzureCredential;
5+
use azure_messaging_eventhubs::{models::EventData, ProducerClient, SendEventOptions};
6+
use criterion::{criterion_group, criterion_main, Criterion};
7+
use std::{env, sync::Arc};
8+
use tokio::runtime::Runtime;
9+
10+
//static INIT_LOGGING: std::sync::Once = std::sync::Once::new();
11+
12+
fn setup() {
13+
// INIT_LOGGING.call_once(|| {
14+
// println!("Setting up test logger...");
15+
16+
// use tracing_subscriber::{fmt::format::FmtSpan, EnvFilter};
17+
// tracing_subscriber::fmt()
18+
// .with_env_filter(EnvFilter::from_default_env())
19+
// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
20+
// .with_ansi(std::env::var("NO_COLOR").map_or(true, |v| v.is_empty()))
21+
// .with_writer(std::io::stderr)
22+
// .init();
23+
// });
24+
}
25+
26+
fn send_batch_benchmark(c: &mut Criterion) {
27+
setup();
28+
29+
// Check if the environment variable is set thus allowing the benchmarks to run
30+
if azure_core_test::TestMode::current().unwrap() != azure_core_test::TestMode::Live {
31+
println!("Skipping benchmarks. Set AZURE_TEST_MODE to run.");
32+
return;
33+
}
34+
35+
let rt = Runtime::new().unwrap();
36+
37+
let namespace = env::var("EVENTHUBS_HOST")
38+
.expect("Set EVENTHUBS_HOST in env (e.g. my-namespace.servicebus.windows.net)");
39+
let event_hub = env::var("EVENTHUB_NAME").expect("Set EVENTHUB_NAME in env");
40+
41+
let credential =
42+
DefaultAzureCredential::new().expect("Failed to create DefaultAzureCredential");
43+
44+
let client = rt.block_on(async move {
45+
Arc::new(
46+
ProducerClient::builder()
47+
.open(namespace.as_str(), event_hub.as_str(), credential)
48+
.await
49+
.expect("Failed to create ProducerClient"),
50+
)
51+
});
52+
53+
let num_events = 1000;
54+
let payload = b"perf-test-payload";
55+
56+
let client = client.clone();
57+
c.bench_function("eventhubs_send_batch", |b| {
58+
let client = client.clone();
59+
b.to_async(&rt).iter(move || {
60+
let client = client.clone();
61+
async move {
62+
let batch = client.create_batch(None).await.unwrap();
63+
for _ in 0..num_events {
64+
batch
65+
.try_add_event_data(EventData::from(payload.as_ref()), None)
66+
.unwrap();
67+
}
68+
let _ = client.send_batch(&batch, None).await;
69+
}
70+
});
71+
});
72+
}
73+
74+
criterion_group!(
75+
name = send_batch_benchmarks;
76+
config = Criterion::default().sample_size(100).warm_up_time(std::time::Duration::new(1, 0));
77+
targets = send_batch_benchmark
78+
);
79+
80+
fn send_benchmark(c: &mut Criterion) {
81+
setup();
82+
83+
// Check if the environment variable is set thus allowing the benchmarks to run
84+
if azure_core_test::TestMode::current().unwrap() != azure_core_test::TestMode::Live {
85+
println!("Skipping benchmarks. Set AZURE_TEST_MODE to run.");
86+
return;
87+
}
88+
89+
let rt = Runtime::new().unwrap();
90+
91+
let namespace = env::var("EVENTHUBS_HOST")
92+
.expect("Set EVENTHUBS_HOST in env (e.g. my-namespace.servicebus.windows.net)");
93+
let event_hub = env::var("EVENTHUB_NAME").expect("Set EVENTHUB_NAME in env");
94+
95+
let credential =
96+
DefaultAzureCredential::new().expect("Failed to create DefaultAzureCredential");
97+
98+
let client = rt.block_on(async move {
99+
Arc::new(
100+
ProducerClient::builder()
101+
.open(namespace.as_str(), event_hub.as_str(), credential)
102+
.await
103+
.expect("Failed to create ProducerClient"),
104+
)
105+
});
106+
107+
c.bench_function("eventhubs_send", |b| {
108+
let client = client.clone();
109+
let mut index: u64 = 0;
110+
b.to_async(&rt).iter(move || {
111+
let client = client.clone();
112+
async move {
113+
index += 1;
114+
let payload = b"a";
115+
let event_data = EventData::builder()
116+
.with_body(payload)
117+
.add_property("Number".to_string(), index)
118+
.add_property("PartitionId".to_string(), "0")
119+
.build();
120+
client
121+
.send_event(
122+
event_data,
123+
Some(SendEventOptions {
124+
partition_id: Some("0".to_string()),
125+
}),
126+
)
127+
.await
128+
}
129+
});
130+
});
131+
}
132+
133+
criterion_group!(
134+
name = send_benchmarks;
135+
config = Criterion::default().sample_size(1000).warm_up_time(std::time::Duration::new(1, 0)).measurement_time(std::time::Duration::new(205, 0));
136+
targets = send_benchmark
137+
);
138+
139+
criterion_main!(send_batch_benchmarks, send_benchmarks);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Service: azure_messaging_eventhubs
2+
3+
Project: azure_messaging_eventhubs
4+
5+
PackageVersions:
6+
- azure_messaging_eventhubs: source
7+
8+
Tests:
9+
- Test: eventhubs_send_batch
10+
Class: eventhubs_send_batch
11+
Arguments:
12+
- --sync
13+
14+
- Test: eventhubs_send
15+
Class: eventhubs_send
16+
Arguments:
17+
- --sync
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
parameters:
2+
- name: PackageVersions
3+
displayName: PackageVersions (regex of package versions to run)
4+
type: string
5+
default: 'source'
6+
- name: Tests
7+
displayName: Tests (regex of tests to run)
8+
type: string
9+
default: '.*'
10+
- name: Arguments
11+
displayName: Arguments (regex of arguments to run)
12+
type: string
13+
default: '.*'
14+
- name: Iterations
15+
displayName: Iterations (times to run each test)
16+
type: number
17+
default: 1
18+
- name: Profile
19+
type: boolean
20+
default: false
21+
- name: AdditionalArguments
22+
displayName: AdditionalArguments (passed to PerfAutomation)
23+
type: string
24+
default: ''
25+
26+
extends:
27+
template: /eng/pipelines/templates/jobs/perf.yml@self
28+
parameters:
29+
ServiceDirectory: eventhubs
30+
PackageVersions: ${{ parameters.PackageVersions }}
31+
Tests: ${{ parameters.Tests }}
32+
Arguments: ${{ parameters.Arguments }}
33+
Iterations: ${{ parameters.Iterations }}
34+
AdditionalArguments: ${{ parameters.AdditionalArguments }}
35+
Profile: ${{ parameters.Profile }}

0 commit comments

Comments
 (0)