Skip to content

Commit fbf3cdc

Browse files
committed
refactor: MetricCollection tests
1 parent 49dbdb2 commit fbf3cdc

File tree

1 file changed

+130
-125
lines changed

1 file changed

+130
-125
lines changed

packages/metrics/src/metric_collection.rs

Lines changed: 130 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,129 @@ mod tests {
240240
use crate::label::{LabelName, LabelValue};
241241
use crate::sample::Sample;
242242

243+
/// It removes leading and trailing whitespace from each line, and empty lines.
244+
fn format_prometheus_output(output: &str) -> String {
245+
output
246+
.lines()
247+
.map(str::trim)
248+
.filter(|line| !line.is_empty())
249+
.collect::<Vec<_>>()
250+
.join("\n")
251+
}
252+
253+
/// Fixture for testing serialization and deserialization of `MetricCollection`.
254+
///
255+
/// It contains a default `MetricCollection` object, its JSON representation,
256+
/// and its Prometheus format representation.
257+
struct MetricCollectionFixture {
258+
pub object: MetricCollection,
259+
pub json: String,
260+
pub prometheus: String,
261+
}
262+
263+
impl Default for MetricCollectionFixture {
264+
fn default() -> Self {
265+
Self {
266+
object: Self::object(),
267+
json: Self::json(),
268+
prometheus: Self::prometheus(),
269+
}
270+
}
271+
}
272+
273+
impl MetricCollectionFixture {
274+
fn deconstruct(&self) -> (MetricCollection, String, String) {
275+
(self.object.clone(), self.json.clone(), self.prometheus.clone())
276+
}
277+
278+
fn object() -> MetricCollection {
279+
let time = DurationSinceUnixEpoch::from_secs(1_743_552_000);
280+
281+
let label_set: LabelSet = [
282+
(LabelName::new("ip_version"), LabelValue::new("ipv4")),
283+
(LabelName::new("protocol"), LabelValue::new("https")),
284+
(LabelName::new("url"), LabelValue::new("https://0.0.0.0:7070")),
285+
]
286+
.into();
287+
288+
MetricCollection::new(
289+
MetricKindCollection::new(vec![Metric::new(
290+
MetricName::new("announce_requests_received_total"),
291+
SampleCollection::new(vec![Sample::new(Counter::new(1), time, label_set.clone())]),
292+
)]),
293+
MetricKindCollection::new(vec![Metric::new(
294+
MetricName::new("udp_avg_connect_processing_time_ns"),
295+
SampleCollection::new(vec![Sample::new(Gauge::new(1.0), time, label_set.clone())]),
296+
)]),
297+
)
298+
}
299+
300+
fn json() -> String {
301+
r#"
302+
[
303+
{
304+
"kind": "counter",
305+
"name": "announce_requests_received_total",
306+
"samples": [
307+
{
308+
"value": 1,
309+
"update_at": "2025-04-02T00:00:00+00:00",
310+
"labels": [
311+
{
312+
"name": "ip_version",
313+
"value": "ipv4"
314+
},
315+
{
316+
"name": "protocol",
317+
"value": "https"
318+
},
319+
{
320+
"name": "url",
321+
"value": "https://0.0.0.0:7070"
322+
}
323+
]
324+
}
325+
]
326+
},
327+
{
328+
"kind": "gauge",
329+
"name": "udp_avg_connect_processing_time_ns",
330+
"samples": [
331+
{
332+
"value": 1.0,
333+
"update_at": "2025-04-02T00:00:00+00:00",
334+
"labels": [
335+
{
336+
"name": "ip_version",
337+
"value": "ipv4"
338+
},
339+
{
340+
"name": "protocol",
341+
"value": "https"
342+
},
343+
{
344+
"name": "url",
345+
"value": "https://0.0.0.0:7070"
346+
}
347+
]
348+
}
349+
]
350+
}
351+
]
352+
"#
353+
.to_owned()
354+
}
355+
356+
fn prometheus() -> String {
357+
format_prometheus_output(
358+
r#"
359+
announce_requests_received_total{ip_version="ipv4",protocol="https",url="https://0.0.0.0:7070"} 1
360+
udp_avg_connect_processing_time_ns{ip_version="ipv4",protocol="https",url="https://0.0.0.0:7070"} 1
361+
"#,
362+
)
363+
}
364+
}
365+
243366
#[test]
244367
fn it_should_increase_a_preexistent_counter() {
245368
let time = DurationSinceUnixEpoch::from_secs(1_743_552_000);
@@ -346,150 +469,32 @@ mod tests {
346469

347470
#[test]
348471
fn it_should_allow_serializing_to_json() {
349-
let time = DurationSinceUnixEpoch::from_secs(1_743_552_000);
350-
let label_set: LabelSet = [
351-
(LabelName::new("ip_version"), LabelValue::new("ipv4")),
352-
(LabelName::new("protocol"), LabelValue::new("https")),
353-
(LabelName::new("url"), LabelValue::new("https://0.0.0.0:7070")),
354-
]
355-
.into();
356-
357-
let metric_collection = MetricCollection::new(
358-
MetricKindCollection::new(vec![Metric::new(
359-
MetricName::new("announce_requests_received_total"),
360-
SampleCollection::new(vec![Sample::new(Counter::new(1), time, label_set.clone())]),
361-
)]),
362-
MetricKindCollection::new(vec![]),
363-
);
472+
let (metric_collection, expected_json, _expected_prometheus) = MetricCollectionFixture::default().deconstruct();
364473

365474
let json = serde_json::to_string_pretty(&metric_collection).unwrap();
366475

367-
let expected_json = r#"
368-
[
369-
{
370-
"kind": "counter",
371-
"name": "announce_requests_received_total",
372-
"samples": [
373-
{
374-
"value": 1,
375-
"update_at": "2025-04-02T00:00:00+00:00",
376-
"labels": [
377-
{
378-
"name": "ip_version",
379-
"value": "ipv4"
380-
},
381-
{
382-
"name": "protocol",
383-
"value": "https"
384-
},
385-
{
386-
"name": "url",
387-
"value": "https://0.0.0.0:7070"
388-
}
389-
]
390-
}
391-
]
392-
}
393-
]
394-
"#;
395-
396476
assert_eq!(
397477
serde_json::from_str::<serde_json::Value>(&json).unwrap(),
398-
serde_json::from_str::<serde_json::Value>(expected_json).unwrap()
478+
serde_json::from_str::<serde_json::Value>(&expected_json).unwrap()
399479
);
400480
}
401481

402482
#[test]
403483
fn it_should_allow_deserializing_from_json() {
404-
let json = r#"
405-
[
406-
{
407-
"kind": "counter",
408-
"name": "announce_requests_received_total",
409-
"samples": [
410-
{
411-
"value": 1,
412-
"update_at": "2025-04-02T00:00:00+00:00",
413-
"labels": [
414-
{
415-
"name": "ip_version",
416-
"value": "ipv4"
417-
},
418-
{
419-
"name": "protocol",
420-
"value": "https"
421-
},
422-
{
423-
"name": "url",
424-
"value": "https://0.0.0.0:7070"
425-
}
426-
]
427-
}
428-
]
429-
}
430-
]
431-
"#;
432-
433-
let metric_collection: MetricCollection = serde_json::from_str(json).unwrap();
434-
435-
let time = DurationSinceUnixEpoch::from_secs(1_743_552_000);
436-
437-
let label_set: LabelSet = [
438-
(LabelName::new("ip_version"), LabelValue::new("ipv4")),
439-
(LabelName::new("protocol"), LabelValue::new("https")),
440-
(LabelName::new("url"), LabelValue::new("https://0.0.0.0:7070")),
441-
]
442-
.into();
484+
let (expected_metric_collection, metric_collection_json, _expected_prometheus) =
485+
MetricCollectionFixture::default().deconstruct();
443486

444-
let expected_metric_collection = MetricCollection::new(
445-
MetricKindCollection::new(vec![Metric::new(
446-
MetricName::new("announce_requests_received_total"),
447-
SampleCollection::new(vec![Sample::new(Counter::new(1), time, label_set.clone())]),
448-
)]),
449-
MetricKindCollection::new(vec![]),
450-
);
487+
let metric_collection: MetricCollection = serde_json::from_str(&metric_collection_json).unwrap();
451488

452489
assert_eq!(metric_collection, expected_metric_collection);
453490
}
454491

455492
#[test]
456493
fn it_should_allow_serializing_to_prometheus_format() {
457-
let time = DurationSinceUnixEpoch::from_secs(1_743_552_000);
458-
let label_set: LabelSet = [
459-
(LabelName::new("ip_version"), LabelValue::new("ipv4")),
460-
(LabelName::new("protocol"), LabelValue::new("https")),
461-
(LabelName::new("url"), LabelValue::new("https://0.0.0.0:7070")),
462-
]
463-
.into();
464-
465-
let metric_collection = MetricCollection::new(
466-
MetricKindCollection::new(vec![Metric::new(
467-
MetricName::new("announce_requests_received_total"),
468-
SampleCollection::new(vec![Sample::new(Counter::new(1), time, label_set.clone())]),
469-
)]),
470-
MetricKindCollection::new(vec![Metric::new(
471-
MetricName::new("udp_avg_connect_processing_time_ns"),
472-
SampleCollection::new(vec![Sample::new(Gauge::new(1.0), time, label_set.clone())]),
473-
)]),
474-
);
494+
let (metric_collection, _expected_json, expected_prometheus) = MetricCollectionFixture::default().deconstruct();
475495

476496
let prometheus_output = metric_collection.to_prometheus();
477497

478-
let expected = r#"
479-
announce_requests_received_total{ip_version="ipv4",protocol="https",url="https://0.0.0.0:7070"} 1
480-
udp_avg_connect_processing_time_ns{ip_version="ipv4",protocol="https",url="https://0.0.0.0:7070"} 1
481-
"#;
482-
483-
assert_eq!(prometheus_output, format_prometheus_output(expected));
484-
}
485-
486-
/// It removes leading and trailing whitespace from each line, and empty lines.
487-
fn format_prometheus_output(output: &str) -> String {
488-
output
489-
.lines()
490-
.map(str::trim)
491-
.filter(|line| !line.is_empty())
492-
.collect::<Vec<_>>()
493-
.join("\n")
498+
assert_eq!(prometheus_output, expected_prometheus);
494499
}
495500
}

0 commit comments

Comments
 (0)