#![allow(clippy::unwrap_used, clippy::expect_used)]
use apfs_core::volume::{ApfsVolume, APFS_MAGIC};
const FSTREE: &[u8] = include_bytes!("../../tests/data/apfs_fstree.bin");
const BLOCK_SIZE: usize = 4096;
fn block(idx: usize) -> &'static [u8] {
&FSTREE[idx * BLOCK_SIZE..(idx + 1) * BLOCK_SIZE]
}
#[test]
fn parse_apsb_magic_and_tree_oids() {
let v = ApfsVolume::parse(block(371)).expect("parse APSB");
assert_eq!(APFS_MAGIC, 0x4253_5041);
assert_eq!(v.omap_oid(), 366);
assert_eq!(v.root_tree_oid(), 1028);
}
#[test]
fn parse_apsb_name_and_role() {
let v = ApfsVolume::parse(block(371)).expect("parse APSB");
assert_eq!(v.name(), "APFSP3");
}
#[test]
fn parse_apsb_fs_index() {
let v = ApfsVolume::parse(block(371)).expect("parse APSB");
assert_eq!(v.fs_index(), 0);
}
#[test]
fn parse_apsb_rejects_wrong_magic() {
let mut b = block(371).to_vec();
b[32..36].copy_from_slice(b"XXXX");
let cks = apfs_core::object::fletcher64_checksum(&b);
b[0..8].copy_from_slice(&cks.to_le_bytes());
match ApfsVolume::parse(&b) {
Err(apfs_core::ApfsError::UnexpectedObjectType { found, .. }) => {
assert_eq!(found, u32::from_le_bytes(*b"XXXX"));
}
other => panic!("expected UnexpectedObjectType, got {other:?}"),
}
}
#[test]
fn parse_apsb_rejects_checksum_mismatch() {
let mut b = block(371).to_vec();
b[200] ^= 0xff;
match ApfsVolume::parse(&b) {
Err(apfs_core::ApfsError::ChecksumMismatch { .. }) => {}
other => panic!("expected ChecksumMismatch, got {other:?}"),
}
}
#[test]
fn parse_apsb_rejects_short_block() {
assert!(ApfsVolume::parse(&[0u8; 16]).is_err());
}
#[test]
fn parse_apsb_rejects_wrong_object_type() {
let mut b = block(371).to_vec();
let mut ot = u32::from_le_bytes(b[24..28].try_into().unwrap());
ot = (ot & 0xffff_0000) | 0x000b;
b[24..28].copy_from_slice(&ot.to_le_bytes());
let cks = apfs_core::object::fletcher64_checksum(&b);
b[0..8].copy_from_slice(&cks.to_le_bytes());
match ApfsVolume::parse(&b) {
Err(apfs_core::ApfsError::UnexpectedObjectType { found, .. }) => {
assert_eq!(found, ot);
}
other => panic!("expected UnexpectedObjectType, got {other:?}"),
}
}
#[test]
fn apsb_accessors_expose_all_fields() {
let v = ApfsVolume::parse(block(371)).expect("parse APSB");
assert_eq!(v.oid(), 1026); assert_eq!(v.xid(), 6); assert_eq!(v.features(), 2); assert_eq!(v.readonly_compatible_features(), 0);
assert_eq!(v.incompatible_features(), 1); assert_eq!(v.root_tree_type(), 0x2); assert_eq!(v.extentref_tree_oid(), 357); assert_eq!(v.snap_meta_tree_oid(), 340); assert_ne!(v.uuid(), [0u8; 16]);
let _ = v.fs_flags();
}