// 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" ); } }