tests: Make cgroup tests hierarchy-aware

Resolve cgroup filesystem paths according to the active hierarchy and
assert systemd's expected cgroup v1 limitations. This lets the existing
manager and D-Bus tests run in both guest modes without changing library
behavior.

Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
This commit is contained in:
Xuewei Niu
2026-07-28 05:07:37 -05:00
parent 7a7fd32e4f
commit 091d694c00
3 changed files with 55 additions and 21 deletions

View File

@@ -1167,6 +1167,19 @@ mod tests {
FsManager::new(TEST_BASE).unwrap()
}
fn managed_cgroup_path(manager: &FsManager, subsystem: Option<&str>) -> String {
if manager.v2() {
return join_path(UNIFIED_MOUNTPOINT, &manager.base);
}
let subsystem = subsystem.expect("cgroup v1 requires a subsystem");
let mountpoint = manager
.mounts
.get(subsystem)
.expect("cgroup v1 subsystem mountpoint should exist");
join_path(mountpoint, &manager.base)
}
fn run_set_resources_failed(resources: LinuxResources) {
let mut child = spawn_sleep_inf();
let mut manager = new_manager();
@@ -1218,14 +1231,8 @@ mod tests {
let mut manager = new_manager();
for (subsystem, mountpoint) in manager.mounts() {
let subsys = if subsystem.is_empty() {
assert!(manager.v2());
None
} else {
Some(subsystem.as_str())
};
let path = manager.cgroup_path(subsys).unwrap();
let path = join_path(mountpoint, &path);
let path = manager.paths().get(subsystem).unwrap();
let path = join_path(mountpoint, path.trim_start_matches('/'));
assert!(Path::new(&path).exists(), "Cgroup {} does not exist", path);
}
@@ -1237,11 +1244,7 @@ mod tests {
let mut manager = new_manager();
manager.create_cgroups().unwrap();
let cgroup_path = if manager.v2() {
manager.cgroup_path(None).unwrap()
} else {
manager.cgroup_path(Some("memory")).unwrap()
};
let cgroup_path = managed_cgroup_path(&manager, (!manager.v2()).then_some("memory"));
assert!(
Path::new(&cgroup_path).exists(),
"Cgroup should exist before destroy"
@@ -1380,7 +1383,6 @@ mod tests {
#[test]
fn test_enable_cpus_topdown() {
let cpuset_cpus_path = format!("/sys/fs/cgroup/{}/cpuset.cpus", TEST_BASE);
let online_cpus = fs::read_to_string("/sys/devices/system/cpu/online").unwrap();
let cpus = parse_cpu_list(&online_cpus);
@@ -1398,6 +1400,8 @@ mod tests {
.build()
.unwrap();
run_set_resources(linux_resources, |manager| {
let managed_path = managed_cgroup_path(manager, (!manager.v2()).then_some("cpuset"));
let cpuset_cpus_path = join_path(&managed_path, "cpuset.cpus");
let cpus1 = fs::read_to_string(&cpuset_cpus_path).unwrap();
let cpus1 = parse_cpu_list(&cpus1);
assert_eq!(cpus[..1], cpus1);

View File

@@ -370,6 +370,20 @@ mod tests {
SystemdManager::new(&format!("{}:{}:{}", slice, scope_prefix, name)).unwrap()
}
fn managed_cgroup_path(manager: &SystemdManager<'_>, subsystem: Option<&str>) -> String {
if manager.v2() {
return manager.cgroup_path(None).unwrap();
}
let subsystem = subsystem.expect("cgroup v1 requires a subsystem");
let mountpoint = manager
.mounts()
.get(subsystem)
.expect("cgroup v1 subsystem mountpoint should exist");
let slice_base = expand_slice(manager.slice()).unwrap();
join_path(mountpoint, &join_path(&slice_base, manager.unit()))
}
fn run_set_resources_failed(resources: LinuxResources) {
let mut child = spawn_sleep_inf();
let mut manager = new_systemd_manager();
@@ -431,7 +445,7 @@ mod tests {
let mut manager =
SystemdManager::new(&format!("{}:{}:{}", slice, scope_prefix, name)).unwrap();
let cgroup_path = manager.cgroup_path(Some("memory")).unwrap();
let cgroup_path = managed_cgroup_path(&manager, (!manager.v2()).then_some("memory"));
// Before starting the unit, no cgroup should exist.
assert!(!Path::new(&cgroup_path).exists());

View File

@@ -452,12 +452,23 @@ pub mod tests {
fn test_freeze_and_thaw() {
skip_if_no_systemd!();
let v2 = hierarchies::is_cgroup2_unified_mode();
let unit = test_unit();
let mut child = spawn_yes();
let cgroup = start_default_cgroup(CgroupPid::from(child.id() as u64), &unit);
// Freeze the unit
cgroup.freeze().unwrap();
let freeze_result = cgroup.freeze();
if !v2 {
assert!(
freeze_result.is_err(),
"systemd should reject FreezeUnit on cgroup v1"
);
stop_cgroup(&cgroup);
child.wait().unwrap();
return;
}
freeze_result.unwrap();
let pid = child.id() as u64;
@@ -507,6 +518,7 @@ pub mod tests {
fn test_add_process() {
skip_if_no_systemd!();
let v2 = hierarchies::is_cgroup2_unified_mode();
let unit = test_unit();
let mut child = spawn_sleep_inf();
let cgroup = start_default_cgroup(CgroupPid::from(child.id() as u64), &unit);
@@ -515,11 +527,15 @@ pub mod tests {
let pid1 = CgroupPid::from(child1.id() as u64);
cgroup.add_process(pid1, "/").unwrap();
let cgroup_procs_path = format!(
"/sys/fs/cgroup/{}/{}/cgroup.procs",
expand_slice(TEST_SLICE).unwrap(),
unit
);
let cgroup_root = if v2 {
Path::new("/sys/fs/cgroup")
} else {
Path::new("/sys/fs/cgroup/memory")
};
let cgroup_procs_path = cgroup_root
.join(expand_slice(TEST_SLICE).unwrap())
.join(&unit)
.join("cgroup.procs");
for i in 0..5 {
let content = fs::read_to_string(&cgroup_procs_path);
if let Ok(content) = content {