74 lines
2.4 KiB
Rust
74 lines
2.4 KiB
Rust
// 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"
|
|
);
|
|
}
|