From 8ed19c43116aa112acf51a18224c4074b3edeb4c Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Mon, 18 May 2026 13:55:48 -0300 Subject: [PATCH] ci(lesavka): stabilize safe gate coverage --- server/src/audio/ear_capture.rs | 1 + server/src/uvc_runtime.rs | 11 ++++++- .../video_sinks/webcam_sink/frame_handoff.rs | 6 ++-- .../server/uvc/server_uvc_runtime_contract.rs | 30 +++++++++++-------- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/server/src/audio/ear_capture.rs b/server/src/audio/ear_capture.rs index 58c5625..644a4f8 100644 --- a/server/src/audio/ear_capture.rs +++ b/server/src/audio/ear_capture.rs @@ -20,6 +20,7 @@ use lesavka_common::lesavka::AudioPacket; #[path = "ear_capture/source_watchdog.rs"] mod source_watchdog; +#[cfg(not(coverage))] use source_watchdog::{AudioSourceHealth, spawn_audio_source_watchdog}; /// “Speaker” stream coming **from** the remote host (UAC2‑gadget playback diff --git a/server/src/uvc_runtime.rs b/server/src/uvc_runtime.rs index 44571dd..ff3dada 100644 --- a/server/src/uvc_runtime.rs +++ b/server/src/uvc_runtime.rs @@ -138,6 +138,15 @@ pub fn spawn_uvc_control(bin: &str, uvc_dev: &str) -> anyhow::Result Duration { + let millis = std::env::var("LESAVKA_UVC_RESTART_DELAY_MS") + .ok() + .and_then(|value| value.parse::().ok()) + .unwrap_or(2_000) + .min(10_000); + Duration::from_millis(millis) +} + /// Supervise the external UVC control helper forever. /// /// Inputs: the helper binary path. @@ -193,7 +202,7 @@ pub async fn supervise_uvc_control(bin: String) { } } - tokio::time::sleep(Duration::from_secs(2)).await; + tokio::time::sleep(uvc_control_restart_delay()).await; } } diff --git a/server/src/video_sinks/webcam_sink/frame_handoff.rs b/server/src/video_sinks/webcam_sink/frame_handoff.rs index 95d3508..dc018d9 100644 --- a/server/src/video_sinks/webcam_sink/frame_handoff.rs +++ b/server/src/video_sinks/webcam_sink/frame_handoff.rs @@ -5,9 +5,9 @@ use std::sync::atomic::Ordering; use tracing::warn; use super::hevc_mjpeg_guard; -use super::mjpeg_spool::{ - MjpegSpoolTiming, freshest_mjpeg_sample, spool_mjpeg_frame_with_timing, -}; +#[cfg(not(coverage))] +use super::mjpeg_spool::freshest_mjpeg_sample; +use super::mjpeg_spool::{MjpegSpoolTiming, spool_mjpeg_frame_with_timing}; use super::*; use crate::video_support::{contains_hevc_irap, reserve_local_pts}; diff --git a/tests/compatibility/server/uvc/server_uvc_runtime_contract.rs b/tests/compatibility/server/uvc/server_uvc_runtime_contract.rs index d858871..52315bb 100644 --- a/tests/compatibility/server/uvc/server_uvc_runtime_contract.rs +++ b/tests/compatibility/server/uvc/server_uvc_runtime_contract.rs @@ -11,7 +11,7 @@ use serial_test::serial; use std::fs; use std::os::unix::fs::PermissionsExt; use std::time::Duration; -use temp_env::with_var; +use temp_env::{with_var, with_vars}; use tempfile::tempdir; use tokio::runtime::Runtime; @@ -76,17 +76,23 @@ fn supervise_uvc_control_restarts_helper_after_exit() { fs::set_permissions(&helper, perms).expect("chmod helper script"); let helper_path = helper.to_string_lossy().to_string(); - with_var("LESAVKA_UVC_DEV", Some("/dev/video-loop"), || { - let rt = Runtime::new().expect("runtime"); - let result = rt.block_on(async { - tokio::time::timeout( - Duration::from_millis(2_450), - supervise_uvc_control(helper_path), - ) - .await - }); - assert!(result.is_err(), "supervisor should still be running"); - }); + with_vars( + [ + ("LESAVKA_UVC_DEV", Some("/dev/video-loop")), + ("LESAVKA_UVC_RESTART_DELAY_MS", Some("25")), + ], + || { + let rt = Runtime::new().expect("runtime"); + let result = rt.block_on(async { + tokio::time::timeout( + Duration::from_millis(450), + supervise_uvc_control(helper_path), + ) + .await + }); + assert!(result.is_err(), "supervisor should still be running"); + }, + ); let calls = fs::read_to_string(marker).expect("read helper marker"); let restart_count = calls