use super::container::*;
use crate::core::types::{ContainerConfig, Machine};
fn container_machine() -> Machine {
Machine {
hostname: "test-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "docker".to_string(),
image: Some("ubuntu:22.04".to_string()),
name: Some("forjar-unit-test".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
}
}
#[test]
fn test_fj021_exec_no_container_config() {
let machine = Machine {
hostname: "bad".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: None,
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = exec_container(&machine, "echo hi");
assert!(result.is_err());
assert!(result.unwrap_err().contains("no container config"));
}
#[test]
fn test_fj021_ensure_no_container_config() {
let machine = Machine {
hostname: "bad".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: None,
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(result.is_err());
}
#[test]
fn test_fj021_cleanup_no_container_config() {
let machine = Machine {
hostname: "bad".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: None,
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = cleanup_container(&machine);
assert!(result.is_err());
}
#[test]
fn test_fj021_container_name_from_config() {
let m = container_machine();
assert_eq!(m.container_name(), "forjar-unit-test");
}
#[test]
fn test_fj021_ensure_no_image() {
let machine = Machine {
hostname: "no-image".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "docker".to_string(),
image: None,
name: Some("forjar-no-image".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(result.is_err());
}
#[test]
fn test_fj021_exec_error_includes_container_name() {
let m = container_machine();
let result = exec_container(&m, "echo hi");
if let Err(e) = result {
assert!(
e.contains("forjar-unit-test") || e.contains("container"),
"error should reference container: {e}"
);
}
}
#[test]
fn test_fj021_exec_with_fake_runtime() {
let machine = Machine {
hostname: "fake-rt".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "/bin/false".to_string(),
image: Some("test:latest".to_string()),
name: Some("forjar-fake".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = exec_container(&machine, "echo test");
match result {
Ok(out) => assert!(!out.success(), "/bin/false should fail"),
Err(e) => assert!(
e.contains("forjar-fake") || e.contains("pipe") || e.contains("false"),
"error should reference container or pipe failure: {e}"
),
}
}
#[test]
fn test_fj021_cleanup_error_includes_container_name() {
let m = container_machine();
let result = cleanup_container(&m);
if let Err(e) = result {
assert!(
e.contains("forjar-unit-test") || e.contains("container"),
"cleanup error should reference container: {e}"
);
}
}
#[test]
fn test_fj021_container_name_derived_from_hostname() {
let machine = Machine {
hostname: "my-web-server".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "docker".to_string(),
image: Some("ubuntu:22.04".to_string()),
name: None,
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
assert_eq!(machine.container_name(), "forjar-my-web-server");
}
#[test]
fn test_fj021_container_name_explicit_overrides() {
let machine = Machine {
hostname: "ignored-hostname".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "docker".to_string(),
image: Some("ubuntu:22.04".to_string()),
name: Some("custom-name".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
assert_eq!(machine.container_name(), "custom-name");
}
#[test]
fn test_fj021_podman_runtime() {
let machine = Machine {
hostname: "podman-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "podman".to_string(),
image: Some("ubuntu:22.04".to_string()),
name: Some("forjar-podman-test".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = exec_container(&machine, "echo test");
if let Err(e) = result {
assert!(
e.contains("forjar-podman-test"),
"podman error should reference container: {e}"
);
}
}
#[test]
fn test_fj021_ensure_with_privileged_and_init_flags() {
let machine = Machine {
hostname: "priv-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "/bin/echo".to_string(), image: Some("test:latest".to_string()),
name: Some("forjar-priv-test".to_string()),
ephemeral: true,
privileged: true,
init: true,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(
result.is_ok(),
"ensure with /bin/echo runtime should succeed"
);
}
#[test]
fn test_fj021_ensure_with_gpus_flag() {
let machine = Machine {
hostname: "gpu-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "/bin/echo".to_string(),
image: Some("nvidia/cuda:12.9.0-devel-ubuntu22.04".to_string()),
name: Some("forjar-gpu-test".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: Some("all".to_string()),
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(
result.is_ok(),
"ensure with --gpus all should succeed: {result:?}"
);
}
#[test]
fn test_fj021_ensure_with_rocm_devices() {
let machine = Machine {
hostname: "rocm-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "/bin/echo".to_string(),
image: Some("rocm/dev-ubuntu-22.04:6.1".to_string()),
name: Some("forjar-rocm-test".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: None,
devices: vec!["/dev/kfd".to_string(), "/dev/dri".to_string()],
group_add: vec!["video".to_string(), "render".to_string()],
env: [("ROCR_VISIBLE_DEVICES".to_string(), "0".to_string())]
.into_iter()
.collect(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(
result.is_ok(),
"ensure with ROCm devices should succeed: {result:?}"
);
}
#[test]
fn test_fj021_ensure_with_env_vars() {
let machine = Machine {
hostname: "env-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "/bin/echo".to_string(),
image: Some("nvidia/cuda:12.4.1-runtime-ubuntu22.04".to_string()),
name: Some("forjar-env-test".to_string()),
ephemeral: true,
privileged: false,
init: true,
gpus: Some("all".to_string()),
devices: vec![],
group_add: vec![],
env: [("CUDA_VISIBLE_DEVICES".to_string(), "0,1".to_string())]
.into_iter()
.collect(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(
result.is_ok(),
"ensure with env vars should succeed: {result:?}"
);
}
#[test]
fn test_fj021_ensure_no_init_no_privileged() {
let machine = Machine {
hostname: "bare-box".to_string(),
addr: "container".to_string(),
user: "root".to_string(),
arch: "x86_64".to_string(),
ssh_key: None,
roles: vec![],
transport: Some("container".to_string()),
container: Some(ContainerConfig {
runtime: "/bin/echo".to_string(),
image: Some("test:latest".to_string()),
name: Some("forjar-bare-test".to_string()),
ephemeral: true,
privileged: false,
init: false,
gpus: None,
devices: vec![],
group_add: vec![],
env: std::collections::HashMap::new(),
volumes: vec![],
}),
pepita: None,
cost: 0,
allowed_operators: vec![],
};
let result = ensure_container(&machine);
assert!(
result.is_ok(),
"ensure without init/privileged should succeed"
);
}