mirror of
https://github.com/containers/youki
synced 2025-04-30 13:20:17 +02:00
test: add checks for classid and net_prio to network.rs
Signed-off-by: moz-sec <m0253c@gmail.com>
This commit is contained in:
parent
c327345c1b
commit
c6e3c0a1db
@ -1,6 +1,7 @@
|
||||
use std::path::Path;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use oci_spec::runtime::{
|
||||
LinuxBuilder, LinuxInterfacePriorityBuilder, LinuxNamespace, LinuxNamespaceType,
|
||||
LinuxNetworkBuilder, LinuxResourcesBuilder, Spec, SpecBuilder,
|
||||
@ -9,7 +10,7 @@ use pnet_datalink::interfaces;
|
||||
use test_framework::{test_result, ConditionalTest, TestGroup, TestResult};
|
||||
|
||||
use crate::utils::test_outside_container;
|
||||
use crate::utils::test_utils::check_container_created;
|
||||
use crate::utils::test_utils::{check_container_created, CGROUP_ROOT};
|
||||
|
||||
fn create_spec(
|
||||
cgroup_name: &str,
|
||||
@ -115,8 +116,9 @@ fn test_network_cgroups() -> TestResult {
|
||||
];
|
||||
|
||||
for spec in cases.into_iter() {
|
||||
let test_result = test_outside_container(spec, &|data| {
|
||||
let test_result = test_outside_container(spec.clone(), &|data| {
|
||||
test_result!(check_container_created(&data));
|
||||
test_result!(validate_network(cgroup_name, &spec));
|
||||
|
||||
TestResult::Passed
|
||||
});
|
||||
@ -128,6 +130,97 @@ fn test_network_cgroups() -> TestResult {
|
||||
TestResult::Passed
|
||||
}
|
||||
|
||||
/// validates the Network structure parsed from /sys/fs/cgroup/net_cls,net_prio with the spec
|
||||
fn validate_network(cgroup_name: &str, spec: &Spec) -> Result<()> {
|
||||
let (net_cls_path, net_prio_path) = if Path::new("/sys/fs/cgroup/net_cls/net_cls.classid")
|
||||
.exists()
|
||||
&& Path::new("/sys/fs/cgroup/net_prio/net_prio.ifpriomap").exists()
|
||||
{
|
||||
(
|
||||
net_cls_path(PathBuf::from(CGROUP_ROOT).join("net_cls"), cgroup_name),
|
||||
net_prio_path(PathBuf::from(CGROUP_ROOT).join("net_prio"), cgroup_name),
|
||||
)
|
||||
} else if Path::new("/sys/fs/cgroup/net_cls,net_prio/net_cls.classid").exists()
|
||||
&& Path::new("/sys/fs/cgroup/net_cls,net_prio/net_prio.ifpriomap").exists()
|
||||
{
|
||||
(
|
||||
net_cls_path(
|
||||
PathBuf::from(CGROUP_ROOT).join("net_cls,net_prio"),
|
||||
cgroup_name,
|
||||
),
|
||||
net_prio_path(
|
||||
PathBuf::from(CGROUP_ROOT).join("net_cls,net_prio"),
|
||||
cgroup_name,
|
||||
),
|
||||
)
|
||||
} else if Path::new("/sys/fs/cgroup/net_prio,net_cls/net_cls.classid").exists()
|
||||
&& Path::new("/sys/fs/cgroup/net_prio,net_cls/net_prio.ifpriomap").exists()
|
||||
{
|
||||
(
|
||||
net_cls_path(
|
||||
PathBuf::from(CGROUP_ROOT).join("net_prio,net_cls"),
|
||||
cgroup_name,
|
||||
),
|
||||
net_prio_path(
|
||||
PathBuf::from(CGROUP_ROOT).join("net_prio,net_cls"),
|
||||
cgroup_name,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
return Err(anyhow::anyhow!("Required cgroup paths do not exist"));
|
||||
};
|
||||
|
||||
let resources = spec.linux().as_ref().unwrap().resources().as_ref().unwrap();
|
||||
let spec_network = resources.network().as_ref().unwrap();
|
||||
|
||||
// Validate net_cls.classid
|
||||
let classid_content = fs::read_to_string(&net_cls_path)
|
||||
.with_context(|| format!("failed to read {:?}", net_cls_path))?;
|
||||
let expected_classid = spec_network.class_id().unwrap();
|
||||
let actual_classid: u32 = classid_content
|
||||
.trim()
|
||||
.parse()
|
||||
.with_context(|| format!("could not parse {:?}", classid_content.trim()))?;
|
||||
if expected_classid != actual_classid {
|
||||
bail!(
|
||||
"expected {:?} to contain a classid of {}, but the classid was {}",
|
||||
net_cls_path,
|
||||
expected_classid,
|
||||
actual_classid
|
||||
);
|
||||
}
|
||||
|
||||
// Validate net_prio.ifpriomap
|
||||
let ifpriomap_content = fs::read_to_string(&net_prio_path)
|
||||
.with_context(|| format!("failed to read {:?}", net_prio_path))?;
|
||||
let expected_priorities = spec_network.priorities().as_ref().unwrap();
|
||||
for priority in expected_priorities {
|
||||
let expected_entry = format!("{} {}", priority.name(), priority.priority());
|
||||
if !ifpriomap_content.contains(&expected_entry) {
|
||||
bail!(
|
||||
"expected {:?} to contain an entry '{}', but it was not found",
|
||||
net_prio_path,
|
||||
expected_entry
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn net_cls_path(base_path: PathBuf, cgroup_name: &str) -> PathBuf {
|
||||
base_path
|
||||
.join("runtime-test")
|
||||
.join(cgroup_name)
|
||||
.join("net_cls.classid")
|
||||
}
|
||||
|
||||
fn net_prio_path(base_path: PathBuf, cgroup_name: &str) -> PathBuf {
|
||||
base_path
|
||||
.join("runtime-test")
|
||||
.join(cgroup_name)
|
||||
.join("net_prio.ifpriomap")
|
||||
}
|
||||
fn can_run() -> bool {
|
||||
// Ensure the expected network interfaces exist on the system running the test
|
||||
let iface_exists = get_network_interfaces().is_some();
|
||||
|
Loading…
Reference in New Issue
Block a user