use std::fs;
use std::path::Path;
use std::process::Command;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("๐งช Testing SafeTensors with Real HuggingFace Models");
let test_dir = Path::new("test-real-safetensors");
fs::create_dir_all(test_dir)?;
test_small_model(test_dir)?;
test_memory_intensive_scenarios(test_dir)?;
test_server_mode()?;
println!("โ
All real SafeTensors tests completed");
Ok(())
}
fn test_small_model(_test_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("\n๐ฆ Testing with small real model...");
let cache_paths = vec![
Path::new("C:/Users/micha/.cache/huggingface/hub"),
Path::new("./models"),
Path::new("./test-models"),
];
for cache_path in cache_paths {
if cache_path.exists() {
println!(
"๐ Scanning for SafeTensors models in: {}",
cache_path.display()
);
if let Ok(entries) = fs::read_dir(cache_path) {
for entry in entries.flatten() {
let path = entry.path();
if is_safetensors_directory(&path) {
println!("โ
Found SafeTensors model directory: {}", path.display());
if let Err(e) = test_model_directory(&path) {
println!("โ Failed to test {}: {}", path.display(), e);
}
return Ok(()); }
}
}
}
}
println!("โ ๏ธ No existing SafeTensors models found in cache");
println!("๐ก To test with real models:");
println!(" 1. Use HuggingFace Hub to download a model in SafeTensors format");
println!(" 2. Or manually place SafeTensors files in ./test-models/");
Ok(())
}
fn is_safetensors_directory(dir: &Path) -> bool {
if !dir.is_dir() {
return false;
}
if let Ok(entries) = fs::read_dir(dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("safetensors") {
if dir.join("config.json").exists() {
return true;
}
}
}
}
false
}
fn test_model_directory(model_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("๐งช Testing model directory: {}", model_dir.display());
let model_file = find_main_safetensors_file(model_dir)?;
println!("๐ Found model file: {}", model_file.display());
println!("๐ Testing probe command...");
let output = Command::new("cargo")
.args(["run", "--bin", "shimmy", "--", "discover"])
.output()?;
if !output.status.success() {
println!(
"โ Discover command failed: {}",
String::from_utf8_lossy(&output.stderr)
);
return Ok(()); }
println!("โ
Discover command succeeded");
let discover_output = String::from_utf8_lossy(&output.stdout);
if discover_output.contains("safetensors") {
println!("โ
SafeTensors model found in discovery");
} else {
println!("โ ๏ธ SafeTensors model not found in discovery output");
}
Ok(())
}
fn find_main_safetensors_file(
dir: &Path,
) -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
let entries = fs::read_dir(dir)?;
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("safetensors") {
let filename = path.file_name().and_then(|s| s.to_str()).unwrap_or("");
if filename.contains("model") && !filename.contains("tokenizer") {
return Ok(path);
}
}
}
Err("No SafeTensors model file found".into())
}
fn test_memory_intensive_scenarios(test_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
println!("\n๐ง Testing memory-intensive scenarios...");
let sizes = vec![1, 10, 50, 100];
for size_mb in sizes {
println!("๐ Testing {}MB SafeTensors file...", size_mb);
let test_file = test_dir.join(format!("test-{}.safetensors", size_mb));
if let Err(e) = create_test_safetensors_file(&test_file, size_mb) {
println!("โ ๏ธ Failed to create {}MB test file: {}", size_mb, e);
continue;
}
println!("๐ Testing load performance...");
let start = std::time::Instant::now();
let output = Command::new("cargo")
.args([
"run",
"--bin",
"shimmy",
"--",
"probe",
&format!("test-{}", size_mb),
])
.output();
match output {
Ok(result) => {
let elapsed = start.elapsed();
if result.status.success() {
println!("โ
{}MB model loaded in {:?}", size_mb, elapsed);
} else {
println!(
"โ {}MB model failed to load: {}",
size_mb,
String::from_utf8_lossy(&result.stderr)
);
}
}
Err(e) => {
println!("โ Failed to test {}MB model: {}", size_mb, e);
}
}
let _ = fs::remove_file(&test_file);
}
Ok(())
}
fn test_server_mode() -> Result<(), Box<dyn std::error::Error>> {
println!("\n๐ Testing server mode with SafeTensors...");
println!("๐ Starting server with SafeTensors model...");
let mut server = Command::new("cargo")
.args(["run", "--bin", "shimmy", "--", "serve"])
.spawn()?;
std::thread::sleep(std::time::Duration::from_secs(2));
println!("๐ Testing server health...");
let health_result = Command::new("curl")
.args(["--max-time", "5", "http://127.0.0.1:11435/health"])
.output();
match health_result {
Ok(output) => {
if output.status.success() {
println!("โ
Server responding to health check");
} else {
println!("โ ๏ธ Server health check failed");
}
}
Err(_) => {
println!("โ ๏ธ curl not available or server not responding");
}
}
println!("๐ Stopping server...");
let _ = server.kill();
let _ = server.wait();
Ok(())
}
fn create_test_safetensors_file(
path: &Path,
size_mb: usize,
) -> Result<(), Box<dyn std::error::Error>> {
let tensor_elements = (size_mb * 1024 * 1024) / 4;
let metadata = format!(
r#"{{"test_tensor":{{ "dtype":"F32", "shape":[{},1], "data_offsets":[0,{}] }}}}"#,
tensor_elements,
tensor_elements * 4
);
let metadata_bytes = metadata.as_bytes();
let metadata_len = metadata_bytes.len() as u64;
let mut data = Vec::new();
data.extend_from_slice(&metadata_len.to_le_bytes());
data.extend_from_slice(metadata_bytes);
let tensor_data = vec![1.0f32; tensor_elements];
for value in tensor_data {
data.extend_from_slice(&value.to_le_bytes());
}
fs::write(path, data)?;
Ok(())
}