use somatize_worker::env_manager::{EnvManager, EnvType};
fn has_python3() -> bool {
std::process::Command::new("python3")
.args(["--version"])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
#[test]
fn create_venv_and_get_python() {
if !has_python3() {
eprintln!("Skipping: python3 not found");
return;
}
let tmp = tempfile::tempdir().unwrap();
let mgr = EnvManager::new(tmp.path(), EnvType::Venv);
let python = mgr.ensure_env("test_pipeline", "").unwrap();
assert!(
python.exists(),
"Python binary should exist at {}",
python.display()
);
assert!(python.starts_with(tmp.path()));
let output = std::process::Command::new(&python)
.args(["--version"])
.output()
.unwrap();
assert!(output.status.success());
let version = String::from_utf8_lossy(&output.stdout);
assert!(
version.contains("Python 3"),
"Should be Python 3, got: {version}"
);
}
#[test]
fn reuse_existing_venv() {
if !has_python3() {
eprintln!("Skipping: python3 not found");
return;
}
let tmp = tempfile::tempdir().unwrap();
let mgr = EnvManager::new(tmp.path(), EnvType::Venv);
let python1 = mgr.ensure_env("reuse_test", "").unwrap();
let python2 = mgr.ensure_env("reuse_test", "").unwrap();
assert_eq!(python1, python2, "should return same python path");
}
#[test]
fn different_requirements_trigger_update() {
if !has_python3() {
eprintln!("Skipping: python3 not found");
return;
}
let tmp = tempfile::tempdir().unwrap();
let mgr = EnvManager::new(tmp.path(), EnvType::Venv);
let _python1 = mgr.ensure_env("update_test", "").unwrap();
let python2 = mgr.ensure_env("update_test", "# updated\n").unwrap();
assert!(python2.exists());
}
#[test]
fn install_real_package() {
if !has_python3() {
eprintln!("Skipping: python3 not found");
return;
}
let tmp = tempfile::tempdir().unwrap();
let mgr = EnvManager::new(tmp.path(), EnvType::Venv);
let python = mgr.ensure_env("pkg_test", "six\n").unwrap();
let output = std::process::Command::new(&python)
.args(["-c", "import six; print(six.__version__)"])
.output()
.unwrap();
assert!(
output.status.success(),
"six should be importable. stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
}
#[test]
fn cleanup_old_envs() {
if !has_python3() {
eprintln!("Skipping: python3 not found");
return;
}
let tmp = tempfile::tempdir().unwrap();
let mgr = EnvManager::new(tmp.path(), EnvType::Venv);
let _python = mgr.ensure_env("cleanup_test", "").unwrap();
let removed = mgr.cleanup(std::time::Duration::from_secs(0));
assert!(removed >= 1, "should have removed at least 1 env");
}
#[test]
fn lockfile_persists_between_calls() {
if !has_python3() {
eprintln!("Skipping: python3 not found");
return;
}
let tmp = tempfile::tempdir().unwrap();
let mgr = EnvManager::new(tmp.path(), EnvType::Venv);
let _python = mgr.ensure_env("lock_test", "six==1.17.0\n").unwrap();
let lockfile_path = tmp.path().join("env-lock_test").join("lockfile.json");
assert!(lockfile_path.exists(), "lockfile should be written");
let content = std::fs::read_to_string(&lockfile_path).unwrap();
let lockfile: serde_json::Value = serde_json::from_str(&content).unwrap();
assert!(lockfile["packages"]["six"].is_string());
}