use super::{required_file_len, AprV2Metadata, AprV2Writer, V2FormatError, HEADER_SIZE_V2};
fn known_good_apr() -> Vec<u8> {
let metadata = AprV2Metadata::new("truncation-fixture");
let mut writer = AprV2Writer::new(metadata);
writer.add_f32_tensor("layer.0.weight", vec![8, 8], &[0.25_f32; 64]);
writer.add_f32_tensor("layer.0.bias", vec![8], &[0.5_f32; 8]);
writer
.write()
.expect("fixture writer must produce a valid .apr")
}
#[test]
fn required_len_of_a_complete_file_fits_inside_it() {
let bytes = known_good_apr();
let required = required_file_len(&bytes).expect("complete .apr must report an extent");
assert!(
required <= bytes.len() as u64,
"a complete .apr must satisfy data_offset + max(offset+size) <= file_length, \
got required={required} file_len={}",
bytes.len()
);
let header = super::AprV2Header::from_bytes(&bytes).expect("header parses");
assert!(
required > header.data_offset,
"required extent {required} must include tensor bytes past data_offset {}",
header.data_offset
);
}
#[test]
fn truncated_file_is_shorter_than_its_own_declared_extent() {
let bytes = known_good_apr();
let required = required_file_len(&bytes).expect("complete .apr must report an extent");
let header = super::AprV2Header::from_bytes(&bytes).expect("header parses");
let cut = header.data_offset as usize + 16;
assert!(
cut < bytes.len(),
"fixture must be longer than the cut point"
);
let truncated = &bytes[..cut];
let required_after =
required_file_len(truncated).expect("truncated .apr still parses its own index");
assert_eq!(
required, required_after,
"the declared extent comes from the index, which the truncation did not touch"
);
assert!(
required_after > truncated.len() as u64,
"truncation must be detectable: required={required_after} file_len={}",
truncated.len()
);
}
#[test]
fn non_apr_v2_buffer_is_an_error_not_a_silent_zero() {
let mut gguf = vec![0u8; HEADER_SIZE_V2 * 2];
gguf[0..4].copy_from_slice(b"GGUF");
assert!(matches!(
required_file_len(&gguf),
Err(V2FormatError::InvalidMagic(_))
));
assert!(required_file_len(&[0u8; 8]).is_err());
}
#[test]
fn index_pointing_past_eof_is_reported_as_a_damaged_index() {
let mut bytes = known_good_apr();
let past_eof = (bytes.len() as u64) + 4096;
bytes[24..32].copy_from_slice(&past_eof.to_le_bytes());
assert!(
matches!(
required_file_len(&bytes),
Err(V2FormatError::InvalidTensorIndex(_))
),
"an index outside the file is damage, not an unknown"
);
}
fn apr_with_unaligned_final_tensor() -> Vec<u8> {
let metadata = AprV2Metadata::new("tail-slack-fixture");
let mut writer = AprV2Writer::new(metadata);
writer.add_f32_tensor("a.weight", vec![8, 8], &[0.25_f32; 64]); writer.add_f32_tensor("z.bias", vec![3], &[0.5_f32; 3]); writer
.write()
.expect("fixture writer must produce a valid .apr")
}
#[test]
fn required_extent_covers_trailing_alignment_padding() {
let bytes = apr_with_unaligned_final_tensor();
let header = super::AprV2Header::from_bytes(&bytes).expect("header parses");
let required = required_file_len(&bytes).expect("extent");
let unpadded_end = header.data_offset + 256 + 12;
let padded_end = header.data_offset + 256 + 64;
assert_eq!(
required, padded_end,
"the extent must reach the end of the final tensor's alignment padding"
);
assert!(
required > unpadded_end,
"the fixture must actually have trailing padding to test \
(required={required}, unpadded_end={unpadded_end})"
);
assert!(required <= bytes.len() as u64);
let cut = usize::try_from(unpadded_end).expect("fits usize") + 4;
assert!(cut < bytes.len());
assert!(
required_file_len(&bytes[..cut]).expect("index survives") > cut as u64,
"a cut inside the trailing padding must be detectable"
);
}
#[test]
fn footer_only_truncation_is_the_disclosed_residual() {
let bytes = apr_with_unaligned_final_tensor();
let required = required_file_len(&bytes).expect("extent");
assert_eq!(
bytes.len() as u64,
required + 4,
"AprV2Writer output is exactly the declared extent plus the 4-byte footer"
);
let footerless = &bytes[..bytes.len() - 4];
assert!(
required_file_len(footerless).expect("index survives") <= footerless.len() as u64,
"known residual: a file missing only its footer is NOT caught by the \
extent check — check 4 (footer CRC32) is the check that would catch it"
);
}