]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
ci(cpio): add test_archive_dev_maj_min
authorDavid Disseldorp <ddiss@suse.de>
Thu, 10 Feb 2022 17:05:21 +0000 (18:05 +0100)
committerJóhann B. Guðmundsson <johannbg@gmail.com>
Thu, 17 Feb 2022 19:28:33 +0000 (19:28 +0000)
This tests dracut-cpio's handling of rmajor / rminor values compared to
GNU cpio. The test requires root, due to mknod invocation for block
device node creation.

Signed-off-by: David Disseldorp <ddiss@suse.de>
src/dracut-cpio/src/main.rs

index b3cc5144eddf58ac76062575d9db0a0a79a1b2a1..a1994b96fc98c97597beef736c248f2a6bf86e96 100644 (file)
@@ -810,7 +810,8 @@ fn main() -> std::io::Result<()> {
     Ok(())
 }
 
-// tests change working directory, so need to be run with --test-threads=1
+// tests change working directory, so need to be run with:
+// cargo test -- --test-threads=1 --nocapture
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -1733,4 +1734,77 @@ mod tests {
         assert_eq!(src_md.uid(), ex_md.uid());
         assert_eq!(src_md.gid(), ex_md.gid());
     }
+
+    #[test]
+    fn test_archive_dev_maj_min() {
+        let mut twd = TempWorkDir::new();
+        twd.create_tmp_file("file1", 0);
+
+        let md = fs::symlink_metadata("file1").unwrap();
+        if md.uid() != 0 {
+            println!("SKIPPED: this test requires root");
+            return;
+        }
+
+        twd.create_tmp_mknod("bdev1", 'b', Some((0x01, 0x01)));
+        twd.create_tmp_mknod("bdev2", 'b', Some((0x02, 0x100)));
+        twd.create_tmp_mknod("bdev3", 'b', Some((0x03, 0x1000)));
+        twd.create_tmp_mknod("bdev4", 'b', Some((0x04, 0x10000)));
+        twd.create_tmp_mknod("bdev5", 'b', Some((0x100, 0x05)));
+        twd.create_tmp_mknod("bdev6", 'b', Some((0x100, 0x06)));
+        let file_list: &str = "file1\nbdev1\nbdev2\nbdev3\nbdev4\nbdev5\nbdev6\n";
+
+        // create GNU cpio archive
+        twd.create_tmp_dir("gnucpio_xtr");
+        gnu_cpio_create(file_list.as_bytes(), "gnucpio_xtr/gnu.cpio");
+        twd.cleanup_files.push(PathBuf::from("gnucpio_xtr/gnu.cpio"));
+
+        // create Dracut cpio archive
+        twd.create_tmp_dir("dracut_xtr");
+        let f = fs::File::create("dracut_xtr/dracut.cpio").unwrap();
+        let mut writer = io::BufWriter::new(f);
+        let mut reader = io::BufReader::new(file_list.as_bytes());
+        let wrote = archive_loop(
+            &mut reader,
+            &mut writer,
+            &ArchiveProperties::default()
+        )
+        .unwrap();
+        twd.cleanup_files.push(PathBuf::from("dracut_xtr/dracut.cpio"));
+
+        let file_list_count = file_list.split_terminator('\n').count() as u64;
+        assert!(wrote >= NEWC_HDR_LEN * file_list_count
+                         + (file_list.len() as u64));
+
+        let status = Command::new("cpio")
+            .current_dir("gnucpio_xtr")
+            .args(&["--quiet", "-i", "-H", "newc", "-F", "gnu.cpio"])
+            .status()
+            .expect("GNU cpio failed to start");
+        assert!(status.success());
+        for s in file_list.split_terminator('\n') {
+            let p = PathBuf::from("gnucpio_xtr/".to_owned() + s);
+            twd.cleanup_files.push(p);
+        }
+
+        let status = Command::new("cpio")
+            .current_dir("dracut_xtr")
+            .args(&["--quiet", "-i", "-H", "newc", "-F", "dracut.cpio"])
+            .status()
+            .expect("GNU cpio failed to start");
+        assert!(status.success());
+        for s in file_list.split_terminator('\n') {
+            let dp = PathBuf::from("dracut_xtr/".to_owned() + s);
+            twd.cleanup_files.push(dp);
+        }
+
+        // diff extracted major/minor between dracut and GNU cpio created archives
+        for s in file_list.split_terminator('\n') {
+            let gmd = fs::symlink_metadata("gnucpio_xtr/".to_owned() + s).unwrap();
+            let dmd = fs::symlink_metadata("dracut_xtr/".to_owned() + s).unwrap();
+            print!("{}: cpio extracted dev_t gnu: {:#x}, dracut: {:#x}\n",
+                   s, gmd.rdev(), dmd.rdev());
+            assert!(gmd.rdev() == dmd.rdev());
+        }
+    }
 }