use std::collections::HashMap;
use std::path::Path;
fn read_baselines() -> HashMap<String, HashMap<String, Option<f64>>> {
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("benches/baselines.json");
let raw = match std::fs::read_to_string(&path) {
Ok(s) => s,
Err(_) => return HashMap::new(),
};
parse_baselines_minimal(&raw)
}
fn parse_baselines_minimal(raw: &str) -> HashMap<String, HashMap<String, Option<f64>>> {
let mut out: HashMap<String, HashMap<String, Option<f64>>> = HashMap::new();
let mut current_class: Option<String> = None;
for line in raw.lines() {
let trimmed = line.trim();
if let Some(class_name) = parse_class_header(trimmed) {
current_class = Some(class_name);
out.entry(current_class.clone().unwrap_or_default())
.or_default();
continue;
}
if trimmed == "}," || trimmed == "}" {
continue;
}
if let Some((key, value)) = parse_metric_line(trimmed) {
if key.starts_with('_') {
continue; }
if let Some(class) = current_class.clone() {
out.entry(class).or_default().insert(key.to_string(), value);
}
}
}
out
}
fn parse_class_header(line: &str) -> Option<String> {
if !line.ends_with(": {") && !line.ends_with(": {,") {
return None;
}
let mut chars = line.chars();
if chars.next()? != '"' {
return None;
}
let rest: String = chars.collect();
let end = rest.find('"')?;
let name = &rest[..end];
if name == "machine_classes"
|| name == "regression_thresholds"
|| name == "tail_target"
|| name.starts_with('_')
{
return None;
}
Some(name.to_string())
}
fn parse_metric_line(line: &str) -> Option<(&str, Option<f64>)> {
let line = line.trim_end_matches(',');
let mut chars = line.chars();
if chars.next()? != '"' {
return None;
}
let rest = chars.as_str();
let end_quote = rest.find('"')?;
let key = &rest[..end_quote];
let after_key = &rest[end_quote + 1..];
let after_colon = after_key.trim_start_matches(':').trim();
if after_colon == "null" {
return Some((key, None));
}
let value: Option<f64> = after_colon.parse::<f64>().ok();
Some((key, value))
}
#[test]
fn baselines_parse_without_panic() {
let baselines = read_baselines();
assert!(
!baselines.is_empty(),
"baselines.json should contain at least one machine class"
);
}
#[test]
fn placeholder_baselines_short_circuit_with_warning() {
let baselines = read_baselines();
let mut placeholder_count = 0;
let mut populated_count = 0;
for (class, metrics) in &baselines {
for (metric, value) in metrics {
if value.is_some() {
populated_count += 1;
eprintln!(
"[regression] baseline {class}/{metric} = {} (populated)",
value.unwrap()
);
} else {
placeholder_count += 1;
}
}
}
eprintln!(
"[regression] {placeholder_count} placeholder baselines, {populated_count} populated"
);
}
#[test]
fn regression_thresholds_have_expected_keys() {
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("benches/baselines.json");
let raw = std::fs::read_to_string(&path).expect("read baselines.json");
assert!(
raw.contains("\"critical_pct\""),
"regression_thresholds.critical_pct missing"
);
assert!(
raw.contains("\"standard_pct\""),
"regression_thresholds.standard_pct missing"
);
assert!(
raw.contains("\"loose_pct\""),
"regression_thresholds.loose_pct missing"
);
}
#[test]
fn tail_target_has_expected_ratio() {
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("benches/baselines.json");
let raw = std::fs::read_to_string(&path).expect("read baselines.json");
assert!(
raw.contains("\"p999_over_p50_max_ratio\""),
"tail_target.p999_over_p50_max_ratio missing"
);
assert!(
raw.contains("10"),
"tail target ratio should be 10x; check baselines.json"
);
}
#[test]
fn parse_metric_line_handles_null_and_numbers() {
assert_eq!(
parse_metric_line(r#""single_write_sync_4k_p50_us": null,"#),
Some(("single_write_sync_4k_p50_us", None))
);
assert_eq!(
parse_metric_line(r#""single_write_sync_4k_p50_us": 80,"#),
Some(("single_write_sync_4k_p50_us", Some(80.0)))
);
assert_eq!(
parse_metric_line(r#""ratio": 12.5"#),
Some(("ratio", Some(12.5)))
);
let result = parse_metric_line(r#""_status": "placeholder","#);
assert_eq!(result.map(|(k, _)| k), Some("_status"));
}