diff --git a/youki_integration_test/src/main.rs b/youki_integration_test/src/main.rs index fa461ca51..695b0eb1d 100644 --- a/youki_integration_test/src/main.rs +++ b/youki_integration_test/src/main.rs @@ -2,6 +2,7 @@ mod tests; mod utils; use crate::tests::lifecycle::{ContainerCreate, ContainerLifecycle}; +use crate::tests::pidfile::get_pidfile_test; use crate::tests::tlb::get_tlb_test; use crate::utils::support::set_runtime_path; use anyhow::Result; @@ -58,10 +59,12 @@ fn main() -> Result<()> { let cl = ContainerLifecycle::new(); let cc = ContainerCreate::new(); let huge_tlb = get_tlb_test(); + let pidfile = get_pidfile_test(); tm.add_test_group(&cl); tm.add_test_group(&cc); tm.add_test_group(&huge_tlb); + tm.add_test_group(&pidfile); if let Some(tests) = opts.tests { let tests_to_run = parse_tests(&tests); diff --git a/youki_integration_test/src/tests/mod.rs b/youki_integration_test/src/tests/mod.rs index 21dec095b..368f21f61 100644 --- a/youki_integration_test/src/tests/mod.rs +++ b/youki_integration_test/src/tests/mod.rs @@ -1,2 +1,3 @@ pub mod lifecycle; +pub mod pidfile; pub mod tlb; diff --git a/youki_integration_test/src/tests/pidfile/mod.rs b/youki_integration_test/src/tests/pidfile/mod.rs new file mode 100644 index 000000000..0f655637f --- /dev/null +++ b/youki_integration_test/src/tests/pidfile/mod.rs @@ -0,0 +1,2 @@ +mod pidfile_test; +pub use pidfile_test::get_pidfile_test; diff --git a/youki_integration_test/src/tests/pidfile/pidfile_test.rs b/youki_integration_test/src/tests/pidfile/pidfile_test.rs new file mode 100644 index 000000000..9680cff74 --- /dev/null +++ b/youki_integration_test/src/tests/pidfile/pidfile_test.rs @@ -0,0 +1,96 @@ +use crate::utils::{ + create_temp_dir, delete_container, generate_uuid, get_runtime_path, get_state, kill_container, + prepare_bundle, State, TempDir, +}; +use anyhow::anyhow; +use std::process::{Command, Stdio}; +use test_framework::{Test, TestGroup, TestResult}; +use uuid::Uuid; + +#[inline] +fn cleanup(id: &Uuid, bundle: &TempDir) { + kill_container(id, bundle).unwrap().wait().unwrap(); + delete_container(id, bundle).unwrap().wait().unwrap(); +} + +// here we have to manually create and manage the container +// as the test_inside container does not provide a way to set the pid file argument +fn test_pidfile() -> TestResult { + // create id for the container and pidfile + let container_id = generate_uuid(); + let pidfile_uuid = generate_uuid(); + + // create temp dir for bundle and for storing the pid + let bundle = prepare_bundle(&container_id).unwrap(); + let pidfile_dir = create_temp_dir(&pidfile_uuid).unwrap(); + + // start the container + Command::new(get_runtime_path()) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .arg("--root") + .arg(bundle.as_ref().join("runtime")) + .arg("create") + .arg(container_id.to_string()) + .arg("--bundle") + .arg(bundle.as_ref().join("bundle")) + .arg("--pid-file") + .arg(pidfile_dir.as_ref().join("pidfile")) + .spawn() + .unwrap() + .wait() + .unwrap(); + + let (out, err) = get_state(&container_id, &bundle).unwrap(); + + if !err.is_empty() { + cleanup(&container_id, &bundle); + return TestResult::Err(anyhow!("Error in state : {}", err)); + } + + let state: State = serde_json::from_str(&out).unwrap(); + + if state.id != container_id.to_string() { + cleanup(&container_id, &bundle); + return TestResult::Err(anyhow!( + "Error in state : ID not matched ,expected {} got {}", + container_id, + state.id + )); + } + + if state.status != "created" { + cleanup(&container_id, &bundle); + return TestResult::Err(anyhow!( + "Error in state : Status not matched ,expected 'created' got {}", + state.status + )); + } + + // get pid from the pidfile + let pidfile: i32 = std::fs::read_to_string(pidfile_dir.as_ref().join("pidfile")) + .unwrap() + .parse() + .unwrap(); + + // get pid from the state + if state.pid.unwrap() != pidfile { + cleanup(&container_id, &bundle); + return TestResult::Err(anyhow!( + "Error : Pid not matched ,expected {} as per state, but got {} from pidfile instead", + state.pid.unwrap(), + pidfile + )); + } + + cleanup(&container_id, &bundle); + TestResult::Ok +} + +pub fn get_pidfile_test<'a>() -> TestGroup<'a> { + let pidfile = Test::new("pidfile", Box::new(test_pidfile)); + let mut tg = TestGroup::new("pidfile"); + tg.add(vec![Box::new(pidfile)]); + tg +} diff --git a/youki_integration_test/src/utils/mod.rs b/youki_integration_test/src/utils/mod.rs index ea69b010f..e173ff097 100644 --- a/youki_integration_test/src/utils/mod.rs +++ b/youki_integration_test/src/utils/mod.rs @@ -7,5 +7,5 @@ pub use support::{ pub use temp_dir::{create_temp_dir, TempDir}; pub use test_utils::{ create_container, delete_container, get_state, kill_container, test_outside_container, - ContainerData, + ContainerData, State, };