OXYGENHUB

Coverage / crates/flow/src/cpio.rs 92.3%

36 of 39 lines run, 5 of 8 functions · run #190 on main · run missed

1
//! A minimal `newc` cpio writer for the per-job initramfs: regular files
2
//! at the archive root, owned by root.
3
4
pub struct Entry<'a> {
5
    pub name: &'a str,
6
    pub mode: u32,
7
    pub data: &'a [u8],
8
}
9
103×
fn header(out: &mut Vec<u8>, ino: u32, mode: u32, size: usize, name: &str) {
113×
    let fields = [ino, mode, 0, 0, 1, 0, size as u32, 0, 0, 0, 0, (name.len() + 1) as u32, 0];
123×
    out.extend_from_slice(b"070701");
1339×
    for f in fields {
1439×
        out.extend_from_slice(format!("{f:08X}").as_bytes());
1539×
    }
163×
    out.extend_from_slice(name.as_bytes());
173×
    out.push(0);
183×
    pad(out);
193×
}
20
215×
fn pad(out: &mut Vec<u8>) {
2212×
    while !out.len().is_multiple_of(4) {
237×
        out.push(0);
247×
    }
255×
}
26
271×
pub fn newc(entries: &[Entry]) -> Vec<u8> {
281×
    let mut out = Vec::new();
292×
    for (i, e) in entries.iter().enumerate() {
302×
        header(&mut out, i as u32 + 1, 0o100000 | e.mode, e.data.len(), e.name);
312×
        out.extend_from_slice(e.data);
322×
        pad(&mut out);
332×
    }
341×
    header(&mut out, 0, 0, 0, "TRAILER!!!");
351×
    out
361×
}
37
38
#[cfg(test)]
39
mod tests {
40
    use super::*;
41
42
    #[test]
431×
    fn system_cpio_reads_it() {
441×
        let dir = tempfile::tempdir().unwrap();
451×
        let archive = newc(&[Entry { name: "init", mode: 0o755, data: b"#!x\n" }, Entry { name: "job.json", mode: 0o644, data: b"{}" }]);
461×
        std::fs::write(dir.path().join("a.cpio"), &archive).unwrap();
471×
        let listed = std::process::Command::new("cpio").args(["-it", "--quiet", "-F"]).arg(dir.path().join("a.cpio")).output();
481×
        if let Ok(o) = listed {
490×
            if o.status.success() {
500×
                assert_eq!(String::from_utf8_lossy(&o.stdout), "init\njob.json\n");
510×
            }
521×
        }
531×
        assert!(archive.len().is_multiple_of(4));
54355×
        assert!(archive.windows(10).any(|w| w == b"TRAILER!!!"));
551×
    }
56
}