// Downstream blackout recovery contracts. // // Scope: keep the eye-video stream observable when frames stop arriving or // queues overflow. // Targets: `server/src/video/eye_capture.rs` and `server/src/video/stream_core.rs`. // Why: black-screen episodes should become measurable recovery events, not // silent UI mysteries. const SERVER_EYE_CAPTURE: &str = include_str!("../../../../server/src/video/eye_capture.rs"); const SERVER_STREAM_CORE: &str = include_str!("../../../../server/src/video/stream_core.rs"); #[test] fn first_frame_and_midstream_blackouts_have_separate_watchdogs() { let first_frame = SERVER_EYE_CAPTURE .find("LESAVKA_EYE_FIRST_FRAME_TIMEOUT_MS") .expect("first-frame timeout marker"); let midstream = SERVER_EYE_CAPTURE .find("eye_stall_warn_timeout()") .expect("midstream stall timeout marker"); assert!( first_frame < midstream, "initial no-video failures should be reported before midstream stall monitoring starts" ); for marker in [ "capture produced no frames within", "downstream eye stream has produced no samples since the last frame", "last_sample_wall_ms", "first_sample_seen", "stall_watchdog_alive", ] { assert!( SERVER_EYE_CAPTURE.contains(marker), "blackout recovery should preserve marker {marker}" ); } } #[test] fn blackout_warning_defaults_are_bounded_below_ten_seconds() { for marker in [ "unwrap_or(5_000)", "Duration::from_millis(millis.max(500))", "(millis > 0).then_some", ] { assert!( SERVER_STREAM_CORE.contains(marker), "stall warning timeout should preserve bounded marker {marker}" ); } } #[test] fn overflow_recovery_waits_for_idr_before_resuming_after_drops() { let full_branch = SERVER_EYE_CAPTURE .find("TrySendError::Full") .expect("overflow branch"); let wait_for_idr = SERVER_EYE_CAPTURE .find("wait_for_idr.store(true") .expect("IDR recovery marker"); let clear_idr = SERVER_EYE_CAPTURE .find("wait_for_idr.store(false") .expect("IDR clear marker"); assert!( full_branch < wait_for_idr, "queue overflow should arm IDR recovery" ); assert!( clear_idr < full_branch, "successful IDR sends should clear recovery before later overflow can re-arm it" ); }