#[cfg(unix)]
mod unix {
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
fn supervisor_exe() -> PathBuf {
if let Some(p) = std::env::var_os("CARGO_BIN_EXE_cellos_supervisor") {
return PathBuf::from(p);
}
let root = Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(|p| p.parent())
.expect("cellos-supervisor crate under workspace root");
let profile = std::env::var("PROFILE").unwrap_or_else(|_| "debug".into());
root.join("target").join(profile).join("cellos-supervisor")
}
fn write_spec(path: &Path, cell_id: &str, artifact_name: &str, src: &Path) {
let spec = serde_json::json!({
"apiVersion": "cellos.io/v1",
"kind": "ExecutionCell",
"spec": {
"id": cell_id,
"authority": { "secretRefs": [] },
"lifetime": { "ttlSeconds": 60 },
"export": {
"artifacts": [
{ "name": artifact_name, "path": src.to_str().unwrap() }
]
}
}
});
std::fs::write(path, serde_json::to_string(&spec).unwrap()).unwrap();
}
#[test]
fn sequential_runs_keep_separate_export_subdirs() {
let tmp = tempfile::tempdir().expect("tempdir");
let export_root = tmp.path().join("export_out");
std::fs::create_dir_all(&export_root).unwrap();
let src_a = tmp.path().join("only-a.txt");
File::create(&src_a).unwrap().write_all(b"alpha").unwrap();
let src_b = tmp.path().join("only-b.txt");
File::create(&src_b).unwrap().write_all(b"beta").unwrap();
let spec_a = tmp.path().join("spec-a.json");
let spec_b = tmp.path().join("spec-b.json");
write_spec(&spec_a, "seq-cell-a", "out.txt", &src_a);
write_spec(&spec_b, "seq-cell-b", "out.txt", &src_b);
let exe = supervisor_exe();
assert!(
exe.is_file(),
"supervisor binary missing at {}",
exe.display()
);
let run = |spec: &Path| {
Command::new(&exe)
.env("CELLOS_DEPLOYMENT_PROFILE", "portable")
.env("CELL_OS_USE_NOOP_SINK", "1")
.env("CELLOS_CELL_BACKEND", "stub")
.env("CELLOS_EXPORT_DIR", &export_root)
.current_dir(env!("CARGO_MANIFEST_DIR"))
.arg(spec)
.status()
.expect("spawn cellos-supervisor")
};
assert!(run(&spec_a).success(), "first run failed");
assert!(run(&spec_b).success(), "second run failed");
let dest_a = export_root.join("seq-cell-a").join("out.txt");
let dest_b = export_root.join("seq-cell-b").join("out.txt");
assert_eq!(std::fs::read_to_string(&dest_a).unwrap(), "alpha");
assert_eq!(std::fs::read_to_string(&dest_b).unwrap(), "beta");
assert!(
!export_root.join("seq-cell-b").join("only-a.txt").exists(),
"run B subtree must not contain run A artifact file name by accident"
);
assert_eq!(
std::fs::read_dir(export_root.join("seq-cell-a"))
.unwrap()
.count(),
1
);
assert_eq!(
std::fs::read_dir(export_root.join("seq-cell-b"))
.unwrap()
.count(),
1
);
}
}