use std::path::PathBuf; use alt_controller_image::hasher::{CommandRunner, HasherInstaller, Invocation}; use alt_controller_image::package_installer::{AptConfig, PackageInstaller, PackageRequest}; use alt_controller_image::{BuildPlan, ImageSpec}; #[derive(Default)] struct RecordingRunner { invocations: std::cell::RefCell>, } impl CommandRunner for RecordingRunner { fn run(&self, invocation: Invocation) -> anyhow::Result<()> { self.invocations.borrow_mut().push(invocation); Ok(()) } } #[test] fn hasher_installer_passes_typed_request_to_initroot_and_install_commands() { let runner = RecordingRunner::default(); let installer = HasherInstaller::new(runner); let request = PackageRequest::new( "/build/work", AptConfig::new("profiles/apt.conf").expect("valid apt config path"), ["basesystem", "make-initrd"], ["^kernel-image-rt$"], ) .expect("valid package request"); installer.install(&request).expect("installation succeeds"); let invocations = &installer.runner().invocations.borrow(); assert_eq!( invocations.as_slice(), [ Invocation::new( "hsh", [ "--mountpoints=/proc", "--initroot-only", "--apt-config", "profiles/apt.conf", "--workdir", "/build/work", ], ), Invocation::new( "hsh-install", [ "--mountpoints=/proc", "--workdir", "/build/work", "^kernel-image-rt$", "basesystem", "make-initrd", ], ), ] ); } #[test] fn package_request_rejects_empty_packages_and_unsafe_apt_config_paths() { assert!(AptConfig::new("").is_err()); assert!( PackageRequest::new( PathBuf::from("work"), AptConfig::new("profiles/apt.conf").expect("valid apt config"), ["basesystem", ""], std::iter::empty::<&str>(), ) .is_err() ); } #[test] fn build_plan_compiles_its_typed_package_request() { let spec = ImageSpec::load(std::path::Path::new("profiles/alt-controller.toml")) .expect("load controller spec"); let plan = BuildPlan::compile(spec).expect("compile controller plan"); let request = plan .package_request("work/alt-controller", "profiles/apt.conf") .expect("compile package request"); assert_eq!( request.workdir(), std::path::Path::new("work/alt-controller") ); assert_eq!( request.apt_config().as_path(), std::path::Path::new("profiles/apt.conf") ); assert_eq!(request.packages()[0], "anacron"); assert!(request.packages().contains(&"apt".to_owned())); assert!(request.packages().contains(&"libiec61850".to_owned())); assert!( request .packages() .contains(&"make-initrd-multipath".to_owned()) ); assert_eq!(request.selectors(), ["^kernel-(image|modules-())-(rt)$"]); } #[test] fn sudo_user_runner_executes_hasher_commands_as_the_configured_user() { let runner = alt_controller_image::hasher::SudoUserRunner::new("hermes"); let invocation = runner.wrap(Invocation::new("hsh", ["--version"])); assert_eq!( invocation, Invocation::new("sudo", ["-n", "-u", "hermes", "hsh", "--version"]) ); let preparation = runner.prepare_workdir(std::path::Path::new("/build/work")); assert_eq!( preparation, Invocation::new( "sudo", [ "-n", "install", "-d", "-o", "hermes", "-g", "hermes", "/build/work" ] ) ); }