1
0
mirror of https://github.com/containers/youki synced 2024-11-22 17:02:00 +01:00

Add e2e test: process rlimits (#2977)

* add process rlimits test

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix newline code

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix fmt

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix format err

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add process args to run test

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix unsafe code by use nix

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* remove unused import

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

---------

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>
This commit is contained in:
sat0ken 2024-11-12 22:11:34 +09:00 committed by GitHub
parent 444cc4ff28
commit 5a9e78fe65
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 125 additions and 1 deletions

@ -21,6 +21,7 @@ use crate::tests::linux_ns_itype::get_ns_itype_tests;
use crate::tests::mounts_recursive::get_mounts_recursive_test;
use crate::tests::no_pivot::get_no_pivot_test;
use crate::tests::pidfile::get_pidfile_test;
use crate::tests::process_rlimits::get_process_rlimits_test;
use crate::tests::readonly_paths::get_ro_paths_test;
use crate::tests::scheduler::get_scheduler_test;
use crate::tests::seccomp::get_seccomp_test;
@ -114,6 +115,7 @@ fn main() -> Result<()> {
let scheduler = get_scheduler_test();
let io_priority_test = get_io_priority_test();
let devices = get_devices_test();
let process_rlimtis = get_process_rlimits_test();
let no_pivot = get_no_pivot_test();
tm.add_test_group(Box::new(cl));
@ -138,6 +140,7 @@ fn main() -> Result<()> {
tm.add_test_group(Box::new(sysctl));
tm.add_test_group(Box::new(scheduler));
tm.add_test_group(Box::new(devices));
tm.add_test_group(Box::new(process_rlimtis));
tm.add_test_group(Box::new(no_pivot));
tm.add_test_group(Box::new(io_priority_test));

@ -11,6 +11,7 @@ pub mod linux_ns_itype;
pub mod mounts_recursive;
pub mod no_pivot;
pub mod pidfile;
pub mod process_rlimits;
pub mod readonly_paths;
pub mod scheduler;
pub mod seccomp;

@ -0,0 +1,2 @@
mod process_rlimits_test;
pub use process_rlimits_test::get_process_rlimits_test;

@ -0,0 +1,67 @@
use anyhow::{Context, Ok, Result};
use oci_spec::runtime::{
PosixRlimit, PosixRlimitBuilder, PosixRlimitType, ProcessBuilder, Spec, SpecBuilder,
};
use test_framework::{test_result, Test, TestGroup, TestResult};
use crate::utils::test_inside_container;
const GIGABYTES: u64 = 1024 * 1024 * 1024;
fn create_rlimit(
rlimit_type: PosixRlimitType,
hard_val: u64,
soft_val: u64,
) -> Result<PosixRlimit> {
let rlimit = PosixRlimitBuilder::default()
.typ(rlimit_type)
.hard(hard_val)
.soft(soft_val)
.build()?;
Ok(rlimit)
}
#[allow(clippy::identity_op)]
fn create_spec() -> Result<Spec> {
let spec = SpecBuilder::default()
.process(
ProcessBuilder::default()
.args(vec![
"runtimetest".to_string(),
"process_rlimits".to_string(),
])
.rlimits(vec![
create_rlimit(PosixRlimitType::RlimitAs, 2 * GIGABYTES, 1 * GIGABYTES).unwrap(),
create_rlimit(PosixRlimitType::RlimitCore, 4 * GIGABYTES, 3 * GIGABYTES)
.unwrap(),
create_rlimit(PosixRlimitType::RlimitData, 6 * GIGABYTES, 5 * GIGABYTES)
.unwrap(),
create_rlimit(PosixRlimitType::RlimitFsize, 8 * GIGABYTES, 7 * GIGABYTES)
.unwrap(),
create_rlimit(PosixRlimitType::RlimitStack, 10 * GIGABYTES, 9 * GIGABYTES)
.unwrap(),
create_rlimit(PosixRlimitType::RlimitCpu, 120, 60).unwrap(),
create_rlimit(PosixRlimitType::RlimitNofile, 4000, 3000).unwrap(),
])
.build()
.expect("error in creating process config"),
)
.build()
.context("failed to build spec")?;
Ok(spec)
}
fn process_rlimits_test() -> TestResult {
let spec = test_result!(create_spec());
test_inside_container(spec, &|_| Ok(()))
}
pub fn get_process_rlimits_test() -> TestGroup {
let mut process_rlimits_test_group = TestGroup::new("process_rlimits");
let test = Test::new("process_rlimits_test", Box::new(process_rlimits_test));
process_rlimits_test_group.add(vec![Box::new(test)]);
process_rlimits_test_group
}

@ -44,6 +44,7 @@ fn main() {
"io_priority_class_be" => tests::test_io_priority_class(&spec, IoprioClassBe),
"io_priority_class_idle" => tests::test_io_priority_class(&spec, IoprioClassIdle),
"devices" => tests::validate_devices(&spec),
"process_rlimits" => tests::validate_process_rlimits(&spec),
"no_pivot" => tests::validate_rootfs(),
_ => eprintln!("error due to unexpected execute test name: {execute_test}"),
}

@ -6,10 +6,13 @@ use std::path::Path;
use anyhow::{bail, Result};
use nix::errno::Errno;
use nix::libc;
use nix::sys::resource::{getrlimit, Resource};
use nix::sys::utsname;
use nix::unistd::getcwd;
use oci_spec::runtime::IOPriorityClass::{self, IoprioClassBe, IoprioClassIdle, IoprioClassRt};
use oci_spec::runtime::{LinuxDevice, LinuxDeviceType, LinuxSchedulerPolicy, Spec};
use oci_spec::runtime::{
LinuxDevice, LinuxDeviceType, LinuxSchedulerPolicy, PosixRlimit, PosixRlimitType, Spec,
};
use crate::utils::{self, test_read_access, test_write_access};
@ -546,6 +549,53 @@ pub fn test_io_priority_class(spec: &Spec, io_priority_class: IOPriorityClass) {
}
}
pub fn validate_process_rlimits(spec: &Spec) {
let process = spec.process().as_ref().unwrap();
let spec_rlimits: &Vec<PosixRlimit> = process.rlimits().as_ref().unwrap();
for spec_rlimit in spec_rlimits.iter() {
let (soft_limit, hard_limit) = getrlimit(change_resource_type(spec_rlimit.typ())).unwrap();
if spec_rlimit.hard() != hard_limit {
eprintln!(
"error type of {:?} hard rlimit expected {:?} , got {:?}",
spec_rlimit.typ(),
spec_rlimit.hard(),
hard_limit
)
}
if spec_rlimit.soft() != soft_limit {
eprintln!(
"error type of {:?} soft rlimit expected {:?} , got {:?}",
spec_rlimit.typ(),
spec_rlimit.soft(),
soft_limit
)
}
}
}
fn change_resource_type(resource_type: PosixRlimitType) -> Resource {
match resource_type {
PosixRlimitType::RlimitCpu => Resource::RLIMIT_CPU,
PosixRlimitType::RlimitFsize => Resource::RLIMIT_FSIZE,
PosixRlimitType::RlimitData => Resource::RLIMIT_DATA,
PosixRlimitType::RlimitStack => Resource::RLIMIT_STACK,
PosixRlimitType::RlimitCore => Resource::RLIMIT_CORE,
PosixRlimitType::RlimitRss => Resource::RLIMIT_RSS,
PosixRlimitType::RlimitNproc => Resource::RLIMIT_NPROC,
PosixRlimitType::RlimitNofile => Resource::RLIMIT_NOFILE,
PosixRlimitType::RlimitMemlock => Resource::RLIMIT_MEMLOCK,
PosixRlimitType::RlimitAs => Resource::RLIMIT_AS,
PosixRlimitType::RlimitLocks => Resource::RLIMIT_LOCKS,
PosixRlimitType::RlimitSigpending => Resource::RLIMIT_SIGPENDING,
PosixRlimitType::RlimitMsgqueue => Resource::RLIMIT_MSGQUEUE,
PosixRlimitType::RlimitNice => Resource::RLIMIT_NICE,
PosixRlimitType::RlimitRtprio => Resource::RLIMIT_RTPRIO,
PosixRlimitType::RlimitRttime => Resource::RLIMIT_RTTIME,
}
}
// the validate_rootfs function is used to validate the rootfs of the container is
// as expected. This function is used in the no_pivot test to validate the rootfs
pub fn validate_rootfs() {