//! Static contract for the v2 bundled upstream media handoff. //! //! Scope: guard `StreamWebcamMedia` against reintroducing timed sink sleeps in //! the gRPC receive loop. //! Targets: `server/src/main/relay_service.rs` and //! `server/src/main/relay_service/upstream_media_rpc.rs`. //! Why: client->server freshness depends on draining bundled media as it //! arrives; presentation timing belongs in bounded handoff workers. const RELAY_SERVICE: &str = include_str!("../../server/src/main/relay_service.rs"); const WEBCAM_RPC: &str = include_str!("../../server/src/main/relay_service/upstream_media_rpc.rs"); const WEBCAM_SINK: &str = include_str!("../../server/src/video_sinks/webcam_sink.rs"); const MJPEG_SPOOL: &str = include_str!("../../server/src/video_sinks/mjpeg_spool.rs"); const PROFILE_OFFSETS: &str = include_str!("../../server/src/calibration/profile_offsets.rs"); const MATRIX_SCRIPT: &str = include_str!("../../scripts/manual/run_server_to_rc_mode_matrix.sh"); #[test] fn bundled_receive_loop_enqueues_instead_of_sleeping_for_handoff() { for expected in [ "tokio::sync::mpsc::channel::(32)", "tokio::sync::mpsc::channel::(32)", "tokio::spawn(run_media_v2_audio_handoff", "tokio::spawn(run_media_v2_video_handoff", "let bundle_epoch = bundle_arrived_at + schedule.common_delay;", "let bundle_base_remote_pts_us = facts.capture_start_us;", "prepare_media_v2_audio(", "prepare_media_v2_video(", "bundle_base_remote_pts_us", "bundle_epoch", ".send(scheduled_audio)", ".send(scheduled_video)", ] { assert!( WEBCAM_RPC.contains(expected), "v2 bundled RPC should enqueue handoff work with marker {expected}" ); } for forbidden in [ "push_media_v2_audio(", "feed_media_v2_video(", "sleep_until_media_v2(", "MediaV2Clock", ] { assert!( !WEBCAM_RPC.contains(forbidden), "v2 bundled RPC receive loop must not perform timed sink handoff: {forbidden}" ); } } #[test] fn handoff_workers_own_timing_and_presentation_telemetry() { for expected in [ "async fn run_media_v2_audio_handoff", "async fn run_media_v2_video_handoff", "sleep_until_media_v2(item.due_at).await;", "sink.push(&audio);", "sink.finish();", "relay.feed(item.packet);", "mark_audio_presented(pts, item.due_at)", "mark_video_presented(presented_pts, item.due_at)", "Why: sleeping in the receive loop created HTTP/2 backlog", ] { assert!( RELAY_SERVICE.contains(expected), "handoff workers should preserve timing/telemetry marker {expected}" ); } } #[test] fn stream_shutdown_drains_handoff_workers_before_releasing_leases() { let audio_drop = WEBCAM_RPC.find("drop(audio_handoff_tx);").unwrap(); let video_drop = WEBCAM_RPC.find("drop(video_handoff_tx);").unwrap(); let audio_join = WEBCAM_RPC.find("audio_worker.await").unwrap(); let video_join = WEBCAM_RPC.find("video_worker.await").unwrap(); let close_camera = WEBCAM_RPC .rfind("upstream_media_rt.close_camera(camera_lease.generation);") .unwrap(); let close_microphone = WEBCAM_RPC .rfind("upstream_media_rt.close_microphone(microphone_lease.generation);") .unwrap(); assert!(audio_drop < audio_join); assert!(video_drop < video_join); assert!(audio_join < close_camera); assert!(video_join < close_microphone); } #[test] fn hevc_ingress_decodes_to_existing_mjpeg_uvc_path() { for expected in [ "let use_hevc = matches!(cfg.codec, CameraCodec::Hevc);", "video/x-h265", "h265parse", "pick_hevc_decoder()", "jpegenc", "LESAVKA_UVC_HEVC_JPEG_QUALITY", "LESAVKA_UVC_HEVC_SPOOL_PULL_TIMEOUT_MS", "image/jpeg", "hevc_mjpeg_spool_sink", ".property(\"sync\", clock_align_enabled)", "failed to spool decoded HEVC frame for UVC helper", "HEVC camera uplink will be decoded and emitted as MJPEG/UVC", ] { assert!( WEBCAM_SINK.contains(expected) || MJPEG_SPOOL.contains(expected), "HEVC UVC sink should preserve decode-to-MJPEG marker {expected}" ); } assert!( WEBCAM_SINK.find("video/x-h265").unwrap() < WEBCAM_SINK.find("jpegenc").unwrap(), "HEVC should be decoded before MJPEG encoding for the existing UVC output path" ); } #[test] fn mjpeg_ingress_remains_passthrough_and_profile_calibrated() { for expected in [ "let use_mjpeg = matches!(cfg.codec, CameraCodec::Mjpeg);", "image/jpeg", "src.set_caps(Some(&caps_mjpeg));", "MjpegSpoolTiming::mjpeg_passthrough(pkt.pts)", "spool_mjpeg_frame_with_timing(path, &pkt.data, Some(timing))", "FACTORY_MJPEG_VIDEO_MODE_OFFSETS_US", "FACTORY_HEVC_VIDEO_MODE_OFFSETS_US", "LESAVKA_UPSTREAM_MJPEG_VIDEO_PLAYOUT_MODE_OFFSETS_US", "LESAVKA_UPSTREAM_HEVC_VIDEO_PLAYOUT_MODE_OFFSETS_US", "LESAVKA_SERVER_RC_PROFILE=${LESAVKA_SERVER_RC_PROFILE:-mjpeg}", "LESAVKA_SERVER_RC_NORMALIZED_PROFILE=hevc", ] { assert!( WEBCAM_SINK.contains(expected) || PROFILE_OFFSETS.contains(expected) || MATRIX_SCRIPT.contains(expected), "MJPEG/HEVC profile separation should contain marker {expected}" ); } assert!( PROFILE_OFFSETS .find("FACTORY_MJPEG_VIDEO_MODE_OFFSETS_US") .unwrap() < PROFILE_OFFSETS .find("FACTORY_HEVC_VIDEO_MODE_OFFSETS_US") .unwrap(), "MJPEG factory map should stay separate from the additive HEVC map" ); }