Skip to content

Commit

Permalink
Merge pull request #2646 from lengrongfu/test/io-priority
Browse files Browse the repository at this point in the history
add io priority e2e test
  • Loading branch information
YJDoc2 authored Feb 20, 2024
2 parents 477bee2 + 10a06f1 commit 660a242
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 1 deletion.
3 changes: 3 additions & 0 deletions tests/contest/contest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::tests::example::get_example_test;
use crate::tests::hooks::get_hooks_tests;
use crate::tests::hostname::get_hostname_test;
use crate::tests::intel_rdt::get_intel_rdt_test;
use crate::tests::io_priority::get_io_priority_test;
use crate::tests::lifecycle::{ContainerCreate, ContainerLifecycle};
use crate::tests::linux_ns_itype::get_ns_itype_tests;
use crate::tests::mounts_recursive::get_mounts_recursive_test;
Expand Down Expand Up @@ -107,6 +108,7 @@ fn main() -> Result<()> {
let intel_rdt = get_intel_rdt_test();
let sysctl = get_sysctl_test();
let scheduler = get_scheduler_test();
let io_priority_test = get_io_priority_test();

tm.add_test_group(Box::new(cl));
tm.add_test_group(Box::new(cc));
Expand All @@ -130,6 +132,7 @@ fn main() -> Result<()> {
tm.add_test_group(Box::new(sysctl));
tm.add_test_group(Box::new(scheduler));

tm.add_test_group(Box::new(io_priority_test));
tm.add_cleanup(Box::new(cgroups::cleanup_v1));
tm.add_cleanup(Box::new(cgroups::cleanup_v2));

Expand Down
78 changes: 78 additions & 0 deletions tests/contest/contest/src/tests/io_priority/io_priority_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use crate::utils::test_inside_container;
use anyhow::{Context, Result};
use oci_spec::runtime::{
IOPriorityClass, LinuxIOPriorityBuilder, ProcessBuilder, Spec, SpecBuilder,
};
use test_framework::{test_result, Test, TestGroup, TestResult};

fn create_spec(
io_priority_class: IOPriorityClass,
execute_test: &str,
priority: i64,
) -> Result<Spec> {
let io_p = LinuxIOPriorityBuilder::default()
.class(io_priority_class)
.priority(priority)
.build()
.unwrap();
SpecBuilder::default()
.process(
ProcessBuilder::default()
.args(
["runtimetest", execute_test]
.iter()
.map(|s| s.to_string())
.collect::<Vec<String>>(),
)
.io_priority(io_p)
.build()?,
)
.build()
.context("failed to create spec")
}

fn io_priority_class_rt_test() -> TestResult {
let spec = test_result!(create_spec(
IOPriorityClass::IoprioClassRt,
"io_priority_class_rt",
1,
));
test_inside_container(spec, &|_| Ok(()))
}

fn io_priority_class_be_test() -> TestResult {
let spec = test_result!(create_spec(
IOPriorityClass::IoprioClassBe,
"io_priority_class_be",
2,
));
test_inside_container(spec, &|_| Ok(()))
}

fn io_priority_class_idle_test() -> TestResult {
let spec = test_result!(create_spec(
IOPriorityClass::IoprioClassIdle,
"io_priority_class_idle",
3,
));
test_inside_container(spec, &|_| Ok(()))
}

pub fn get_io_priority_test() -> TestGroup {
let mut io_priority_group = TestGroup::new("set_io_priority");
let io_priority_class_rt =
Test::new("io_priority_class_rt", Box::new(io_priority_class_rt_test));
let io_priority_class_be =
Test::new("io_priority_class_be", Box::new(io_priority_class_be_test));
let io_priority_class_idle = Test::new(
"io_priority_class_idle",
Box::new(io_priority_class_idle_test),
);

io_priority_group.add(vec![
Box::new(io_priority_class_rt),
Box::new(io_priority_class_be),
Box::new(io_priority_class_idle),
]);
io_priority_group
}
3 changes: 3 additions & 0 deletions tests/contest/contest/src/tests/io_priority/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod io_priority_test;

pub use io_priority_test::get_io_priority_test;
1 change: 1 addition & 0 deletions tests/contest/contest/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod example;
pub mod hooks;
pub mod hostname;
pub mod intel_rdt;
pub mod io_priority;
pub mod lifecycle;
pub mod linux_ns_itype;
pub mod mounts_recursive;
Expand Down
4 changes: 4 additions & 0 deletions tests/contest/runtimetest/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod tests;
mod utils;

use oci_spec::runtime::IOPriorityClass::{IoprioClassBe, IoprioClassIdle, IoprioClassRt};
use oci_spec::runtime::Spec;
use std::env;
use std::path::PathBuf;
Expand Down Expand Up @@ -38,6 +39,9 @@ fn main() {
"sysctl" => tests::validate_sysctl(&spec),
"scheduler_policy_other" => tests::validate_scheduler_policy(&spec),
"scheduler_policy_batch" => tests::validate_scheduler_policy(&spec),
"io_priority_class_rt" => tests::test_io_priority_class(&spec, IoprioClassRt),
"io_priority_class_be" => tests::test_io_priority_class(&spec, IoprioClassBe),
"io_priority_class_idle" => tests::test_io_priority_class(&spec, IoprioClassIdle),
_ => eprintln!("error due to unexpected execute test name: {execute_test}"),
}
}
58 changes: 57 additions & 1 deletion tests/contest/runtimetest/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::utils::{self, test_read_access, test_write_access};
use anyhow::{bail, Result};
use nix::libc;
use nix::{errno::Errno, sys::utsname, unistd::getcwd};
use oci_spec::runtime::{LinuxSchedulerPolicy, Spec};
use oci_spec::runtime::{
IOPriorityClass::{self, IoprioClassBe, IoprioClassIdle, IoprioClassRt},
LinuxSchedulerPolicy, Spec,
};
use std::fs::{self, read_dir};
use std::mem;
use std::path::Path;
Expand Down Expand Up @@ -376,3 +380,55 @@ pub fn validate_scheduler_policy(spec: &Spec) {
eprintln!("error due to sched_nice want {want_sn}, got {sn}")
}
}

