use super::{ SOFTWARE_VIDEO_FALLBACK_ENV, adjust_effective_fps, contains_hevc_irap, contains_idr, default_eye_fps, env_u32, env_usize, is_hardware_h264_decoder, is_hardware_hevc_decoder, next_local_pts, pick_h264_decoder, pick_hevc_decoder, require_h264_decoder, require_hevc_decoder, reserve_local_pts, should_send_frame, software_video_fallback_allowed, }; use serial_test::serial; use std::sync::atomic::AtomicU64; use temp_env::with_var; #[test] fn default_eye_fps_tracks_bitrate_tiers() { assert_eq!(default_eye_fps(0), 25); assert_eq!(default_eye_fps(2_000), 15); assert_eq!(default_eye_fps(3_000), 20); assert_eq!(default_eye_fps(8_000), 25); } #[test] fn contains_idr_finds_annex_b_keyframes() { let sample = [0, 0, 0, 1, 0x65, 0x88, 0x99]; assert!(contains_idr(&sample)); assert!(contains_idr(&[0, 0, 1, 0x65, 0x88])); assert!(!contains_idr(&[0, 0, 0, 1, 0x41, 0x99])); assert!(!contains_idr(&[0, 0, 2, 0x65, 0x88])); } #[test] fn contains_hevc_irap_finds_annex_b_recovery_frames() { assert!(contains_hevc_irap(&[0, 0, 0, 1, 0x26, 0x01, 0xaa])); assert!(contains_hevc_irap(&[0, 0, 1, 0x28, 0x01, 0xaa])); assert!(!contains_hevc_irap(&[0, 0, 0, 1, 0x02, 0x01, 0xaa])); } #[test] fn adjust_effective_fps_reacts_to_drop_windows() { assert_eq!(adjust_effective_fps(20, 12, 25, 5, 10), 17); assert_eq!(adjust_effective_fps(20, 12, 25, 0, 20), 21); assert_eq!(adjust_effective_fps(12, 12, 25, 10, 10), 12); } #[test] fn should_send_frame_enforces_interval() { assert!(should_send_frame(0, 10, 25)); assert!(!should_send_frame(40_000, 50_000, 25)); assert!(should_send_frame(40_000, 90_000, 25)); assert!(!should_send_frame(40_000, 40_001, 0)); assert!(should_send_frame(40_000, 1_040_000, 0)); } #[test] fn next_local_pts_monotonically_advances() { let counter = AtomicU64::new(0); assert_eq!(next_local_pts(&counter, 40_000), 0); assert_eq!(next_local_pts(&counter, 40_000), 40_000); } #[test] fn reserve_local_pts_prefers_preferred_value_but_stays_monotonic() { let counter = AtomicU64::new(0); assert_eq!(reserve_local_pts(&counter, 0, 40_000), 0); assert_eq!(reserve_local_pts(&counter, 10_000, 40_000), 40_000); assert_eq!(reserve_local_pts(&counter, 120_000, 40_000), 120_000); } #[test] #[serial] fn env_helpers_parse_values_and_fallbacks() { with_var("LESAVKA_TEST_U32", Some("42"), || { assert_eq!(env_u32("LESAVKA_TEST_U32", 7), 42); }); with_var("LESAVKA_TEST_U32", Some("oops"), || { assert_eq!(env_u32("LESAVKA_TEST_U32", 7), 7); }); with_var("LESAVKA_TEST_USIZE", Some("128"), || { assert_eq!(env_usize("LESAVKA_TEST_USIZE", 64), 128); }); with_var("LESAVKA_TEST_USIZE", None::<&str>, || { assert_eq!(env_usize("LESAVKA_TEST_USIZE", 64), 64); }); } #[test] #[serial] fn software_video_fallback_requires_clear_operator_opt_in() { for disabled in [ None, Some(""), Some("0"), Some("false"), Some("no"), Some("off"), ] { with_var(SOFTWARE_VIDEO_FALLBACK_ENV, disabled, || { assert!(!software_video_fallback_allowed()); }); } for enabled in ["1", "true", "yes", "on", "lab"] { with_var(SOFTWARE_VIDEO_FALLBACK_ENV, Some(enabled), || { assert!(software_video_fallback_allowed()); }); } } #[test] fn hardware_decoder_classification_keeps_software_fallbacks_out() { for name in [ "v4l2h264dec", "v4l2slh264dec", "omxh264dec", "vulkanh264dec", ] { assert!(is_hardware_h264_decoder(name)); } assert!(!is_hardware_h264_decoder("avdec_h264")); for name in [ "v4l2slh265dec", "v4l2h265dec", "vulkanh265dec", "nvh265dec", "nvh265sldec", ] { assert!(is_hardware_hevc_decoder(name)); } assert!(!is_hardware_hevc_decoder("libde265dec")); } #[test] #[serial] fn explicit_bad_decoder_overrides_fail_loudly_without_registry_assumptions() { gstreamer::init().expect("initialize gstreamer registry for decoder lookup"); with_var( "LESAVKA_H264_DECODER", Some("definitely-not-a-decoder"), || { let err = require_h264_decoder().expect_err("bogus H.264 decoder should fail"); assert!( err.to_string().contains("not buildable"), "unexpected H.264 override error: {err:#}" ); assert_eq!(pick_h264_decoder(), "missing-hardware-h264dec"); }, ); with_var( "LESAVKA_HEVC_DECODER", Some("definitely-not-a-decoder"), || { let err = require_hevc_decoder().expect_err("bogus HEVC decoder should fail"); assert!( err.to_string().contains("not buildable"), "unexpected HEVC override error: {err:#}" ); assert_eq!(pick_hevc_decoder(), "missing-hardware-hevcdec"); }, ); } #[test] fn adjust_effective_fps_keeps_current_rate_when_no_samples() { assert_eq!(adjust_effective_fps(18, 12, 25, 0, 0), 18); }