use std::path::PathBuf;
fn training_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("training")
}
#[test]
fn pipeline_scripts_all_present() {
for script in [
"scripts/auto_label.py",
"scripts/train_lora.py",
"scripts/distill.py",
"scripts/bench_compare.py",
"scripts/promote_to_ollama.sh",
] {
let p = training_root().join(script);
assert!(
p.is_file(),
"training pipeline script missing: {}",
p.display()
);
}
}
#[test]
fn dockerfile_and_requirements_present() {
assert!(training_root().join("Dockerfile").is_file());
assert!(training_root().join("requirements.txt").is_file());
}
#[test]
fn runbook_references_existing_scripts_only() {
let runbook = std::fs::read_to_string(training_root().join("RUNBOOK.md")).unwrap();
const NEEDLE: &str = "training/scripts/";
let mut missing: Vec<String> = Vec::new();
let mut search_from = 0;
while let Some(start) = runbook[search_from..].find(NEEDLE) {
let abs_start = search_from + start;
let rest = &runbook[abs_start..];
let end = rest
.char_indices()
.find(|(_, c)| !(c.is_ascii_alphanumeric() || matches!(c, '/' | '.' | '_' | '-')))
.map(|(i, _)| i)
.unwrap_or(rest.len());
let mut rel = &rest[..end];
while rel.ends_with('.') {
rel = &rel[..rel.len() - 1];
}
let p = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(rel);
if !p.is_file() && !p.is_dir() {
missing.push(rel.to_string());
}
search_from = abs_start + end;
}
assert!(
missing.is_empty(),
"RUNBOOK references missing paths: {missing:?}"
);
}