use std::fs; use std::path::Path; use alt_controller_image::initramfs::{ CommandRunner, InitramfsBuilder, InitramfsRecipe, InitramfsRequest, Invocation, KernelVersion, MakeInitrdBuilder, }; use tempfile::tempdir; #[test] fn discovers_the_single_rt_kernel_and_renders_a_sorted_oem_recipe() { let rootfs = tempdir().expect("rootfs directory"); fs::create_dir(rootfs.path().join("boot")).expect("boot directory"); fs::write(rootfs.path().join("boot/vmlinuz-6.12.8-alt1.rt1"), "kernel") .expect("RT kernel"); fs::write(rootfs.path().join("boot/vmlinuz-6.12.8-alt1.std"), "kernel") .expect("non-RT kernel"); let kernel = KernelVersion::discover_rt(rootfs.path()).expect("discover RT kernel"); assert_eq!(kernel.as_str(), "6.12.8-alt1.rt1"); assert_eq!( InitramfsRecipe::new(["rootfs", "compress"], ["virtio_blk.ko", "ext4"]) .expect("valid recipe") .render(), "FEATURES += compress rootfs\nMODULES += ext4 virtio_blk.ko\n" ); } #[test] fn diagnoses_missing_or_ambiguous_rt_kernels() { let rootfs = tempdir().expect("rootfs directory"); fs::create_dir(rootfs.path().join("boot")).expect("boot directory"); let missing = KernelVersion::discover_rt(rootfs.path()).expect_err("missing RT kernel"); assert!(missing.to_string().contains("no RT kernel image")); fs::write(rootfs.path().join("boot/vmlinuz-6.12-rt1"), "kernel").expect("first RT kernel"); fs::write(rootfs.path().join("boot/vmlinuz-6.11-rt1"), "kernel").expect("second RT kernel"); let ambiguous = KernelVersion::discover_rt(rootfs.path()).expect_err("ambiguous RT kernel"); assert!(ambiguous.to_string().contains("multiple RT kernel images")); } #[test] fn make_initrd_adapter_uses_typed_chroot_arguments_and_records_output_digest() { let rootfs = tempdir().expect("rootfs directory"); fs::create_dir(rootfs.path().join("boot")).expect("boot directory"); fs::write(rootfs.path().join("boot/vmlinuz-6.12-rt1"), "kernel").expect("RT kernel"); fs::write(rootfs.path().join("boot/initrd-6.12-rt1.img"), b"generated initrd") .expect("generated initrd"); let request = InitramfsRequest::discover(rootfs.path()).expect("initramfs request"); let mut builder = MakeInitrdBuilder::new(RecordingRunner::default()); let result = builder.build(&request).expect("build initramfs"); assert_eq!( builder.runner().invocations, vec![Invocation::new( "chroot", [ rootfs.path().as_os_str().to_owned(), "make-initrd".into(), "-k".into(), "6.12-rt1".into(), ], )] ); assert_eq!(result.initrd_path(), Path::new("boot/initrd-6.12-rt1.img")); assert_eq!( result.sha256(), "aec42bc86f526931d7c7f01ecba8d643dbb748f9102539a99db5d4855ee4435f" ); } #[derive(Debug, Default)] struct RecordingRunner { invocations: Vec, } impl CommandRunner for RecordingRunner { fn run(&mut self, invocation: Invocation) -> anyhow::Result<()> { self.invocations.push(invocation); Ok(()) } }