lesavka/tests/reliability/audio/audio_epoch_recovery_reliability_contract.rs

68 lines
2.6 KiB
Rust

// Reliability contract for repeated audio epoch recovery.
//
// Scope: exercise repeated server-side audio recovery cycles without HID, UVC,
// GTK, GStreamer, or physical USB devices.
// Targets: `server/src/upstream_media_runtime.rs`.
// Why: the first-join audio fix should be safe to call during reconnect churn
// without causing heal loops, video resets, or calibration drift.
use lesavka_server::upstream_media_runtime::UpstreamMediaRuntime;
#[test]
fn repeated_audio_epoch_heals_do_not_reset_video_or_calibration() {
let runtime = UpstreamMediaRuntime::new();
runtime.set_playout_offsets(162_659, 5_000);
let camera = runtime.activate_camera();
let microphone = runtime.activate_microphone();
let session_id = runtime.snapshot().session_id;
for _ in 0..5 {
runtime.soft_recover_microphone();
assert!(runtime.is_camera_active(camera.generation));
assert!(!runtime.is_microphone_active(microphone.generation));
assert_eq!(runtime.playout_offsets(), (162_659, 5_000));
assert_eq!(runtime.snapshot().session_id, session_id);
}
let fresh_microphone = runtime.activate_microphone();
assert!(runtime.is_microphone_active(fresh_microphone.generation));
assert!(fresh_microphone.generation > microphone.generation);
assert_eq!(fresh_microphone.session_id, session_id);
}
#[test]
fn connect_disconnect_cycles_leave_no_stale_microphone_generation_active() {
let runtime = UpstreamMediaRuntime::new();
for cycle in 0..20 {
let camera = runtime.activate_camera();
let microphone = runtime.activate_microphone();
let session_id = runtime.snapshot().session_id;
runtime.soft_recover_microphone();
assert!(
runtime.is_camera_active(camera.generation),
"cycle {cycle}: video generation should survive audio heal"
);
assert!(
!runtime.is_microphone_active(microphone.generation),
"cycle {cycle}: stale microphone generation should be retired"
);
let replacement = runtime.activate_microphone();
assert_eq!(replacement.session_id, session_id);
assert!(runtime.is_microphone_active(replacement.generation));
runtime.close_microphone(replacement.generation);
runtime.close_camera(camera.generation);
assert!(
!runtime.is_camera_active(camera.generation),
"cycle {cycle}: camera should close cleanly after session"
);
assert!(
!runtime.is_microphone_active(replacement.generation),
"cycle {cycle}: replacement microphone should close cleanly after session"
);
}
}