blob: b54f99fbe0d1b2e671e11d68ec186dc9166b8a58 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Runs a benchmark and converts the [custom output format] to fuchsiaperf JSON.
//!
//! [custom output format]: https://source.android.com/docs/core/tests/vts/performance#iterations
use {
crate::helpers::*,
anyhow::{ensure, Context as _, Error},
fidl_fuchsia_component_runner as frunner,
fidl_fuchsia_test::{self as ftest},
fuchsiaperf::FuchsiaPerfBenchmarkResult,
serde::Deserialize,
std::collections::BTreeMap,
};
pub async fn run_binder_latency(
test: ftest::Invocation,
start_info: frunner::ComponentStartInfo,
run_listener_proxy: &ftest::RunListenerProxy,
component_runner: &frunner::ComponentRunnerProxy,
) -> Result<(), Error> {
run_starnix_benchmark(
test,
start_info,
run_listener_proxy,
component_runner,
"benchmark.json",
binder_latency_to_fuchsiaperf,
)
.await
}
#[derive(Debug, Deserialize)]
struct BinderLatencyResults {
cfg: BenchmarkConfig,
#[allow(unused)] // TODO(https://fxbug.dev/42074253) require that inheritance passes
inheritance: InheritanceResult,
#[serde(flatten)]
pairs: BTreeMap<String, PairResult>,
}
#[derive(Debug, Deserialize)]
struct BenchmarkConfig {
pair: u32,
}
#[derive(Debug, Deserialize)]
struct PairResult {
#[allow(unused)] // TODO(https://fxbug.dev/42074254) require a good sync ratio?
#[serde(rename = "SYNC")]
sync: SyncResult,
other_ms: Timing,
fifo_ms: Timing,
}
#[derive(Debug, Deserialize)]
struct Timing {
avg: f64,
#[serde(rename = "wst")]
max: f64,
#[serde(rename = "bst")]
min: f64,
}
#[allow(unused)] // TODO(https://fxbug.dev/42074254) require a good sync ratio?
#[derive(Debug, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
enum SyncResult {
Good,
Poor,
}
#[allow(unused)] // TODO(https://fxbug.dev/42074253) require that inheritance passes
#[derive(Debug, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
enum InheritanceResult {
Pass,
Fail,
}
fn binder_latency_to_fuchsiaperf(
contents: &str,
test_suite: &str,
) -> Result<Vec<FuchsiaPerfBenchmarkResult>, Error> {
let results: BinderLatencyResults =
serde_json::from_str(&contents).context("deserializing results")?;
ensure!(results.cfg.pair == 1, "expecting only a single pair of processes");
let timing = results.pairs.get("P0").context("getting first pair's timing results")?;
Ok(vec![
FuchsiaPerfBenchmarkResult {
label: "NormalSchedulerMin".to_string(),
test_suite: test_suite.to_owned(),
unit: "ms".to_string(),
values: vec![timing.other_ms.min],
},
FuchsiaPerfBenchmarkResult {
label: "NormalSchedulerAvg".to_string(),
test_suite: test_suite.to_owned(),
unit: "ms".to_string(),
values: vec![timing.other_ms.avg],
},
FuchsiaPerfBenchmarkResult {
label: "NormalSchedulerMax".to_string(),
test_suite: test_suite.to_owned(),
unit: "ms".to_string(),
values: vec![timing.other_ms.max],
},
FuchsiaPerfBenchmarkResult {
label: "FifoSchedulerMin".to_string(),
test_suite: test_suite.to_owned(),
unit: "ms".to_string(),
values: vec![timing.fifo_ms.min],
},
FuchsiaPerfBenchmarkResult {
label: "FifoSchedulerAvg".to_string(),
test_suite: test_suite.to_owned(),
unit: "ms".to_string(),
values: vec![timing.fifo_ms.avg],
},
FuchsiaPerfBenchmarkResult {
label: "FifoSchedulerMax".to_string(),
test_suite: test_suite.to_owned(),
unit: "ms".to_string(),
values: vec![timing.fifo_ms.max],
},
])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_binder_latency_to_fuchsiaperf() {
let suite = "suite.for.testing";
let sample = r#"{
"cfg":{"pair":1,"iterations":1000,"deadline_us":2500},
"P0":{"SYNC":"GOOD","S":2000,"I":2000,"R":1,
"other_ms":{ "avg":2.2 ,"wst":10 ,"bst":0.56,"miss":272,"meetR":0.728},
"fifo_ms": { "avg":1.9 ,"wst":3.9 ,"bst":0.68,"miss":108,"meetR":0.892}
},
"inheritance": "FAIL"
}"#;
let expected_perfs = vec![
FuchsiaPerfBenchmarkResult {
label: "NormalSchedulerMin".to_string(),
test_suite: suite.to_owned(),
unit: "ms".to_string(),
values: vec![0.56],
},
FuchsiaPerfBenchmarkResult {
label: "NormalSchedulerAvg".to_string(),
test_suite: suite.to_owned(),
unit: "ms".to_string(),
values: vec![2.2],
},
FuchsiaPerfBenchmarkResult {
label: "NormalSchedulerMax".to_string(),
test_suite: suite.to_owned(),
unit: "ms".to_string(),
values: vec![10.0],
},
FuchsiaPerfBenchmarkResult {
label: "FifoSchedulerMin".to_string(),
test_suite: suite.to_owned(),
unit: "ms".to_string(),
values: vec![0.68],
},
FuchsiaPerfBenchmarkResult {
label: "FifoSchedulerAvg".to_string(),
test_suite: suite.to_owned(),
unit: "ms".to_string(),
values: vec![1.9],
},
FuchsiaPerfBenchmarkResult {
label: "FifoSchedulerMax".to_string(),
test_suite: suite.to_owned(),
unit: "ms".to_string(),
values: vec![3.9],
},
];
let perfs = binder_latency_to_fuchsiaperf(sample, suite).unwrap();
assert_eq!(perfs.len(), expected_perfs.len());
for i in 0..perfs.len() {
assert_eq!(perfs[i], expected_perfs[i]);
}
}
}