lesavka/testing/tests/client_uplink_freshness_contract.rs

141 lines
5.4 KiB
Rust
Raw Normal View History

//! Contract guardrails for uplink queue freshness budgets.
//!
//! Scope: source-level checks over client uplink queue constants.
//! Targets: `client/src/app/uplink_media.rs`, `client/src/sync_probe/capture.rs`.
//! Why: lip-sync quality depends on bounded queue age; accidental widening can
//! create near-second video lag under load.
const UPLINK_MEDIA_SRC: &str = include_str!("../../client/src/app/uplink_media.rs");
const SYNC_PROBE_CAPTURE_SRC: &str = include_str!("../../client/src/sync_probe/capture.rs");
fn queue_block<'a>(src: &'a str, queue_const: &str) -> &'a str {
let marker = format!("const {queue_const}:");
let start = src
.find(&marker)
.unwrap_or_else(|| panic!("missing queue constant marker: {marker}"));
let tail = &src[start..];
let end = tail
.find("};")
.unwrap_or_else(|| panic!("missing queue terminator for {queue_const}"));
&tail[..end]
}
fn parse_queue_capacity(block: &str, queue_const: &str) -> u64 {
let marker = "capacity:";
let start = block
.find(marker)
.unwrap_or_else(|| panic!("missing capacity for {queue_const}"));
let tail = &block[start + marker.len()..];
let value = tail.trim_start().split(',').next().unwrap_or("").trim();
value
.parse::<u64>()
.unwrap_or_else(|_| panic!("invalid capacity value for {queue_const}: {value}"))
}
fn parse_queue_max_age_ms(block: &str, queue_const: &str) -> u64 {
let millis_marker = "max_age: Duration::from_millis(";
if let Some(start) = block.find(millis_marker) {
let tail = &block[start + millis_marker.len()..];
let value = tail.split(')').next().unwrap_or("").trim();
return value
.parse::<u64>()
.unwrap_or_else(|_| panic!("invalid millis max_age for {queue_const}: {value}"));
}
let secs_marker = "max_age: Duration::from_secs(";
if let Some(start) = block.find(secs_marker) {
let tail = &block[start + secs_marker.len()..];
let value = tail.split(')').next().unwrap_or("").trim();
let seconds = value
.parse::<u64>()
.unwrap_or_else(|_| panic!("invalid seconds max_age for {queue_const}: {value}"));
return seconds.saturating_mul(1_000);
}
panic!("missing max_age for {queue_const}");
}
2026-05-01 15:21:26 -03:00
fn assert_queue_policy(block: &str, queue_const: &str, policy: &str) {
let expected = format!("policy: crate::uplink_fresh_queue::FreshQueuePolicy::{policy}");
assert!(
block.contains(&expected),
"{queue_const} should use {policy} policy to preserve the intended live-media behavior"
);
}
#[test]
fn camera_uplink_queue_freshness_budget_stays_within_lipsync_window() {
let block = queue_block(UPLINK_MEDIA_SRC, "VIDEO_UPLINK_QUEUE");
let max_age_ms = parse_queue_max_age_ms(block, "VIDEO_UPLINK_QUEUE");
assert!(
max_age_ms <= 350,
"VIDEO_UPLINK_QUEUE max_age is {max_age_ms}ms; keep it <= 350ms to prevent ~1s video drift"
);
2026-05-01 15:21:26 -03:00
assert_queue_policy(block, "VIDEO_UPLINK_QUEUE", "LatestOnly");
}
#[test]
fn microphone_uplink_queue_freshness_budget_stays_within_live_audio_window() {
let block = queue_block(UPLINK_MEDIA_SRC, "AUDIO_UPLINK_QUEUE");
let max_age_ms = parse_queue_max_age_ms(block, "AUDIO_UPLINK_QUEUE");
assert!(
max_age_ms <= 400,
"AUDIO_UPLINK_QUEUE max_age is {max_age_ms}ms; keep it <= 400ms for live calls"
);
assert_queue_policy(block, "AUDIO_UPLINK_QUEUE", "DrainOldest");
let capacity = parse_queue_capacity(block, "AUDIO_UPLINK_QUEUE");
assert!(
capacity <= 64,
"AUDIO_UPLINK_QUEUE capacity is {capacity}; keep audio continuity bounded"
);
}
#[test]
fn camera_uplink_queue_capacity_remains_bounded() {
let block = queue_block(UPLINK_MEDIA_SRC, "VIDEO_UPLINK_QUEUE");
let capacity = parse_queue_capacity(block, "VIDEO_UPLINK_QUEUE");
assert!(
capacity <= 32,
"VIDEO_UPLINK_QUEUE capacity is {capacity}; larger queues amplify tail-latency under stalls"
);
}
#[test]
fn sync_probe_video_queue_uses_same_freshness_budget() {
let block = queue_block(SYNC_PROBE_CAPTURE_SRC, "PROBE_VIDEO_QUEUE");
let max_age_ms = parse_queue_max_age_ms(block, "PROBE_VIDEO_QUEUE");
assert!(
max_age_ms <= 350,
"PROBE_VIDEO_QUEUE max_age is {max_age_ms}ms; keep probe and runtime freshness policies aligned"
);
2026-05-01 15:21:26 -03:00
assert_queue_policy(block, "PROBE_VIDEO_QUEUE", "LatestOnly");
}
#[test]
fn sync_probe_audio_queue_preserves_bounded_marker_continuity() {
let block = queue_block(SYNC_PROBE_CAPTURE_SRC, "PROBE_AUDIO_QUEUE");
let max_age_ms = parse_queue_max_age_ms(block, "PROBE_AUDIO_QUEUE");
assert!(
max_age_ms <= 400,
"PROBE_AUDIO_QUEUE max_age is {max_age_ms}ms; keep probe audio continuity bounded"
);
assert_queue_policy(block, "PROBE_AUDIO_QUEUE", "DrainOldest");
}
#[test]
fn strict_explicit_media_source_failures_abort_the_headless_probe_client() {
for expected in [
"LESAVKA_REQUIRE_EXPLICIT_MEDIA_SOURCES",
"abort_if_required_media_source_failed",
"required {kind} source '{source}' failed to start",
"std::process::exit(2)",
"abort_if_required_media_source_failed(\"microphone\"",
"abort_if_required_media_source_failed(\"camera\"",
] {
assert!(
UPLINK_MEDIA_SRC.contains(expected),
"required-source setup failures must be fatal in strict probe mode: missing {expected}"
);
}
}