zipfuse: supports zip on block device
Add a test case to ensure that zipfuse works with a block device whose
content is backed by a zip file. Fortunately, zip-rs already supports
reading a zip file from a block device: it locates the end of central
directory record by reverse-scanning a file from the end.
Bug: 186377508
Test: cargo test (android test missing because we don't have the
loopdevice crate for Android, which is fine)
Change-Id: I8fbbfd18a2a0df2a550e3f679ba74ba603b59efd
diff --git a/zipfuse/src/main.rs b/zipfuse/src/main.rs
index 21f7f9c..12c891c 100644
--- a/zipfuse/src/main.rs
+++ b/zipfuse/src/main.rs
@@ -633,14 +633,8 @@
);
}
- #[test]
- fn supports_deflate() {
- let test_dir = tempfile::TempDir::new().unwrap();
- let zip_path = test_dir.path().join("test.zip");
- let mut zip_file = File::create(&zip_path).unwrap();
- zip_file.write_all(include_bytes!("../testdata/test.zip")).unwrap();
-
- let mnt_path = test_dir.path().join("mnt");
+ fn run_fuse_and_check_test_zip(test_dir: &Path, zip_path: &Path) {
+ let mnt_path = test_dir.join("mnt");
assert!(fs::create_dir(&mnt_path).is_ok());
start_fuse(&zip_path, &mnt_path);
@@ -654,4 +648,44 @@
check_file(&mnt_path, "dir/file2", include_bytes!("../testdata/dir/file2"));
assert!(nix::mount::umount2(&mnt_path, nix::mount::MntFlags::empty()).is_ok());
}
+
+ #[test]
+ fn supports_deflate() {
+ let test_dir = tempfile::TempDir::new().unwrap();
+ let zip_path = test_dir.path().join("test.zip");
+ let mut zip_file = File::create(&zip_path).unwrap();
+ zip_file.write_all(include_bytes!("../testdata/test.zip")).unwrap();
+
+ run_fuse_and_check_test_zip(&test_dir.path(), &zip_path);
+ }
+
+ #[cfg(not(target_os = "android"))] // Android doesn't have the loopdev crate
+ #[test]
+ fn supports_zip_on_block_device() {
+ // Write test.zip to the test directory
+ let test_dir = tempfile::TempDir::new().unwrap();
+ let zip_path = test_dir.path().join("test.zip");
+ let mut zip_file = File::create(&zip_path).unwrap();
+ let data = include_bytes!("../testdata/test.zip");
+ zip_file.write_all(data).unwrap();
+
+ // Pad 0 to test.zip so that its size is multiple of 4096.
+ const BLOCK_SIZE: usize = 4096;
+ let size = (data.len() + BLOCK_SIZE) & !BLOCK_SIZE;
+ let pad_size = size - data.len();
+ assert!(pad_size != 0);
+ let pad = vec![0; pad_size];
+ zip_file.write_all(pad.as_slice()).unwrap();
+ drop(zip_file);
+
+ // Attach test.zip to a loop device
+ let lc = loopdev::LoopControl::open().unwrap();
+ let ld = scopeguard::guard(lc.next_free().unwrap(), |ld| {
+ ld.detach().unwrap();
+ });
+ ld.attach_file(&zip_path).unwrap();
+
+ // Start zipfuse over to the loop device (not the zip file)
+ run_fuse_and_check_test_zip(&test_dir.path(), &ld.path().unwrap());
+ }
}