Skip to content

Commit

Permalink
Merge pull request #4137 from Shensd/sandbox-tests-online_resources
Browse files Browse the repository at this point in the history
agent: add test coverage for functions find_process and online_resources
  • Loading branch information
jodh-intel committed May 6, 2022
2 parents e2f68c6 + 475e3bf commit 79d93f1
Showing 1 changed file with 257 additions and 1 deletion.
258 changes: 257 additions & 1 deletion src/agent/src/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ fn online_memory(logger: &Logger) -> Result<()> {

#[cfg(test)]
mod tests {
use super::Sandbox;
use super::*;
use crate::{mount::baremount, skip_if_not_root};
use anyhow::{anyhow, Error};
use nix::mount::MsFlags;
Expand All @@ -480,6 +480,7 @@ mod tests {
use rustjail::specconv::CreateOpts;
use slog::Logger;
use std::fs::{self, File};
use std::io::prelude::*;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use tempfile::{tempdir, Builder, TempDir};
Expand Down Expand Up @@ -847,4 +848,259 @@ mod tests {
let p = s.find_container_process("not-exist-cid", "");
assert!(p.is_err(), "Expecting Error, Got {:?}", p);
}

#[tokio::test]
async fn test_find_process() {
let logger = slog::Logger::root(slog::Discard, o!());

let test_pids = [std::i32::MIN, -1, 0, 1, std::i32::MAX];

for test_pid in test_pids {
let mut s = Sandbox::new(&logger).unwrap();
let (mut linux_container, _root) = create_linuxcontainer();

let mut test_process = Process::new(
&logger,
&oci::Process::default(),
"this_is_a_test_process",
true,
1,
)
.unwrap();
// processes interally only have pids when manually set
test_process.pid = test_pid;

linux_container.processes.insert(test_pid, test_process);

s.add_container(linux_container);

let find_result = s.find_process(test_pid);

// test first if it finds anything
assert!(find_result.is_some(), "Should be able to find a process");

let found_process = find_result.unwrap();

// then test if it founds the correct process
assert_eq!(
found_process.pid, test_pid,
"Should be able to find correct process"
);
}

// to test for nonexistent pids, any pid that isn't the one set
// above should work, as linuxcontainer starts with no processes
let mut s = Sandbox::new(&logger).unwrap();

let nonexistent_test_pid = 1234;

let find_result = s.find_process(nonexistent_test_pid);

assert!(
find_result.is_none(),
"Shouldn't find a process for non existent pid"
);
}

#[tokio::test]
async fn test_online_resources() {
#[derive(Debug, Default)]
struct TestFile {
name: String,
content: String,
}

#[derive(Debug, Default)]
struct TestDirectory<'a> {
name: String,
files: &'a [TestFile],
}

#[derive(Debug)]
struct TestData<'a> {
directory_autogen_name: String,
number_autogen_directories: u32,

extra_directories: &'a [TestDirectory<'a>],
pattern: String,
to_enable: i32,

result: Result<i32>,
}

impl Default for TestData<'_> {
fn default() -> Self {
TestData {
directory_autogen_name: Default::default(),
number_autogen_directories: Default::default(),
extra_directories: Default::default(),
pattern: Default::default(),
to_enable: Default::default(),
result: Ok(Default::default()),
}
}
}

