pub(crate) use super::*;
pub(super) fn create_gguf_header(tensor_count: u64, metadata_count: u64) -> Vec<u8> {
let mut data = Vec::new();
data.extend_from_slice(&GGUF_MAGIC.to_le_bytes());
data.extend_from_slice(&3u32.to_le_bytes());
data.extend_from_slice(&tensor_count.to_le_bytes());
data.extend_from_slice(&metadata_count.to_le_bytes());
data
}
#[test]
fn test_bug_gguf_001_excessive_tensor_count_rejected() {
let data = create_gguf_header(MAX_TENSOR_COUNT + 1, 0);
let result = GgufReader::from_bytes(data);
assert!(
result.is_err(),
"FALSIFIED: Excessive tensor_count should be rejected"
);
let err = format!("{:?}", result.unwrap_err());
assert!(
err.contains("exceeds maximum"),
"Error should mention limit: {err}"
);
}
#[test]
fn test_bug_gguf_001_excessive_metadata_count_rejected() {
let data = create_gguf_header(1, MAX_METADATA_COUNT + 1);
let result = GgufReader::from_bytes(data);
assert!(
result.is_err(),
"FALSIFIED: Excessive metadata_kv_count should be rejected"
);
let err = format!("{:?}", result.unwrap_err());
assert!(
err.contains("exceeds maximum"),
"Error should mention limit: {err}"
);
}
#[test]
fn test_bug_gguf_001_max_tensor_count_allowed() {
let data = create_gguf_header(MAX_TENSOR_COUNT, 0);
let result = GgufReader::from_bytes(data);
match result {
Err(e) => {
let err = format!("{e:?}");
assert!(
!err.contains("tensor_count") || !err.contains("exceeds"),
"MAX_TENSOR_COUNT should be accepted: {err}"
);
}
Ok(_) => {
}
}
}
#[test]
fn test_bug_gguf_001_zero_counts_valid() {
let data = create_gguf_header(0, 0);
let result = GgufReader::from_bytes(data);
match result {
Err(e) => {
let err = format!("{e:?}");
assert!(
!err.contains("exceeds maximum"),
"Zero counts should be valid: {err}"
);
}
Ok(_) => {
}
}
}
#[test]
fn test_bug_gguf_002_overflow_protection_documented() {
assert!(MAX_TENSOR_ELEMENTS == 4_000_000_000);
}
#[test]
fn test_read_metadata_value_uint64() {
let val: u64 = 0x_DEAD_BEEF_CAFE_BABE;
let bytes = val.to_le_bytes();
let (result, consumed) = read_metadata_value(&bytes, 0, 10).expect("read uint64");
assert_eq!(consumed, 8);
match result {
GgufValue::Uint64(v) => assert_eq!(v, val),
other => panic!("Expected Uint64, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_int64() {
let val: i64 = -123_456_789_012_345;
let bytes = val.to_le_bytes();
let (result, consumed) = read_metadata_value(&bytes, 0, 11).expect("read int64");
assert_eq!(consumed, 8);
match result {
GgufValue::Int64(v) => assert_eq!(v, val),
other => panic!("Expected Int64, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_float64() {
let val: f64 = std::f64::consts::PI;
let bytes = val.to_le_bytes();
let (result, consumed) = read_metadata_value(&bytes, 0, 12).expect("read float64");
assert_eq!(consumed, 8);
match result {
GgufValue::Float64(v) => assert!((v - val).abs() < f64::EPSILON),
other => panic!("Expected Float64, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_unknown_type() {
let bytes = [0u8; 8];
let (result, consumed) = read_metadata_value(&bytes, 0, 99).expect("read unknown");
assert_eq!(consumed, 4);
match result {
GgufValue::Uint32(v) => assert_eq!(v, 0),
other => panic!("Expected Uint32(0) for unknown type, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_uint8() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&0u32.to_le_bytes()); bytes.extend_from_slice(&3u64.to_le_bytes()); bytes.extend_from_slice(&[10u8, 20u8, 30u8]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array uint8");
assert_eq!(consumed, 15);
match result {
GgufValue::ArrayUint32(v) => {
assert!(v.is_empty(), "Other-type arrays return empty vec")
}
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_uint16() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&2u32.to_le_bytes()); bytes.extend_from_slice(&2u64.to_le_bytes()); bytes.extend_from_slice(&[0u8; 4]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array uint16");
assert_eq!(consumed, 16); match result {
GgufValue::ArrayUint32(v) => assert!(v.is_empty()),
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_uint64() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&10u32.to_le_bytes()); bytes.extend_from_slice(&2u64.to_le_bytes()); bytes.extend_from_slice(&[0u8; 16]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array uint64");
assert_eq!(consumed, 28); match result {
GgufValue::ArrayUint32(v) => assert!(v.is_empty()),
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_int64() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&11u32.to_le_bytes()); bytes.extend_from_slice(&1u64.to_le_bytes()); bytes.extend_from_slice(&[0u8; 8]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array int64");
assert_eq!(consumed, 20); match result {
GgufValue::ArrayUint32(v) => assert!(v.is_empty()),
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_float64() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&12u32.to_le_bytes()); bytes.extend_from_slice(&1u64.to_le_bytes()); bytes.extend_from_slice(&[0u8; 8]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array float64");
assert_eq!(consumed, 20); match result {
GgufValue::ArrayUint32(v) => assert!(v.is_empty()),
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_bool() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&7u32.to_le_bytes()); bytes.extend_from_slice(&4u64.to_le_bytes()); bytes.extend_from_slice(&[1u8, 0u8, 1u8, 0u8]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array bool");
assert_eq!(consumed, 16); match result {
GgufValue::ArrayUint32(v) => assert!(v.is_empty()),
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_other_type_default() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&99u32.to_le_bytes()); bytes.extend_from_slice(&2u64.to_le_bytes()); bytes.extend_from_slice(&[0u8; 8]); let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array unknown");
assert_eq!(consumed, 20); match result {
GgufValue::ArrayUint32(v) => assert!(v.is_empty()),
other => panic!("Expected empty ArrayUint32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_array_int32() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&5u32.to_le_bytes()); bytes.extend_from_slice(&3u64.to_le_bytes()); bytes.extend_from_slice(&(-10i32).to_le_bytes());
bytes.extend_from_slice(&0i32.to_le_bytes());
bytes.extend_from_slice(&42i32.to_le_bytes());
let (result, consumed) = read_metadata_value(&bytes, 0, 9).expect("read array int32");
assert_eq!(consumed, 24); match result {
GgufValue::ArrayInt32(v) => {
assert_eq!(v, vec![-10, 0, 42]);
}
other => panic!("Expected ArrayInt32, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_int64_eof() {
let bytes = [0u8; 4]; let result = read_metadata_value(&bytes, 0, 11);
assert!(result.is_err(), "Int64 with < 8 bytes should fail");
}
#[test]
fn test_read_metadata_value_float64_eof() {
let bytes = [0u8; 5]; let result = read_metadata_value(&bytes, 0, 12);
assert!(result.is_err(), "Float64 with < 8 bytes should fail");
}
#[test]
fn test_read_metadata_value_uint8() {
let bytes = [42u8];
let (result, consumed) = read_metadata_value(&bytes, 0, 0).expect("read uint8");
assert_eq!(consumed, 1);
match result {
GgufValue::Uint8(v) => assert_eq!(v, 42),
other => panic!("Expected Uint8, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_int8() {
let bytes = [0xFEu8]; let (result, consumed) = read_metadata_value(&bytes, 0, 1).expect("read int8");
assert_eq!(consumed, 1);
match result {
GgufValue::Int8(v) => assert_eq!(v, -2),
other => panic!("Expected Int8, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_uint16() {
let bytes = 1000u16.to_le_bytes();
let (result, consumed) = read_metadata_value(&bytes, 0, 2).expect("read uint16");
assert_eq!(consumed, 2);
match result {
GgufValue::Uint16(v) => assert_eq!(v, 1000),
other => panic!("Expected Uint16, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_int16() {
let bytes = (-500i16).to_le_bytes();
let (result, consumed) = read_metadata_value(&bytes, 0, 3).expect("read int16");
assert_eq!(consumed, 2);
match result {
GgufValue::Int16(v) => assert_eq!(v, -500),
other => panic!("Expected Int16, got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_bool_true() {
let bytes = [1u8];
let (result, consumed) = read_metadata_value(&bytes, 0, 7).expect("read bool");
assert_eq!(consumed, 1);
match result {
GgufValue::Bool(v) => assert!(v),
other => panic!("Expected Bool(true), got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_bool_false() {
let bytes = [0u8];
let (result, consumed) = read_metadata_value(&bytes, 0, 7).expect("read bool");
assert_eq!(consumed, 1);
match result {
GgufValue::Bool(v) => assert!(!v),
other => panic!("Expected Bool(false), got {other:?}"),
}
}
#[test]
fn test_read_metadata_value_with_offset() {
let mut bytes = vec![0u8; 10]; bytes.extend_from_slice(&42u64.to_le_bytes());
let (result, consumed) = read_metadata_value(&bytes, 10, 10).expect("read uint64 at offset");
assert_eq!(consumed, 8);
match result {
GgufValue::Uint64(v) => assert_eq!(v, 42),
other => panic!("Expected Uint64, got {other:?}"),
}
}
#[test]
fn test_from_bytes_file_too_small() {
let data = vec![0u8; 10]; let result = GgufReader::from_bytes(data);
assert!(result.is_err());
let err = format!("{:?}", result.unwrap_err());
assert!(
err.contains("too small"),
"Error should mention 'too small': {err}"
);
}
#[test]
fn test_from_bytes_file_exactly_23_bytes() {
let data = vec![0u8; 23]; let result = GgufReader::from_bytes(data);
assert!(result.is_err());
}
#[test]
fn test_from_bytes_invalid_magic() {
let mut data = vec![0u8; 24];
data[0] = b'X';
data[1] = b'X';
data[2] = b'X';
data[3] = b'X';
let result = GgufReader::from_bytes(data);
assert!(result.is_err());
let err = format!("{:?}", result.unwrap_err());
assert!(
err.contains("Invalid GGUF magic"),
"Error should mention invalid magic: {err}"
);
assert!(
err.contains("0x") || err.contains("ascii"),
"Error should include hex/ascii debug info: {err}"
);
}
#[path = "builder.rs"]
mod builder;
#[path = "reader_tests_accessors.rs"]
mod reader_tests_accessors;