pub fn test_io_priority_class(spec: &Spec, io_priority_class: IOPriorityClass) {
let io_priority_spec = spec
.process()
.as_ref()
.unwrap()
.io_priority()
.as_ref()
.unwrap();
if io_priority_spec.class() != io_priority_class {
let io_class = io_priority_spec.class();
return eprintln!("error io_priority class want {io_priority_class:?}, got {io_class:?}");
}

let io_priority_who_progress: libc::c_int = 1;
let io_priority_who_pid = 0;
let res = unsafe {
libc::syscall(
libc::SYS_ioprio_get,
io_priority_who_progress,
io_priority_who_pid,
)
};
if let Err(e) = Errno::result(res) {
return eprintln!("error ioprio_get error {e}");
}

// ref: https://docs.kernel.org/block/ioprio.html
let class = res as u16 >> 13;
let priority = res as u16 & 0xFF;

let expected_class = match io_priority_class {
IoprioClassRt => 1,
IoprioClassBe => 2,
IoprioClassIdle => 3,
};
if class != expected_class {
return eprintln!(
"error ioprio_get class expected {io_priority_class:?} ({expected_class}), got {class}"
);
}

// these number mappings are arbitrary, we set the priority in test cases io_priority_test.rs file
let expected_priority = match io_priority_class {
IoprioClassRt => 1,
IoprioClassBe => 2,
IoprioClassIdle => 3,
};
if priority != expected_priority {
eprintln!("error ioprio_get expected priority {expected_priority:?}, got {priority}")
}
}

0 comments on commit 660a242

Please sign in to comment.