1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
use std::fs;
use std::os::unix::fs::symlink;
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 kernel_discovery_ignores_non_regular_vmlinuz_entries() {
let rootfs = tempdir().expect("rootfs directory");
let boot = rootfs.path().join("boot");
fs::create_dir(&boot).expect("boot directory");
fs::create_dir(boot.join("vmlinuz-6.12-rt-directory")).expect("misleading RT directory");
symlink("/not-a-kernel", boot.join("vmlinuz-6.12-rt-symlink")).expect("misleading RT symlink");
fs::write(boot.join("vmlinuz-6.12-rt-real"), "kernel").expect("RT kernel");
let kernel = KernelVersion::discover_rt(rootfs.path()).expect("discover regular RT kernel");
assert_eq!(kernel.as_str(), "6.12-rt-real");
}
#[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<Invocation>,
}
impl CommandRunner for RecordingRunner {
fn run(&mut self, invocation: Invocation) -> anyhow::Result<()> {
self.invocations.push(invocation);
Ok(())
}
}
|