#![cfg(target_os = "linux")]
use std::fs;
use cellos_core::types::{RunCpuMax, RunLimits};
use cellos_supervisor::linux_cgroup::{apply_cpu_max_to_leaf, CpuMaxApplyOutcome, CpuMaxSource};
fn limits_with_cpu(quota: u64, period: Option<u64>) -> RunLimits {
RunLimits {
memory_max_bytes: None,
cpu_max: Some(RunCpuMax {
quota_micros: quota,
period_micros: period,
}),
graceful_shutdown_seconds: None,
}
}
#[test]
fn cpu_max_from_spec_is_written_to_leaf() {
let dir = tempfile::tempdir().expect("tempdir");
let leaf = dir.path();
let limits = limits_with_cpu(50_000, Some(100_000));
let outcome = apply_cpu_max_to_leaf(
leaf,
Some(&limits),
Some("max 200000"), );
match outcome {
CpuMaxApplyOutcome::Wrote { source, payload } => {
assert_eq!(source, CpuMaxSource::Spec, "spec must be primary source");
assert_eq!(payload, "50000 100000");
}
other => panic!("expected Wrote{{Spec,...}}, got {other:?}"),
}
let written = fs::read_to_string(leaf.join("cpu.max")).expect("read cpu.max");
assert_eq!(
written, "50000 100000\n",
"cpu.max payload must match spec quota/period (kernel parses without trailing newline; we add one for readability)"
);
}
#[test]
fn cpu_max_not_written_when_spec_silent_and_env_unset() {
let dir = tempfile::tempdir().expect("tempdir");
let leaf = dir.path();
let cpu_max_path = leaf.join("cpu.max");
assert!(!cpu_max_path.exists(), "tempdir starts clean");
let outcome = apply_cpu_max_to_leaf(leaf, None, None);
assert_eq!(outcome, CpuMaxApplyOutcome::Skipped);
assert!(
!cpu_max_path.exists(),
"no cpu.max must be written when neither spec nor env supplied a value (kernel default remains in effect)"
);
let limits_no_cpu = RunLimits {
memory_max_bytes: None,
cpu_max: None,
graceful_shutdown_seconds: None,
};
let outcome = apply_cpu_max_to_leaf(leaf, Some(&limits_no_cpu), None);
assert_eq!(outcome, CpuMaxApplyOutcome::Skipped);
assert!(
!cpu_max_path.exists(),
"limits.cpuMax=None must behave identically to limits=None"
);
let outcome = apply_cpu_max_to_leaf(leaf, None, Some(""));
assert_eq!(outcome, CpuMaxApplyOutcome::Skipped);
assert!(
!cpu_max_path.exists(),
"empty CELLOS_CGROUP_CPU_MAX is not a default; no write"
);
}
#[test]
fn cpu_max_env_override_used_when_spec_silent() {
let dir = tempfile::tempdir().expect("tempdir");
let leaf = dir.path();
let outcome = apply_cpu_max_to_leaf(leaf, None, Some("25000 100000"));
match outcome {
CpuMaxApplyOutcome::Wrote { source, payload } => {
assert_eq!(source, CpuMaxSource::EnvOverride);
assert_eq!(payload, "25000 100000");
}
other => panic!("expected Wrote{{EnvOverride,...}}, got {other:?}"),
}
let written = fs::read_to_string(leaf.join("cpu.max")).expect("read cpu.max");
assert_eq!(written, "25000 100000\n");
}
#[test]
fn cpu_max_invalid_env_override_does_not_write() {
let dir = tempfile::tempdir().expect("tempdir");
let leaf = dir.path();
let outcome = apply_cpu_max_to_leaf(leaf, None, Some("not-a-number"));
assert_eq!(outcome, CpuMaxApplyOutcome::InvalidEnvOverride);
assert!(!leaf.join("cpu.max").exists());
}