lesavka/tests/regression/install/install_preserves_codec_settings_contract.rs

101 lines
4.0 KiB
Rust

// Regression contract for preserving codec settings across upgrades.
//
// Scope: keep safe HEVC/MJPEG ingress selection and MJPEG UVC output defaults
// explicit, while still allowing operator-provided install overrides.
// Targets: server/client install scripts and client camera capture defaults.
// Why: Lesavka now supports both MJPEG and HEVC upstream media, and installer
// reruns may prefer HEVC when decode is proven, falling back to either a
// smoke-tested software HEVC decoder or MJPEG instead of producing black frames.
const SERVER_INSTALL: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/scripts/install/server.sh"
));
const CLIENT_CAMERA: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/client/src/input/camera/capture_pipeline.rs"
));
#[test]
fn server_install_defaults_to_hevc_ingress_with_mjpeg_fallback_and_mjpeg_uvc_output() {
for marker in [
"PERSISTED_UVC_CODEC=$(persisted_uvc_value LESAVKA_UVC_CODEC || true)",
"normalize_uvc_codec()",
"normalize_cam_codec()",
"REQUESTED_UVC_CODEC=${LESAVKA_INSTALL_UVC_CODEC:-${PERSISTED_UVC_CODEC:-mjpeg}}",
"INSTALL_UVC_CODEC=$(normalize_uvc_codec \"$REQUESTED_UVC_CODEC\")",
"REQUESTED_CAM_CODEC=${LESAVKA_INSTALL_CAM_CODEC:-${LESAVKA_CAM_CODEC:-hevc}}",
"INSTALL_CAM_CODEC=$(normalize_cam_codec \"${REQUESTED_CAM_CODEC}\")",
"INSTALL_CAM_CODEC_EXPLICIT=0",
"INSTALL_HEVC_DECODER=${LESAVKA_INSTALL_HEVC_DECODER:-${LESAVKA_HEVC_DECODER:-}}",
"INSTALL_ALLOW_SOFTWARE_VIDEO=${LESAVKA_INSTALL_ALLOW_SOFTWARE_VIDEO:-${LESAVKA_ALLOW_SOFTWARE_VIDEO:-0}}",
"Software HEVC decoder passed the same 1280x720 smoke",
"Default HEVC upstream cannot be proven on this host; falling back to MJPEG ingress.",
"printf 'LESAVKA_CAM_CODEC=%s\\n' \"${INSTALL_CAM_CODEC}\"",
"printf 'LESAVKA_HEVC_DECODER=%s\\n' \"$INSTALL_HEVC_DECODER\"",
"printf 'LESAVKA_ALLOW_SOFTWARE_VIDEO=%s\\n' \"${INSTALL_ALLOW_SOFTWARE_VIDEO}\"",
"printf 'LESAVKA_UVC_CODEC=%s\\n' \"${INSTALL_UVC_CODEC}\"",
"\"LESAVKA_UVC_CODEC=${INSTALL_UVC_CODEC}\"",
"uvc_env_value LESAVKA_UVC_WIDTH 1280",
] {
assert!(
SERVER_INSTALL.contains(marker),
"server installer should preserve codec marker {marker}"
);
}
}
#[test]
fn server_install_does_not_let_ambient_uvc_codec_override_persisted_default() {
assert!(
!SERVER_INSTALL.contains("LESAVKA_UVC_CODEC=${LESAVKA_UVC_CODEC:-mjpeg}"),
"ambient runtime UVC codec should not leak into install defaults"
);
assert!(
SERVER_INSTALL.contains("LESAVKA_INSTALL_UVC_CODEC"),
"operator install override should remain available"
);
assert!(
SERVER_INSTALL
.contains("UVC gadget output codec '${REQUESTED_UVC_CODEC}' is not supported"),
"unsupported host-facing UVC codecs should be downgraded loudly instead of creating a stale YUYV descriptor"
);
}
#[test]
fn client_camera_can_emit_hevc_or_mjpeg_from_live_capture() {
for marker in [
"LESAVKA_CAM_CODEC",
"CameraCodec::Hevc",
"CameraCodec::Mjpeg",
"choose_hevc_encoder",
"hevc_keyframe_interval",
"image/jpeg",
"video/x-h265",
] {
assert!(
CLIENT_CAMERA.contains(marker),
"client camera pipeline should preserve codec marker {marker}"
);
}
}
#[test]
fn hevc_prerequisites_are_rechecked_idempotently() {
for marker in [
"ensure_hevc_decode_support",
"pacman -Sq --needed --noconfirm",
"modprobe rpi_hevc_dec",
"/etc/modules-load.d/lesavka-hevc.conf",
"gst-inspect-1.0 v4l2slh265dec",
"avdec_h265 libde265dec",
"Keeping default HEVC upstream to avoid direct-MJPEG UVC artifacts",
"Refusing HEVC upstream install because production video decode must be hardware-accelerated and proven",
] {
assert!(
SERVER_INSTALL.contains(marker),
"HEVC prerequisite path should preserve marker {marker}"
);
}
}