let tests = &[
// 4 well formed directories, request enabled 4,
// correct result 4 enabled, should pass
TestData {
directory_autogen_name: String::from("cpu"),
number_autogen_directories: 4,
pattern: String::from(r"cpu[0-9]+"),
to_enable: 4,
result: Ok(4),
..Default::default()
},
// 0 well formed directories, request enabled 4,
// correct result 0 enabled, should pass
TestData {
number_autogen_directories: 0,
to_enable: 4,
result: Ok(0),
..Default::default()
},
// 10 well formed directories, request enabled 4,
// correct result 4 enabled, should pass
TestData {
directory_autogen_name: String::from("cpu"),
number_autogen_directories: 10,
pattern: String::from(r"cpu[0-9]+"),
to_enable: 4,
result: Ok(4),
..Default::default()
},
// 0 well formed directories, request enabled 0,
// correct result 0 enabled, should pass
TestData {
number_autogen_directories: 0,
pattern: String::from(r"cpu[0-9]+"),
to_enable: 0,
result: Ok(0),
..Default::default()
},
// 4 well formed directories, 1 malformed (no online file),
// request enable 5, correct result 4
TestData {
directory_autogen_name: String::from("cpu"),
number_autogen_directories: 4,
pattern: String::from(r"cpu[0-9]+"),
extra_directories: &[TestDirectory {
name: String::from("cpu4"),
files: &[],
}],
to_enable: 5,
result: Ok(4),
},
// 3 malformed directories (no online files),
// request enable 3, correct result 0
TestData {
pattern: String::from(r"cpu[0-9]+"),
extra_directories: &[
TestDirectory {
name: String::from("cpu0"),
files: &[],
},
TestDirectory {
name: String::from("cpu1"),
files: &[],
},
TestDirectory {
name: String::from("cpu2"),
files: &[],
},
],
to_enable: 3,
result: Ok(0),
..Default::default()
},
// 1 malformed directories (online file with content "1"),
// request enable 1, correct result 0
TestData {
pattern: String::from(r"cpu[0-9]+"),
extra_directories: &[TestDirectory {
name: String::from("cpu0"),
files: &[TestFile {
name: SYSFS_ONLINE_FILE.to_string(),
content: String::from("1"),
}],
}],
to_enable: 1,
result: Ok(0),
..Default::default()
},
// 2 well formed directories, 1 malformed (online file with content "1"),
// request enable 3, correct result 2
TestData {
directory_autogen_name: String::from("cpu"),
number_autogen_directories: 2,
pattern: String::from(r"cpu[0-9]+"),
extra_directories: &[TestDirectory {
name: String::from("cpu2"),
files: &[TestFile {
name: SYSFS_ONLINE_FILE.to_string(),
content: String::from("1"),
}],
}],
to_enable: 3,
result: Ok(2),
},
];

let logger = slog::Logger::root(slog::Discard, o!());
let tmpdir = Builder::new().tempdir().unwrap();
let tmpdir_path = tmpdir.path().to_str().unwrap();

for (i, d) in tests.iter().enumerate() {
let current_test_dir_path = format!("{}/test_{}", tmpdir_path, i);
fs::create_dir(&current_test_dir_path).unwrap();

// create numbered directories and fill using root name
for j in 0..d.number_autogen_directories {
let subdir_path = format!(
"{}/{}{}",
current_test_dir_path, d.directory_autogen_name, j
);
let subfile_path = format!("{}/{}", subdir_path, SYSFS_ONLINE_FILE);
fs::create_dir(&subdir_path).unwrap();
let mut subfile = File::create(subfile_path).unwrap();
subfile.write_all(b"0").unwrap();
}
// create extra directories and fill to specification
for j in d.extra_directories {
let subdir_path = format!("{}/{}", current_test_dir_path, j.name);
fs::create_dir(&subdir_path).unwrap();
for file in j.files {
let subfile_path = format!("{}/{}", subdir_path, file.name);
let mut subfile = File::create(&subfile_path).unwrap();
subfile.write_all(file.content.as_bytes()).unwrap();
}
}

// run created directory structure against online_resources
let result = online_resources(&logger, &current_test_dir_path, &d.pattern, d.to_enable);

let mut msg = format!(
"test[{}]: {:?}, expected {}, actual {}",
i,
d,
d.result.is_ok(),
result.is_ok()
);

assert_eq!(result.is_ok(), d.result.is_ok(), "{}", msg);

if d.result.is_ok() {
let test_result_val = *d.result.as_ref().ok().unwrap();
let result_val = result.ok().unwrap();

msg = format!(
"test[{}]: {:?}, expected {}, actual {}",
i, d, test_result_val, result_val
);

assert_eq!(test_result_val, result_val, "{}", msg);
}
}
}
}

0 comments on commit 79d93f1

Please sign in to comment.