use piper_sdk::driver::{PipelineConfig, PiperBuilder};
use std::time::{Duration, Instant};
fn is_ci_env() -> bool {
std::env::var("CI").is_ok()
|| std::env::var("GITHUB_ACTIONS").is_ok()
|| std::env::var("GITLAB_CI").is_ok()
|| std::env::var("CIRCLECI").is_ok()
|| std::env::var("TRAVIS").is_ok()
|| std::env::var("APPVEYOR").is_ok()
}
fn adjust_threshold_ms(local_threshold_ms: u64) -> Duration {
let multiplier = if is_ci_env() { 5 } else { 1 };
Duration::from_millis(local_threshold_ms * multiplier)
}
fn calculate_percentiles(mut latencies: Vec<Duration>) -> (Duration, Duration, Duration, Duration) {
latencies.sort();
let len = latencies.len();
let p50 = latencies[len * 50 / 100];
let p95 = latencies[len * 95 / 100];
let p99 = latencies[len * 99 / 100];
let max = latencies[len - 1];
(p50, p95, p99, max)
}
#[test]
#[ignore]
fn test_command_latency_quiet_bus() {
let config = PipelineConfig::default();
assert_eq!(
config.receive_timeout_ms, 2,
"Default timeout should be 2ms"
);
let piper = PiperBuilder::new()
.pipeline_config(config)
.build()
.expect("Failed to create Piper");
let frame = piper_sdk::can::PiperFrame::new_standard(0x123, &[0x01, 0x02, 0x03, 0x04]);
let mut latencies = Vec::new();
for _ in 0..100 {
let start = Instant::now();
piper.send_frame(frame).expect("Failed to send frame");
let elapsed = start.elapsed();
latencies.push(elapsed);
std::thread::sleep(Duration::from_millis(1));
}
let (p50, p95, p99, max) = calculate_percentiles(latencies);
println!("\n=== 命令延迟分布(安静总线场景)===");
println!("P50: {:?}", p50);
println!("P95: {:?}", p95);
println!("P99: {:?}", p99);
println!("Max: {:?}", max);
let p99_threshold = adjust_threshold_ms(5);
assert!(
p99 < p99_threshold,
"P99 latency too high: {:?} (expected < {:?}, CI环境已放宽)",
p99,
p99_threshold
);
let p50_threshold = adjust_threshold_ms(1);
assert!(
p50 < p50_threshold,
"P50 latency too high: {:?} (expected < {:?}, CI环境已放宽)",
p50,
p50_threshold
);
}
#[cfg(target_os = "linux")]
#[test]
#[ignore]
fn test_socketcan_timeout_config() {
use piper_sdk::can::CanAdapter;
use piper_sdk::can::SocketCanAdapter;
use std::time::Duration;
let mut adapter = SocketCanAdapter::new("can0").expect("Failed to create SocketCAN adapter");
adapter
.set_read_timeout(Duration::from_millis(2))
.expect("Failed to set read timeout");
let start = Instant::now();
match adapter.receive() {
Err(piper_sdk::can::CanError::Timeout) => {
let elapsed = start.elapsed();
println!("SocketCAN timeout: {:?}", elapsed);
let max_threshold = adjust_threshold_ms(10);
assert!(
elapsed >= Duration::from_millis(1) && elapsed < max_threshold,
"Timeout latency out of range: {:?} (max: {:?}, CI环境已放宽)",
elapsed,
max_threshold
);
},
Ok(frame) => {
println!("Received frame unexpectedly: ID=0x{:X}", frame.id);
},
Err(e) => panic!("Unexpected error: {}", e),
}
}
#[test]
#[ignore]
fn test_gs_usb_timeout_config() {
use piper_sdk::can::CanAdapter;
use piper_sdk::can::gs_usb::GsUsbCanAdapter;
use std::time::Duration;
let mut adapter = GsUsbCanAdapter::new().expect("Failed to create GS-USB adapter");
adapter.configure(500_000).expect("Failed to configure");
adapter.set_receive_timeout(Duration::from_millis(2));
let start = Instant::now();
match adapter.receive() {
Err(piper_sdk::can::CanError::Timeout) => {
let elapsed = start.elapsed();
println!("GS-USB timeout: {:?}", elapsed);
let max_threshold = adjust_threshold_ms(15);
assert!(
elapsed >= Duration::from_millis(1) && elapsed < max_threshold,
"Timeout latency out of range: {:?} (max: {:?}, CI环境已放宽)",
elapsed,
max_threshold
);
},
Ok(frame) => {
println!("Received frame unexpectedly: ID=0x{:X}", frame.id);
},
Err(e) => panic!("Unexpected error: {}", e),
}
}