use btrfs::structs::{ExtentData, ObjectType}; use btrfs::v2::error::Result; use btrfs::v2::tree::PartialKey; use btrfs::v2::volume::*; use include_blob::include_blob; fn open_filesystem() -> Result>> { let filesystem_data = include_blob!("simple.img").as_slice(); let volume = Volume::new(filesystem_data)?.into_volume2()?; Ok(volume) } fn open_filesystem_lzo() -> Result>> { let filesystem_data = include_blob!("compressed-lzo.img").as_slice(); let volume = Volume::new(filesystem_data)?.into_volume2()?; Ok(volume) } fn open_filesystem_zlib() -> Result>> { let filesystem_data = include_blob!("compressed-zlib.img").as_slice(); let volume = Volume::new(filesystem_data)?.into_volume2()?; Ok(volume) } fn open_filesystem_zstd() -> Result>> { let filesystem_data = include_blob!("compressed-zstd.img").as_slice(); let volume = Volume::new(filesystem_data)?.into_volume2()?; Ok(volume) } #[test_log::test] fn asdf() -> Result<()> { let a = open_filesystem()?; Ok(()) } #[test_log::test] fn read_superblock() -> Result<()> { let vol2 = open_filesystem()?; let sb = vol2.inner.superblock(); println!("{sb:#?}"); assert!(sb.verify_magic()); assert!(sb.verify_checksum()); Ok(()) } #[test_log::test] fn iter_roots() -> Result<()> { let vol2 = open_filesystem()?; for (id, _) in vol2.roots.iter() { log::info!("[{id:?}] "); } Ok(()) } #[test_log::test] fn iter_roots_rev() -> Result<()> { let vol2 = open_filesystem()?; for (id, _) in vol2.roots.iter().rev() { log::info!("[{id:?}] "); } Ok(()) } #[test_log::test] fn iter_default_subvol() -> Result<()> { let v2 = open_filesystem()?; let fs = v2.default_subvolume().expect("default subvol"); log::info!("files 1:"); let now = std::time::Instant::now(); for (_id, entry) in fs.fs_root().iter() { if let Some(_dir) = entry.as_dir_index() { //log::info!("{}", dir.name_as_string_lossy()); } } log::info!("files 1: [took {}ms]", now.elapsed().as_millis()); log::info!("files 2:"); let now = std::time::Instant::now(); for (_id, entry) in fs.fs_root().iter() { if let Some(_dir) = entry.as_dir_index() { //log::info!("{}", dir.name_as_string_lossy()); } } log::info!("files 2: [took {}ms]", now.elapsed().as_millis()); Ok(()) } #[test_log::test] fn get_inode_items() -> Result<()> { let v2 = open_filesystem()?; let fs = v2.default_subvolume().expect("default subvol"); let search_key = PartialKey::new(fs.root_dir_id(), Some(ObjectType::DirIndex), None); // with range log::info!("range:"); for (key, v) in fs.fs_root().find_range(&search_key)? { let dirindex = v.as_dir_index().unwrap(); let inode_id: u64 = dirindex.item().location.id().into(); log::info!("[{key:?}] {v:#?}"); log::info!("inode: {inode_id}"); let inode_item = fs.get_inode_item(inode_id)?; log::info!("inode: {inode_item:#?}"); let extents = fs.get_inode_extents(inode_id)?; for (_, extent) in extents { match extent { ExtentData::Inline { header, data } => { log::info!("{header:?}\n{}", String::from_utf8_lossy(&data)); } _ => {} } } } log::info!("range: [end]"); Ok(()) } #[test_log::test] fn find_file() -> Result<()> { let v2 = open_filesystem()?; let fs = v2.default_subvolume().expect("default subvol"); let root_dir = fs.get_root_dir(); let children = fs.get_inode_children(&root_dir)?.collect::>(); log::info!("chidlren: {:?}", children); let cmake_list = fs.get_inode_by_path(b"/quibble/LICENCE")?; let file_contents = fs.read_inode_raw(&cmake_list, ..).expect("file contents"); assert_eq!( &file_contents[..52], b" GNU LESSER GENERAL PUBLIC LICENSE" ); log::info!("license file:"); log::info!("{}", String::from_utf8_lossy(&file_contents)); Ok(()) } #[test_log::test] fn find_file_zlib() -> Result<()> { let v2 = open_filesystem_zlib()?; let fs = v2.default_subvolume().expect("default subvol"); let root_dir = fs.get_root_dir(); let children = fs.get_inode_children(&root_dir)?.collect::>(); log::info!("chidlren: {:?}", children); let cmake_list = fs.get_inode_by_path(b"/quibble/LICENCE")?; let file_contents = fs .read_inode_raw(&cmake_list, ..100) .expect("file contents"); //assert_eq!(&file_contents[..11], b"hello world"); log::info!("license file:"); log::info!("{}", String::from_utf8_lossy(&file_contents)); assert_eq!( &file_contents[..52], b" GNU LESSER GENERAL PUBLIC LICENSE" ); Ok(()) } #[test_log::test] fn find_file_lzo() -> Result<()> { let v2 = open_filesystem_lzo()?; let fs = v2.default_subvolume().expect("default subvol"); let root_dir = fs.get_root_dir(); let children = fs.get_inode_children(&root_dir)?.collect::>(); log::info!("chidlren: {:?}", children); let cmake_list = fs.get_inode_by_path(b"/quibble/LICENCE")?; let file_contents = fs.read_inode_raw(&cmake_list, ..).expect("file contents"); assert_eq!( &file_contents[..52], b" GNU LESSER GENERAL PUBLIC LICENSE" ); log::info!("license file:"); log::info!("{}", String::from_utf8_lossy(&file_contents)); Ok(()) } #[test_log::test] fn find_file_zstd() -> Result<()> { let v2 = open_filesystem_zstd()?; let fs = v2.default_subvolume().expect("default subvol"); let root_dir = fs.get_root_dir(); let children = fs.get_inode_children(&root_dir)?.collect::>(); log::info!("chidlren: {:?}", children); let cmake_list = fs.get_inode_by_path(b"/quibble/LICENCE")?; let file_contents = fs .read_inode_raw(&cmake_list, ..100) .expect("file contents"); assert_eq!( &file_contents[..52], b" GNU LESSER GENERAL PUBLIC LICENSE" ); log::info!("license file:"); log::info!("{}", String::from_utf8_lossy(&file_contents)); Ok(()) }