45 lines
1.5 KiB
Rust
45 lines
1.5 KiB
Rust
|
|
// Non-disruptive HID latency budget coverage.
|
||
|
|
//
|
||
|
|
// Scope: measure fake endpoint write latency on local temp files only.
|
||
|
|
// Targets: server HID handoff path and Phase 7 latency budget.
|
||
|
|
// Why: input responsiveness needs a concrete p95 number; this keeps us from
|
||
|
|
// tuning by vibes while staying safe on the active desktop.
|
||
|
|
|
||
|
|
use std::{sync::Arc, time::Instant};
|
||
|
|
|
||
|
|
use lesavka_server::runtime_support::write_hid_report;
|
||
|
|
use tokio::sync::Mutex;
|
||
|
|
|
||
|
|
fn percentile_95(mut values: Vec<u128>) -> u128 {
|
||
|
|
values.sort_unstable();
|
||
|
|
let index = ((values.len() - 1) as f64 * 0.95).ceil() as usize;
|
||
|
|
values[index]
|
||
|
|
}
|
||
|
|
|
||
|
|
#[tokio::test]
|
||
|
|
async fn fake_hid_loopback_p95_stays_under_interactive_budget() {
|
||
|
|
let dir = tempfile::tempdir().expect("tempdir");
|
||
|
|
let endpoint = dir.path().join("hidg0");
|
||
|
|
std::fs::File::create(&endpoint).expect("create fake HID endpoint");
|
||
|
|
let endpoint = endpoint.to_string_lossy().to_string();
|
||
|
|
let handle = Arc::new(Mutex::new(None));
|
||
|
|
let reports: Vec<[u8; 8]> = (0..96)
|
||
|
|
.map(|idx| [0, 0, 0x04 + (idx % 26) as u8, 0, 0, 0, 0, 0])
|
||
|
|
.collect();
|
||
|
|
let mut samples_ms = Vec::with_capacity(reports.len());
|
||
|
|
|
||
|
|
for report in reports {
|
||
|
|
let started = Instant::now();
|
||
|
|
write_hid_report(&handle, &endpoint, &report)
|
||
|
|
.await
|
||
|
|
.expect("write fake HID report");
|
||
|
|
samples_ms.push(started.elapsed().as_millis());
|
||
|
|
}
|
||
|
|
|
||
|
|
let p95_ms = percentile_95(samples_ms);
|
||
|
|
assert!(
|
||
|
|
p95_ms < 150,
|
||
|
|
"fake HID write p95 should stay below 150ms, got {p95_ms}ms"
|
||
|
|
);
|
||
|
|
}
|