use native_neural_network_std::benchmark;
use native_neural_network_std::parser;
use std::fs;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
fn temp_formats_dir() -> PathBuf {
let mut dir = std::env::temp_dir();
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0);
dir.push(format!("nns_formats_{}_{}", std::process::id(), nanos));
dir
}
#[test]
fn parser_json_csv_yaml_smoke() {
let json = parser::json::parse_json(br#"{"name":"demo","ok":true,"v":1}"#).expect("json parse");
assert!(matches!(json, parser::json::JsonValue::Object));
let csv = parser::csv::parse_csv(b"id,name\n1,alice\n2,bob\n").expect("csv parse");
assert!(matches!(csv, parser::csv::CsvValue::Table));
let yaml = parser::yaml::parse_yaml(b"name: demo\nok: true\n").expect("yaml parse");
assert!(matches!(yaml, parser::yaml::YamlValue::Mapping));
}
#[test]
fn parser_limit_rejection_works() {
let deep = br#"{"a":{"b":{"c":1}}}"#;
let err = parser::json::parse_json_with_max_depth(deep, 1).expect_err("must fail on depth");
assert!(matches!(
err.kind,
parser::json::JsonErrorKind::MaxDepthExceeded
));
}
#[test]
fn benchmark_blob_roundtrip_bmk() {
let metrics = benchmark::BenchmarkMetrics {
model_name: "demo-model",
precision: "f32",
elapsed_ms: 1234,
iterations: 99,
train_samples: 2048,
avg_loss: 0.125,
last_loss: 0.101,
output_bytes: 4096,
total_params: 777,
layer_count: 3,
input_dim: 16,
output_dim: 4,
benchmark_flags: 0x55AA,
weights_bytes: 3000,
biases_bytes: 96,
min_loss: 0.09,
max_loss: 0.25,
loss_stddev: 0.02,
iterations_per_sec: 12.5,
samples_per_sec: 350.0,
};
let size = benchmark::encoded_size_benchmark_blob(&metrics).expect("size");
let mut out = vec![0u8; size];
let used = benchmark::encode_benchmark_blob(&metrics, &mut out).expect("encode");
assert_eq!(used, size);
let view = benchmark::decode_benchmark_blob(&out[..used]).expect("decode");
assert_eq!(view.model_name, metrics.model_name);
assert_eq!(view.precision, metrics.precision);
assert_eq!(view.elapsed_ms, metrics.elapsed_ms);
assert_eq!(view.iterations, metrics.iterations);
assert_eq!(view.train_samples, metrics.train_samples);
assert_eq!(view.layer_count, metrics.layer_count);
assert_eq!(view.input_dim, metrics.input_dim);
assert_eq!(view.output_dim, metrics.output_dim);
}
#[derive(Default)]
struct MemBmkStorage {
path: String,
bytes: Vec<u8>,
}
impl benchmark::BenchmarkStorage for MemBmkStorage {
fn write_all(&mut self, path: &str, bytes: &[u8]) -> Result<(), benchmark::BenchmarkIoError> {
self.path.clear();
self.path.push_str(path);
self.bytes.clear();
self.bytes.extend_from_slice(bytes);
Ok(())
}
}
#[test]
fn benchmark_persist_supports_bmk_path() {
let metrics = benchmark::BenchmarkMetrics {
model_name: "demo",
precision: "f64",
elapsed_ms: 10,
iterations: 1,
train_samples: 1,
avg_loss: 1.0,
last_loss: 1.0,
output_bytes: 16,
total_params: 8,
layer_count: 1,
input_dim: 2,
output_dim: 1,
benchmark_flags: 0,
weights_bytes: 8,
biases_bytes: 8,
min_loss: 1.0,
max_loss: 1.0,
loss_stddev: 0.0,
iterations_per_sec: 1.0,
samples_per_sec: 1.0,
};
let mut scratch = vec![0u8; benchmark::encoded_size_benchmark_blob(&metrics).unwrap_or(0)];
let mut storage = MemBmkStorage::default();
let used = benchmark::persist_benchmark_blob(
&mut storage,
"benchmarks/demo.bmk",
&metrics,
&mut scratch,
)
.expect("persist");
assert!(storage.path.ends_with(".bmk"));
assert_eq!(used, storage.bytes.len());
let decoded = benchmark::decode_benchmark_blob(&storage.bytes).expect("decode persisted");
assert_eq!(decoded.model_name, "demo");
assert_eq!(decoded.precision, "f64");
}
#[test]
fn formats_file_io_json_csv_yaml_bmk() {
let dir = temp_formats_dir();
fs::create_dir_all(&dir).expect("create temp formats dir");
let json_path = dir.join("sample.json");
fs::write(&json_path, br#"{"id":1,"ok":true}"#).expect("write json");
let json_bytes = fs::read(&json_path).expect("read json");
let json_val = parser::json::parse_json(&json_bytes).expect("parse json file");
assert!(matches!(json_val, parser::json::JsonValue::Object));
let csv_path = dir.join("sample.csv");
fs::write(&csv_path, b"id,name\n1,alice\n").expect("write csv");
let csv_bytes = fs::read(&csv_path).expect("read csv");
let csv_val = parser::csv::parse_csv(&csv_bytes).expect("parse csv file");
assert!(matches!(csv_val, parser::csv::CsvValue::Table));
let yaml_path = dir.join("sample.yaml");
fs::write(&yaml_path, b"name: demo\nok: true\n").expect("write yaml");
let yaml_bytes = fs::read(&yaml_path).expect("read yaml");
let yaml_val = parser::yaml::parse_yaml(&yaml_bytes).expect("parse yaml file");
assert!(matches!(yaml_val, parser::yaml::YamlValue::Mapping));
let metrics = benchmark::BenchmarkMetrics {
model_name: "formats-demo",
precision: "f32",
elapsed_ms: 5,
iterations: 1,
train_samples: 1,
avg_loss: 0.5,
last_loss: 0.5,
output_bytes: 32,
total_params: 4,
layer_count: 1,
input_dim: 2,
output_dim: 1,
benchmark_flags: 1,
weights_bytes: 16,
biases_bytes: 4,
min_loss: 0.5,
max_loss: 0.5,
loss_stddev: 0.0,
iterations_per_sec: 1.0,
samples_per_sec: 1.0,
};
let size = benchmark::encoded_size_benchmark_blob(&metrics).expect("bmk size");
let mut bmk_bytes = vec![0u8; size];
let used = benchmark::encode_benchmark_blob(&metrics, &mut bmk_bytes).expect("encode bmk");
let bmk_path = dir.join("sample.bmk");
fs::write(&bmk_path, &bmk_bytes[..used]).expect("write bmk");
let persisted = fs::read(&bmk_path).expect("read bmk");
let bmk_view = benchmark::decode_benchmark_blob(&persisted).expect("decode bmk file");
assert_eq!(bmk_view.model_name, "formats-demo");
assert_eq!(bmk_view.precision, "f32");
let _ = fs::remove_dir_all(&dir);
}