2019-05-07 11:55:38 +02:00
|
|
|
use serde::*;
|
2018-03-20 17:00:24 -04:00
|
|
|
use serde_json::to_vec_pretty;
|
2018-03-19 17:37:56 -04:00
|
|
|
|
2021-08-24 21:33:48 +02:00
|
|
|
use super::Exporter;
|
2022-02-20 13:44:34 +01:00
|
|
|
use crate::benchmark::benchmark_result::BenchmarkResult;
|
2023-06-03 21:06:50 +02:00
|
|
|
use crate::options::SortOrder;
|
2026-10-05 14:19:34 +02:00
|
|
|
use crate::quantity::TimeUnit;
|
2021-08-24 21:33:48 +02:00
|
|
|
|
2022-02-06 17:44:28 +01:00
|
|
|
use anyhow::Result;
|
|
|
|
|
|
2018-03-19 17:37:56 -04:00
|
|
|
#[derive(Serialize, Debug)]
|
|
|
|
|
struct HyperfineSummary<'a> {
|
2026-10-05 16:10:08 +02:00
|
|
|
schema_version: u32,
|
2019-07-13 10:29:05 +02:00
|
|
|
results: &'a [BenchmarkResult],
|
2018-03-19 17:37:56 -04:00
|
|
|
}
|
|
|
|
|
|
2018-03-20 17:00:24 -04:00
|
|
|
#[derive(Default)]
|
2018-03-19 17:37:56 -04:00
|
|
|
pub struct JsonExporter {}
|
|
|
|
|
|
2018-03-20 20:26:28 +01:00
|
|
|
impl Exporter for JsonExporter {
|
2023-06-03 21:06:50 +02:00
|
|
|
fn serialize(
|
|
|
|
|
&self,
|
|
|
|
|
results: &[BenchmarkResult],
|
2026-10-05 14:18:33 +02:00
|
|
|
_time_unit: Option<TimeUnit>,
|
2023-06-03 21:06:50 +02:00
|
|
|
_sort_order: SortOrder,
|
2026-10-05 14:59:18 +02:00
|
|
|
_reference_index: Option<usize>,
|
2023-06-03 21:06:50 +02:00
|
|
|
) -> Result<Vec<u8>> {
|
2026-10-05 16:10:08 +02:00
|
|
|
let mut output = to_vec_pretty(&HyperfineSummary {
|
|
|
|
|
schema_version: 2,
|
|
|
|
|
results,
|
|
|
|
|
});
|
2022-09-07 09:20:50 +02:00
|
|
|
if let Ok(ref mut content) = output {
|
2018-03-21 22:56:01 +01:00
|
|
|
content.push(b'\n');
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-06 17:44:28 +01:00
|
|
|
Ok(output?)
|
2018-03-19 17:37:56 -04:00
|
|
|
}
|
|
|
|
|
}
|
2026-10-05 15:32:27 +02:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_json_optional_memory() {
|
|
|
|
|
use crate::benchmark::measurement::{Measurement, Measurements};
|
|
|
|
|
use crate::quantity::{byte, Information};
|
|
|
|
|
use serde_json::json;
|
|
|
|
|
|
|
|
|
|
for (memory, expected_memory) in [
|
|
|
|
|
(None, None),
|
|
|
|
|
(
|
|
|
|
|
Some(Information::new::<byte>(0.0)),
|
|
|
|
|
Some(json!({"value": 0.0, "unit": "byte"})),
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
Some(Information::new::<byte>(1024.0)),
|
|
|
|
|
Some(json!({"value": 1024.0, "unit": "byte"})),
|
|
|
|
|
),
|
|
|
|
|
] {
|
|
|
|
|
let result = BenchmarkResult {
|
|
|
|
|
command: "example".into(),
|
|
|
|
|
measurements: Measurements::new(vec![Measurement {
|
|
|
|
|
peak_memory_usage: memory,
|
|
|
|
|
..Measurement::default()
|
|
|
|
|
}]),
|
|
|
|
|
..BenchmarkResult::default()
|
|
|
|
|
};
|
|
|
|
|
let output = JsonExporter::default()
|
2026-10-05 16:03:23 +02:00
|
|
|
.serialize(&[result], None, SortOrder::Command, None)
|
2026-10-05 15:32:27 +02:00
|
|
|
.unwrap();
|
|
|
|
|
let actual: serde_json::Value = serde_json::from_slice(&output).unwrap();
|
|
|
|
|
let mut expected = json!({
|
2026-10-05 16:10:08 +02:00
|
|
|
"schema_version": 2,
|
2026-10-05 15:32:27 +02:00
|
|
|
"results": [{
|
|
|
|
|
"command": "example",
|
|
|
|
|
"measurements": [{
|
|
|
|
|
"time_wall_clock": {"value": 0.0, "unit": "second"},
|
|
|
|
|
"time_user": {"value": 0.0, "unit": "second"},
|
|
|
|
|
"time_system": {"value": 0.0, "unit": "second"},
|
|
|
|
|
"exit_code": 0
|
|
|
|
|
}]
|
|
|
|
|
}]
|
|
|
|
|
});
|
|
|
|
|
if let Some(memory) = expected_memory {
|
|
|
|
|
expected["results"][0]["measurements"][0]["peak_memory_usage"] = memory;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(actual, expected);
|
|
|
|
|
}
|
|
|
|
|
}
|