68 lines
2.6 KiB
Rust
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"
|
|
);
|
|
}
|
|
}
|