Skip to content

Commit 659efc4

Browse files
test(starknet_sequencer_metrics): add testing utilities to the metrics
1 parent ff807ed commit 659efc4

File tree

5 files changed

+138
-79
lines changed

5 files changed

+138
-79
lines changed

crates/starknet_mempool/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ rstest.workspace = true
4343
starknet-types-core.workspace = true
4444
starknet_api = { workspace = true, features = ["testing"] }
4545
starknet_mempool_p2p_types = { workspace = true, features = ["testing"] }
46+
starknet_sequencer_metrics = { workspace = true, features = ["testing"] }
4647

4748
[package.metadata.cargo-machete]
4849
ignored = ["starknet-types-core"]

crates/starknet_mempool/src/test_utils.rs

Lines changed: 20 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -107,50 +107,6 @@ macro_rules! tx {
107107
};
108108
}
109109

110-
// TODO(Yael): Consider moving to a more general place.
111-
/// Compares a metric, by it's name and label if exists, from a metrics str with an expected value
112-
/// and asserts if false.
113-
#[macro_export]
114-
macro_rules! assert_metric_eq {
115-
($metrics:expr, $expected:expr, $metric:ident $(, $labels:expr)?) => {
116-
let return_value = $metric.parse_numeric_metric::<u64>($metrics $(, $labels)?).unwrap();
117-
assert_eq!(
118-
return_value,
119-
$expected,
120-
"Metric {} did not match expected value. expected value: {}, returned value: {}",
121-
stringify!($metric $(, $labels)?), $expected, return_value
122-
123-
);
124-
};
125-
}
126-
127-
/// Compares a histogram metric value to the expected value. Only the sum and count values are
128-
/// compared, not the quantiles.
129-
#[macro_export]
130-
macro_rules! assert_metric_histogram_eq {
131-
($metrics:expr, $expected:expr, $metric:ident) => {
132-
let return_value = $metric.parse_histogram_metric($metrics).unwrap();
133-
assert_eq!(
134-
return_value.sum,
135-
$expected.sum,
136-
"Histogram {} sum did not match expected value. expected value: {:?}, returned value: \
137-
{:?}",
138-
stringify!($metric),
139-
$expected.sum,
140-
return_value.sum
141-
);
142-
assert_eq!(
143-
return_value.count,
144-
$expected.count,
145-
"Histogram {} count did not match expected value. expected value: {:?}, returned \
146-
value: {:?}",
147-
stringify!($metric),
148-
$expected.count,
149-
return_value.count
150-
);
151-
};
152-
}
153-
154110
/// Creates an input for `add_tx` with the given field subset (the rest receive default values).
155111
#[macro_export]
156112
macro_rules! add_tx_input {
@@ -367,57 +323,43 @@ pub struct MempoolMetrics {
367323
impl MempoolMetrics {
368324
pub fn verify_metrics(&self, recorder: &PrometheusRecorder) {
369325
let metrics = &recorder.handle().render();
370-
assert_metric_eq!(
326+
MEMPOOL_TRANSACTIONS_RECEIVED.assert_eq(
371327
metrics,
372328
self.txs_received_invoke,
373-
MEMPOOL_TRANSACTIONS_RECEIVED,
374-
&[(LABEL_NAME_TX_TYPE, RpcTransactionLabelValue::Invoke.into())]
329+
&[(LABEL_NAME_TX_TYPE, RpcTransactionLabelValue::Invoke.into())],
375330
);
376-
assert_metric_eq!(
331+
MEMPOOL_TRANSACTIONS_RECEIVED.assert_eq(
377332
metrics,
378333
self.txs_received_declare,
379-
MEMPOOL_TRANSACTIONS_RECEIVED,
380-
&[(LABEL_NAME_TX_TYPE, RpcTransactionLabelValue::Declare.into())]
334+
&[(LABEL_NAME_TX_TYPE, RpcTransactionLabelValue::Declare.into())],
381335
);
382-
assert_metric_eq!(
336+
MEMPOOL_TRANSACTIONS_RECEIVED.assert_eq(
383337
metrics,
384338
self.txs_received_deploy_account,
385-
MEMPOOL_TRANSACTIONS_RECEIVED,
386-
&[(LABEL_NAME_TX_TYPE, RpcTransactionLabelValue::DeployAccount.into())]
339+
&[(LABEL_NAME_TX_TYPE, RpcTransactionLabelValue::DeployAccount.into())],
387340
);
388-
389-
assert_metric_eq!(metrics, self.txs_committed, MEMPOOL_TRANSACTIONS_COMMITTED);
390-
391-
assert_metric_eq!(
341+
MEMPOOL_TRANSACTIONS_COMMITTED.assert_eq(metrics, self.txs_committed);
342+
MEMPOOL_TRANSACTIONS_DROPPED.assert_eq(
392343
metrics,
393344
self.txs_dropped_expired,
394-
MEMPOOL_TRANSACTIONS_DROPPED,
395-
&[(LABEL_NAME_DROP_REASON, DropReason::Expired.into())]
345+
&[(LABEL_NAME_DROP_REASON, DropReason::Expired.into())],
396346
);
397-
398-
assert_metric_eq!(
347+
MEMPOOL_TRANSACTIONS_DROPPED.assert_eq(
399348
metrics,
400349
self.txs_dropped_failed_add_tx_checks,
401-
MEMPOOL_TRANSACTIONS_DROPPED,
402-
&[(LABEL_NAME_DROP_REASON, DropReason::FailedAddTxChecks.into())]
350+
&[(LABEL_NAME_DROP_REASON, DropReason::FailedAddTxChecks.into())],
403351
);
404-
405-
assert_metric_eq!(
352+
MEMPOOL_TRANSACTIONS_DROPPED.assert_eq(
406353
metrics,
407354
self.txs_dropped_rejected,
408-
MEMPOOL_TRANSACTIONS_DROPPED,
409-
&[(LABEL_NAME_DROP_REASON, DropReason::Rejected.into())]
410-
);
411-
412-
assert_metric_eq!(metrics, self.pool_size, MEMPOOL_POOL_SIZE);
413-
assert_metric_eq!(metrics, self.priority_queue_size, MEMPOOL_PRIORITY_QUEUE_SIZE);
414-
assert_metric_eq!(metrics, self.pending_queue_size, MEMPOOL_PENDING_QUEUE_SIZE);
415-
assert_metric_eq!(metrics, self.get_txs_size, MEMPOOL_GET_TXS_SIZE);
416-
assert_metric_eq!(metrics, self.delayed_declares_size, MEMPOOL_DELAYED_DECLARES_SIZE);
417-
assert_metric_histogram_eq!(
418-
metrics,
419-
self.transaction_time_spent_in_mempool,
420-
TRANSACTION_TIME_SPENT_IN_MEMPOOL
355+
&[(LABEL_NAME_DROP_REASON, DropReason::Rejected.into())],
421356
);
357+
MEMPOOL_POOL_SIZE.assert_eq(metrics, self.pool_size);
358+
MEMPOOL_PRIORITY_QUEUE_SIZE.assert_eq(metrics, self.priority_queue_size);
359+
MEMPOOL_PENDING_QUEUE_SIZE.assert_eq(metrics, self.pending_queue_size);
360+
MEMPOOL_GET_TXS_SIZE.assert_eq(metrics, self.get_txs_size);
361+
MEMPOOL_DELAYED_DECLARES_SIZE.assert_eq(metrics, self.delayed_declares_size);
362+
TRANSACTION_TIME_SPENT_IN_MEMPOOL
363+
.assert_eq(metrics, &self.transaction_time_spent_in_mempool);
422364
}
423365
}

crates/starknet_sequencer_infra/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ once_cell.workspace = true
3737
pretty_assertions.workspace = true
3838
starknet-types-core.workspace = true
3939
starknet_infra_utils = { workspace = true, features = ["testing"] }
40+
starknet_sequencer_metrics = { workspace = true, features = ["testing"] }

crates/starknet_sequencer_infra/src/metrics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl LocalServerMetrics {
8585
self.received_msgs.increment(1);
8686
}
8787

88+
#[cfg(any(feature = "testing", test))]
8889
pub fn get_received_value(&self, metrics_as_string: &str) -> u64 {
8990
self.received_msgs
9091
.parse_numeric_metric::<u64>(metrics_as_string)
@@ -95,6 +96,7 @@ impl LocalServerMetrics {
9596
self.processed_msgs.increment(1);
9697
}
9798

99+
#[cfg(any(feature = "testing", test))]
98100
pub fn get_processed_value(&self, metrics_as_string: &str) -> u64 {
99101
self.processed_msgs
100102
.parse_numeric_metric::<u64>(metrics_as_string)
@@ -105,6 +107,7 @@ impl LocalServerMetrics {
105107
self.queue_depth.set_lossy(value);
106108
}
107109

110+
#[cfg(any(feature = "testing", test))]
108111
pub fn get_queue_depth_value(&self, metrics_as_string: &str) -> usize {
109112
self.queue_depth
110113
.parse_numeric_metric::<usize>(metrics_as_string)
@@ -138,6 +141,7 @@ impl RemoteServerMetrics {
138141
self.total_received_msgs.increment(1);
139142
}
140143

144+
#[cfg(any(feature = "testing", test))]
141145
pub fn get_total_received_value(&self, metrics_as_string: &str) -> u64 {
142146
self.total_received_msgs
143147
.parse_numeric_metric::<u64>(metrics_as_string)
@@ -148,6 +152,7 @@ impl RemoteServerMetrics {
148152
self.valid_received_msgs.increment(1);
149153
}
150154

155+
#[cfg(any(feature = "testing", test))]
151156
pub fn get_valid_received_value(&self, metrics_as_string: &str) -> u64 {
152157
self.valid_received_msgs
153158
.parse_numeric_metric::<u64>(metrics_as_string)
@@ -158,6 +163,7 @@ impl RemoteServerMetrics {
158163
self.processed_msgs.increment(1);
159164
}
160165

166+
#[cfg(any(feature = "testing", test))]
161167
pub fn get_processed_value(&self, metrics_as_string: &str) -> u64 {
162168
self.processed_msgs
163169
.parse_numeric_metric::<u64>(metrics_as_string)

crates/starknet_sequencer_metrics/src/metrics.rs

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(test)]
22
#[path = "metrics_test.rs"]
33
mod metrics_tests;
4-
4+
use std::fmt::Debug;
55
use std::str::FromStr;
66

77
use indexmap::IndexMap;
@@ -70,9 +70,24 @@ impl MetricCounter {
7070
counter!(self.name).increment(value);
7171
}
7272

73+
#[cfg(any(feature = "testing", test))]
7374
pub fn parse_numeric_metric<T: Num + FromStr>(&self, metrics_as_string: &str) -> Option<T> {
7475
parse_numeric_metric::<T>(metrics_as_string, self.get_name(), None)
7576
}
77+
78+
#[cfg(any(feature = "testing", test))]
79+
pub fn assert_eq<T: Num + FromStr + Debug>(&self, metrics_as_string: &str, expected_value: T) {
80+
let metric_value = self.parse_numeric_metric::<T>(metrics_as_string).unwrap();
81+
assert_eq!(
82+
metric_value,
83+
expected_value,
84+
"Metric counter {} did not match the expected value. expected value: {:?}, metric \
85+
value: {:?}",
86+
self.get_name(),
87+
expected_value,
88+
metric_value
89+
);
90+
}
7691
}
7792

7893
pub struct LabeledMetricCounter {
@@ -117,13 +132,34 @@ impl LabeledMetricCounter {
117132
counter!(self.name, labels).increment(value);
118133
}
119134

135+
#[cfg(any(feature = "testing", test))]
120136
pub fn parse_numeric_metric<T: Num + FromStr>(
121137
&self,
122138
metrics_as_string: &str,
123139
labels: &[(&'static str, &'static str)],
124140
) -> Option<T> {
125141
parse_numeric_metric::<T>(metrics_as_string, self.get_name(), Some(labels))
126142
}
143+
144+
#[cfg(any(feature = "testing", test))]
145+
pub fn assert_eq<T: Num + FromStr + Debug>(
146+
&self,
147+
metrics_as_string: &str,
148+
expected_value: T,
149+
label: &[(&'static str, &'static str)],
150+
) {
151+
let metric_value = self.parse_numeric_metric::<T>(metrics_as_string, label).unwrap();
152+
assert_eq!(
153+
metric_value,
154+
expected_value,
155+
"Metric counter {} {:?} did not match the expected value. expected value: {:?}, metric
156+
value: {:?}",
157+
self.get_name(),
158+
label,
159+
expected_value,
160+
metric_value
161+
);
162+
}
127163
}
128164

129165
pub struct MetricGauge {
@@ -162,6 +198,7 @@ impl MetricGauge {
162198
gauge!(self.name).decrement(value.into_f64());
163199
}
164200

201+
#[cfg(any(feature = "testing", test))]
165202
pub fn parse_numeric_metric<T: Num + FromStr>(&self, metrics_as_string: &str) -> Option<T> {
166203
parse_numeric_metric::<T>(metrics_as_string, self.get_name(), None)
167204
}
@@ -173,6 +210,20 @@ impl MetricGauge {
173210
pub fn set_lossy<T: LossyIntoF64>(&self, value: T) {
174211
gauge!(self.name).set(value.into_f64());
175212
}
213+
214+
#[cfg(any(feature = "testing", test))]
215+
pub fn assert_eq<T: Num + FromStr + Debug>(&self, metrics_as_string: &str, expected_value: T) {
216+
let metric_value = self.parse_numeric_metric::<T>(metrics_as_string).unwrap();
217+
assert_eq!(
218+
metric_value,
219+
expected_value,
220+
"Metric gauge {} did not match the expected value. expected value: {:?}, metric
221+
value: {:?}",
222+
self.get_name(),
223+
expected_value,
224+
metric_value
225+
);
226+
}
176227
}
177228

178229
/// An object which can be lossy converted into a `f64` representation.
@@ -244,6 +295,7 @@ impl LabeledMetricGauge {
244295
gauge!(self.name, label).decrement(value.into_f64());
245296
}
246297

298+
#[cfg(any(feature = "testing", test))]
247299
pub fn parse_numeric_metric<T: Num + FromStr>(
248300
&self,
249301
metrics_as_string: &str,
@@ -255,6 +307,26 @@ impl LabeledMetricGauge {
255307
pub fn set<T: IntoF64>(&self, value: T, label: &[(&'static str, &'static str)]) {
256308
gauge!(self.name, label).set(value.into_f64());
257309
}
310+
311+
#[cfg(any(feature = "testing", test))]
312+
pub fn assert_eq<T: Num + FromStr + Debug>(
313+
&self,
314+
metrics_as_string: &str,
315+
expected_value: T,
316+
label: &[(&'static str, &'static str)],
317+
) {
318+
let metric_value = self.parse_numeric_metric::<T>(metrics_as_string, label).unwrap();
319+
assert_eq!(
320+
metric_value,
321+
expected_value,
322+
"Metric gauge {} {:?} did not match the expected value. expected value: {:?}, metric
323+
value: {:?}",
324+
self.get_name(),
325+
label,
326+
expected_value,
327+
metric_value
328+
);
329+
}
258330
}
259331

260332
pub struct MetricHistogram {
@@ -300,9 +372,24 @@ impl MetricHistogram {
300372
histogram!(self.name).record_many(value.into_f64(), count);
301373
}
302374

375+
#[cfg(any(feature = "testing", test))]
303376
pub fn parse_histogram_metric(&self, metrics_as_string: &str) -> Option<HistogramValue> {
304377
parse_histogram_metric(metrics_as_string, self.get_name(), None)
305378
}
379+
380+
// Only the sum and count values are compared, not the quantiles.
381+
#[cfg(any(feature = "testing", test))]
382+
pub fn assert_eq(&self, metrics_as_string: &str, expected_value: &HistogramValue) {
383+
let metric_value = self.parse_histogram_metric(metrics_as_string).unwrap();
384+
assert!(
385+
metric_value.sum == expected_value.sum && metric_value.count == expected_value.count,
386+
"Metric histogram {} sum or count did not match the expected value. expected value: \
387+
{:?}, metric value: {:?}",
388+
self.get_name(),
389+
expected_value,
390+
metric_value
391+
);
392+
}
306393
}
307394

308395
pub struct LabeledMetricHistogram {
@@ -354,13 +441,35 @@ impl LabeledMetricHistogram {
354441
histogram!(self.name, labels).record_many(value.into_f64(), count);
355442
}
356443

444+
#[cfg(any(feature = "testing", test))]
357445
pub fn parse_histogram_metric(
358446
&self,
359447
metrics_as_string: &str,
360448
labels: &[(&'static str, &'static str)],
361449
) -> Option<HistogramValue> {
362450
parse_histogram_metric(metrics_as_string, self.get_name(), Some(labels))
363451
}
452+
453+
// Only the sum and count values are compared, not the quantiles.
454+
#[cfg(any(feature = "testing", test))]
455+
// TODO(tsabary): unite the labeled and unlabeld assert_eq functions.
456+
pub fn assert_eq(
457+
&self,
458+
metrics_as_string: &str,
459+
expected_value: &HistogramValue,
460+
label: &[(&'static str, &'static str)],
461+
) {
462+
let metric_value = self.parse_histogram_metric(metrics_as_string, label).unwrap();
463+
assert!(
464+
metric_value.sum == expected_value.sum && metric_value.count == expected_value.count,
465+
"Metric histogram {} {:?} sum or count did not match the expected value. expected \
466+
value: {:?}, metric value: {:?}",
467+
self.get_name(),
468+
label,
469+
expected_value,
470+
metric_value
471+
);
472+
}
364473
}
365474

366475
/// Parses a specific numeric metric value from a metrics string.

0 commit comments

Comments
 (0)