2026-04-22 08:07:09 -03:00
|
|
|
//! Include-based coverage for microphone level-tap publishing.
|
|
|
|
|
//!
|
|
|
|
|
//! Scope: include `client/src/input/microphone.rs` and exercise level-tap
|
|
|
|
|
//! publishing behavior without requiring a live microphone.
|
|
|
|
|
//! Targets: `client/src/input/microphone.rs`.
|
|
|
|
|
//! Why: the local launcher tap should stay best-effort and never destabilize
|
|
|
|
|
//! microphone uplink startup.
|
|
|
|
|
|
2026-04-25 16:48:20 -03:00
|
|
|
#[allow(warnings)]
|
|
|
|
|
mod live_capture_clock {
|
|
|
|
|
include!("support/live_capture_clock_shim.rs");
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-22 08:07:09 -03:00
|
|
|
#[allow(warnings)]
|
|
|
|
|
mod microphone_tap_contract {
|
|
|
|
|
include!(env!("LESAVKA_CLIENT_MICROPHONE_SRC"));
|
|
|
|
|
|
|
|
|
|
use tempfile::tempdir;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn spawned_mic_level_tap_tolerates_publish_errors() {
|
|
|
|
|
gst::init().ok();
|
|
|
|
|
let dir = tempdir().expect("tempdir");
|
|
|
|
|
let path = dir.path().join("missing-parent").join("mic-level.value");
|
|
|
|
|
let pipeline: gst::Pipeline = gst::parse::launch(
|
|
|
|
|
"appsrc name=src is-live=true format=time caps=audio/x-raw,format=S16LE,channels=2,rate=48000 ! \
|
|
|
|
|
appsink name=sink emit-signals=false sync=false max-buffers=4 drop=true",
|
|
|
|
|
)
|
|
|
|
|
.expect("pipeline")
|
|
|
|
|
.downcast()
|
|
|
|
|
.expect("pipeline cast");
|
|
|
|
|
let src: gst_app::AppSrc = pipeline
|
|
|
|
|
.by_name("src")
|
|
|
|
|
.expect("appsrc")
|
|
|
|
|
.downcast()
|
|
|
|
|
.expect("appsrc cast");
|
|
|
|
|
let sink: gst_app::AppSink = pipeline
|
|
|
|
|
.by_name("sink")
|
|
|
|
|
.expect("appsink")
|
|
|
|
|
.downcast()
|
|
|
|
|
.expect("appsink cast");
|
|
|
|
|
pipeline.set_state(gst::State::Playing).expect("playing");
|
|
|
|
|
|
|
|
|
|
let running = spawn_mic_level_tap(sink, path);
|
|
|
|
|
src.push_buffer(gst::Buffer::from_slice(i16::MAX.to_le_bytes().repeat(4)))
|
|
|
|
|
.expect("push buffer");
|
|
|
|
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
|
|
|
|
|
|
|
|
|
running.store(false, AtomicOrdering::Release);
|
|
|
|
|
let _ = pipeline.set_state(gst::State::Null);
|
|
|
|
|
}
|
|
|
|
|
}
|