#[test]
fn test_cb1000_no_model_files_empty() {
let temp = TempDir::new().unwrap();
let violations = detect_cb1000_missing_model_card(temp.path());
assert!(violations.is_empty());
}
#[test]
fn test_cb1000_detects_missing_model_card() {
let temp = TempDir::new().unwrap();
let models_dir = temp.path().join("models");
fs::create_dir_all(&models_dir).unwrap();
let mut gguf_header = vec![0x47u8, 0x47, 0x55, 0x46]; gguf_header.extend_from_slice(&3u32.to_le_bytes()); gguf_header.extend_from_slice(&10u64.to_le_bytes()); gguf_header.extend_from_slice(&5u64.to_le_bytes()); gguf_header.resize(64, 0);
fs::write(models_dir.join("model.gguf"), &gguf_header).unwrap();
let violations = detect_cb1000_missing_model_card(temp.path());
assert_eq!(violations.len(), 1);
assert_eq!(violations[0].pattern_id, "CB-1000");
}
#[test]
fn test_cb1000_passes_with_readme() {
let temp = TempDir::new().unwrap();
let models_dir = temp.path().join("models");
fs::create_dir_all(&models_dir).unwrap();
fs::write(
models_dir.join("model.gguf"),
[0x47, 0x47, 0x55, 0x46, 0, 0, 0, 0],
)
.unwrap();
fs::write(models_dir.join("README.md"), "# Model Card\n").unwrap();
let violations = detect_cb1000_missing_model_card(temp.path());
assert!(violations.is_empty());
}
#[test]
fn test_cb1001_detects_oversized_tensor_count() {
let temp = TempDir::new().unwrap();
let mut header = vec![0x47u8, 0x47, 0x55, 0x46]; header.extend_from_slice(&3u32.to_le_bytes()); header.extend_from_slice(&200_000u64.to_le_bytes()); header.extend_from_slice(&0u64.to_le_bytes()); header.resize(64, 0);
fs::write(temp.path().join("bad.gguf"), &header).unwrap();
let violations = detect_cb1001_oversized_tensor_count(temp.path());
assert_eq!(violations.len(), 1);
assert_eq!(violations[0].pattern_id, "CB-1001");
assert!(matches!(violations[0].severity, Severity::Error));
}
#[test]
fn test_cb1001_passes_normal_tensor_count() {
let temp = TempDir::new().unwrap();
let mut header = vec![0x47u8, 0x47, 0x55, 0x46]; header.extend_from_slice(&3u32.to_le_bytes()); header.extend_from_slice(&500u64.to_le_bytes()); header.extend_from_slice(&10u64.to_le_bytes()); header.resize(64, 0);
fs::write(temp.path().join("good.gguf"), &header).unwrap();
let violations = detect_cb1001_oversized_tensor_count(temp.path());
assert!(violations.is_empty());
}
#[test]
fn test_cb1006_detects_sharded_without_index() {
let temp = TempDir::new().unwrap();
let json_header = b"{\"tensor\":{\"dtype\":\"F32\",\"shape\":[1],\"data_offsets\":[0,4]}}";
let header_len = json_header.len() as u64;
let mut data = Vec::new();
data.extend_from_slice(&header_len.to_le_bytes());
data.extend_from_slice(json_header);
data.extend_from_slice(&[0u8; 4]);
fs::write(temp.path().join("model-00001-of-00002.safetensors"), &data).unwrap();
fs::write(temp.path().join("model-00002-of-00002.safetensors"), &data).unwrap();
let violations = detect_cb1006_sharded_without_index(temp.path());
assert_eq!(violations.len(), 1);
assert_eq!(violations[0].pattern_id, "CB-1006");
}
#[test]
fn test_cb1006_passes_with_index() {
let temp = TempDir::new().unwrap();
let json_header = b"{\"tensor\":{\"dtype\":\"F32\",\"shape\":[1],\"data_offsets\":[0,4]}}";
let header_len = json_header.len() as u64;
let mut data = Vec::new();
data.extend_from_slice(&header_len.to_le_bytes());
data.extend_from_slice(json_header);
data.extend_from_slice(&[0u8; 4]);
fs::write(temp.path().join("model-00001-of-00002.safetensors"), &data).unwrap();
fs::write(temp.path().join("model-00002-of-00002.safetensors"), &data).unwrap();
fs::write(temp.path().join("model.safetensors.index.json"), "{}").unwrap();
let violations = detect_cb1006_sharded_without_index(temp.path());
assert!(violations.is_empty());
}
#[test]
fn test_cb1007_detects_large_file() {
let temp = TempDir::new().unwrap();
fs::write(temp.path().join("small.gguf"), [0u8; 100]).unwrap();
let violations = detect_cb1007_excessive_file_size(temp.path());
assert!(violations.is_empty());
}
#[test]
fn test_walkdir_model_files() {
let temp = TempDir::new().unwrap();
fs::write(temp.path().join("model.gguf"), [0u8; 16]).unwrap();
fs::write(temp.path().join("weights.safetensors"), [0u8; 16]).unwrap();
fs::write(temp.path().join("model.apr"), [0u8; 16]).unwrap();
fs::write(temp.path().join("code.rs"), "fn main() {}").unwrap();
let files = walkdir_model_files(temp.path());
assert_eq!(files.len(), 3);
}
#[test]
fn test_model_format_from_extension() {
assert_eq!(ModelFormat::from_extension("gguf"), Some(ModelFormat::Gguf));
assert_eq!(ModelFormat::from_extension("apr"), Some(ModelFormat::Apr));
assert_eq!(
ModelFormat::from_extension("safetensors"),
Some(ModelFormat::SafeTensors)
);
assert_eq!(ModelFormat::from_extension("rs"), None);
}
#[test]
fn test_cb1004_detects_missing_architecture() {
let temp = TempDir::new().unwrap();
let mut header = vec![0x47u8, 0x47, 0x55, 0x46]; header.extend_from_slice(&3u32.to_le_bytes()); header.extend_from_slice(&10u64.to_le_bytes()); header.extend_from_slice(&0u64.to_le_bytes()); header.resize(200, 0); fs::write(temp.path().join("model.gguf"), &header).unwrap();
let violations = detect_cb1004_missing_architecture(temp.path());
assert_eq!(violations.len(), 1);
assert_eq!(violations[0].pattern_id, "CB-1004");
}
#[test]
fn test_cb1004_passes_with_architecture() {
let temp = TempDir::new().unwrap();
let mut header = vec![0x47u8, 0x47, 0x55, 0x46]; header.extend_from_slice(&3u32.to_le_bytes());
header.extend_from_slice(&10u64.to_le_bytes());
header.extend_from_slice(&1u64.to_le_bytes()); header.extend_from_slice(b"general.architecture");
header.resize(200, 0);
fs::write(temp.path().join("model.gguf"), &header).unwrap();
let violations = detect_cb1004_missing_architecture(temp.path());
assert_eq!(violations.len(), 0);
}
#[test]
fn test_cb1005_detects_size_mismatch() {
let temp = TempDir::new().unwrap();
let mut header = vec![0x47u8, 0x47, 0x55, 0x46];
header.extend_from_slice(&3u32.to_le_bytes());
header.extend_from_slice(&10u64.to_le_bytes());
header.extend_from_slice(&0u64.to_le_bytes());
fs::write(temp.path().join("model-f32.gguf"), &header).unwrap();
let violations = detect_cb1005_quantization_mismatch(temp.path());
assert_eq!(violations.len(), 1);
assert_eq!(violations[0].pattern_id, "CB-1005");
}
#[test]
fn test_truncated_gguf_is_not_a_valid_header() {
let temp = TempDir::new().unwrap();
let mut bytes = b"GGUF".to_vec();
bytes.extend_from_slice(&3u32.to_le_bytes());
assert_eq!(
bytes.len(),
8,
"fixture must be shorter than GGUF's 24-byte header"
);
let path = temp.path().join("truncated.gguf");
fs::write(&path, &bytes).unwrap();
assert!(
!model_header_matches_extension(&path),
"an 8-byte GGUF has no tensor count to read; it must not validate"
);
}
#[test]
fn test_minimal_complete_gguf_is_still_valid() {
let temp = TempDir::new().unwrap();
let mut bytes = b"GGUF".to_vec();
bytes.extend_from_slice(&3u32.to_le_bytes());
bytes.extend_from_slice(&2u64.to_le_bytes());
bytes.extend_from_slice(&1u64.to_le_bytes());
assert_eq!(bytes.len(), 24);
let path = temp.path().join("minimal.gguf");
fs::write(&path, &bytes).unwrap();
assert!(model_header_matches_extension(&path));
}
#[test]
fn test_safetensors_header_running_past_eof_is_not_valid() {
let temp = TempDir::new().unwrap();
let mut bytes = Vec::new();
bytes.extend_from_slice(&1000u64.to_le_bytes());
let path = temp.path().join("truncated.safetensors");
fs::write(&path, &bytes).unwrap();
assert!(
!model_header_matches_extension(&path),
"an 8-byte file declaring a 1000-byte header is truncated, not valid"
);
}
#[test]
fn test_safetensors_header_that_is_not_json_is_not_valid() {
let temp = TempDir::new().unwrap();
let junk = b"abcdefghij";
let mut bytes = (junk.len() as u64).to_le_bytes().to_vec();
bytes.extend_from_slice(junk);
bytes.extend_from_slice(&[0u8; 8]);
let path = temp.path().join("notjson.safetensors");
fs::write(&path, &bytes).unwrap();
assert!(
!model_header_matches_extension(&path),
"a SafeTensors header must be a JSON object"
);
}
#[test]
fn test_well_formed_safetensors_is_valid() {
let temp = TempDir::new().unwrap();
let json = br#"{"w":{"dtype":"F32","shape":[2],"data_offsets":[0,8]}}"#;
let mut bytes = (json.len() as u64).to_le_bytes().to_vec();
bytes.extend_from_slice(json);
bytes.extend_from_slice(&[0u8; 8]);
let path = temp.path().join("good.safetensors");
fs::write(&path, &bytes).unwrap();
assert!(model_header_matches_extension(&path));
}
#[test]
fn test_apr_with_absurd_metadata_length_is_not_valid() {
let temp = TempDir::new().unwrap();
let mut bytes = b"APR2".to_vec();
bytes.extend_from_slice(&u32::MAX.to_le_bytes());
let path = temp.path().join("absurd.apr");
fs::write(&path, &bytes).unwrap();
assert!(
!model_header_matches_extension(&path),
"an 8-byte APR claiming a 4 GiB metadata block must not validate"
);
}
#[test]
fn test_text_file_beginning_with_apr_is_not_valid() {
let temp = TempDir::new().unwrap();
let path = temp.path().join("notes.apr");
fs::write(
&path,
b"APRIL notes on the model serialization container format",
)
.unwrap();
assert!(
!model_header_matches_extension(&path),
"prose beginning with \"APR\" is not an APR container"
);
}
#[test]
fn test_well_formed_apr_is_valid() {
let temp = TempDir::new().unwrap();
let json = br#"{"tensors":[{"name":"w","dtype":"f32"}]}"#;
let mut bytes = b"APR2".to_vec();
bytes.extend_from_slice(&(json.len() as u32).to_le_bytes());
bytes.extend_from_slice(json);
bytes.extend_from_slice(&[0u8; 8]);
let path = temp.path().join("good.apr");
fs::write(&path, &bytes).unwrap();
assert!(model_header_matches_extension(&path));
}