mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-02 21:47:29 +00:00
agent: add tests for get_memory_info function
Add test coverage for get_memory_info function in src/rpc.rs. Includes some minor refactoring of the function. Fixes #3837 Signed-off-by: Braden Rayhorn <bradenrayhorn@fastmail.com>
This commit is contained in:
parent
522eb8f3c3
commit
c088a3f3ad
@ -85,6 +85,8 @@ use std::path::PathBuf;
|
|||||||
const CONTAINER_BASE: &str = "/run/kata-containers";
|
const CONTAINER_BASE: &str = "/run/kata-containers";
|
||||||
const MODPROBE_PATH: &str = "/sbin/modprobe";
|
const MODPROBE_PATH: &str = "/sbin/modprobe";
|
||||||
|
|
||||||
|
const ERR_INVALID_BLOCK_SIZE: &str = "Invalid block size";
|
||||||
|
|
||||||
// Convenience macro to obtain the scope logger
|
// Convenience macro to obtain the scope logger
|
||||||
macro_rules! sl {
|
macro_rules! sl {
|
||||||
() => {
|
() => {
|
||||||
@ -1154,7 +1156,12 @@ impl protocols::agent_ttrpc::AgentService for AgentService {
|
|||||||
info!(sl!(), "get guest details!");
|
info!(sl!(), "get guest details!");
|
||||||
let mut resp = GuestDetailsResponse::new();
|
let mut resp = GuestDetailsResponse::new();
|
||||||
// to get memory block size
|
// to get memory block size
|
||||||
match get_memory_info(req.mem_block_size, req.mem_hotplug_probe) {
|
match get_memory_info(
|
||||||
|
req.mem_block_size,
|
||||||
|
req.mem_hotplug_probe,
|
||||||
|
SYSFS_MEMORY_BLOCK_SIZE_PATH,
|
||||||
|
SYSFS_MEMORY_HOTPLUG_PROBE_PATH,
|
||||||
|
) {
|
||||||
Ok((u, v)) => {
|
Ok((u, v)) => {
|
||||||
resp.mem_block_size_bytes = u;
|
resp.mem_block_size_bytes = u;
|
||||||
resp.support_mem_hotplug_probe = v;
|
resp.support_mem_hotplug_probe = v;
|
||||||
@ -1343,24 +1350,29 @@ impl protocols::health_ttrpc::Health for HealthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_memory_info(block_size: bool, hotplug: bool) -> Result<(u64, bool)> {
|
fn get_memory_info(
|
||||||
|
block_size: bool,
|
||||||
|
hotplug: bool,
|
||||||
|
block_size_path: &str,
|
||||||
|
hotplug_probe_path: &str,
|
||||||
|
) -> Result<(u64, bool)> {
|
||||||
let mut size: u64 = 0;
|
let mut size: u64 = 0;
|
||||||
let mut plug: bool = false;
|
let mut plug: bool = false;
|
||||||
if block_size {
|
if block_size {
|
||||||
match fs::read_to_string(SYSFS_MEMORY_BLOCK_SIZE_PATH) {
|
match fs::read_to_string(block_size_path) {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
if v.is_empty() {
|
if v.is_empty() {
|
||||||
info!(sl!(), "string in empty???");
|
warn!(sl!(), "file {} is empty", block_size_path);
|
||||||
return Err(anyhow!("Invalid block size"));
|
return Err(anyhow!(ERR_INVALID_BLOCK_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
size = u64::from_str_radix(v.trim(), 16).map_err(|_| {
|
size = u64::from_str_radix(v.trim(), 16).map_err(|_| {
|
||||||
warn!(sl!(), "failed to parse the str {} to hex", size);
|
warn!(sl!(), "failed to parse the str {} to hex", size);
|
||||||
anyhow!("Invalid block size")
|
anyhow!(ERR_INVALID_BLOCK_SIZE)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
info!(sl!(), "memory block size error: {:?}", e.kind());
|
warn!(sl!(), "memory block size error: {:?}", e.kind());
|
||||||
if e.kind() != std::io::ErrorKind::NotFound {
|
if e.kind() != std::io::ErrorKind::NotFound {
|
||||||
return Err(anyhow!(e));
|
return Err(anyhow!(e));
|
||||||
}
|
}
|
||||||
@ -1369,10 +1381,10 @@ fn get_memory_info(block_size: bool, hotplug: bool) -> Result<(u64, bool)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hotplug {
|
if hotplug {
|
||||||
match stat::stat(SYSFS_MEMORY_HOTPLUG_PROBE_PATH) {
|
match stat::stat(hotplug_probe_path) {
|
||||||
Ok(_) => plug = true,
|
Ok(_) => plug = true,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
info!(sl!(), "hotplug memory error: {:?}", e);
|
warn!(sl!(), "hotplug memory error: {:?}", e);
|
||||||
match e {
|
match e {
|
||||||
nix::Error::ENOENT => plug = false,
|
nix::Error::ENOENT => plug = false,
|
||||||
_ => return Err(anyhow!(e)),
|
_ => return Err(anyhow!(e)),
|
||||||
@ -1803,8 +1815,35 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::protocols::agent_ttrpc::AgentService as _;
|
use crate::protocols::agent_ttrpc::AgentService as _;
|
||||||
use oci::{Hook, Hooks};
|
use oci::{Hook, Hooks};
|
||||||
|
use tempfile::tempdir;
|
||||||
use ttrpc::{r#async::TtrpcContext, MessageHeader};
|
use ttrpc::{r#async::TtrpcContext, MessageHeader};
|
||||||
|
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// 1: expected Result
|
||||||
|
// 2: actual Result
|
||||||
|
// 3: string used to identify the test on error
|
||||||
|
macro_rules! assert_result {
|
||||||
|
($expected_result:expr, $actual_result:expr, $msg:expr) => {
|
||||||
|
if $expected_result.is_ok() {
|
||||||
|
let expected_level = $expected_result.as_ref().unwrap();
|
||||||
|
let actual_level = $actual_result.unwrap();
|
||||||
|
assert!(*expected_level == actual_level, "{}", $msg);
|
||||||
|
} else {
|
||||||
|
let expected_error = $expected_result.as_ref().unwrap_err();
|
||||||
|
let expected_error_msg = format!("{:?}", expected_error);
|
||||||
|
|
||||||
|
if let Err(actual_error) = $actual_result {
|
||||||
|
let actual_error_msg = format!("{:?}", actual_error);
|
||||||
|
|
||||||
|
assert!(expected_error_msg == actual_error_msg, "{}", $msg);
|
||||||
|
} else {
|
||||||
|
assert!(expected_error_msg == "expected error, got OK", "{}", $msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn mk_ttrpc_context() -> TtrpcContext {
|
fn mk_ttrpc_context() -> TtrpcContext {
|
||||||
TtrpcContext {
|
TtrpcContext {
|
||||||
fd: -1,
|
fd: -1,
|
||||||
@ -1906,6 +1945,119 @@ mod tests {
|
|||||||
assert!(result.is_err(), "expected add arp neighbors to fail");
|
assert!(result.is_err(), "expected add arp neighbors to fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_memory_info() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TestData<'a> {
|
||||||
|
// if None is provided, no file will be generated, else the data in the Option will populate the file
|
||||||
|
block_size_data: Option<&'a str>,
|
||||||
|
|
||||||
|
hotplug_probe_data: bool,
|
||||||
|
get_block_size: bool,
|
||||||
|
get_hotplug: bool,
|
||||||
|
result: Result<(u64, bool)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let tests = &[
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("10000000"),
|
||||||
|
hotplug_probe_data: true,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: true,
|
||||||
|
result: Ok((268435456, true)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("100"),
|
||||||
|
hotplug_probe_data: false,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: true,
|
||||||
|
result: Ok((256, false)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: None,
|
||||||
|
hotplug_probe_data: false,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: true,
|
||||||
|
result: Ok((0, false)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some(""),
|
||||||
|
hotplug_probe_data: false,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: false,
|
||||||
|
result: Err(anyhow!(ERR_INVALID_BLOCK_SIZE)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("-1"),
|
||||||
|
hotplug_probe_data: false,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: false,
|
||||||
|
result: Err(anyhow!(ERR_INVALID_BLOCK_SIZE)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some(" "),
|
||||||
|
hotplug_probe_data: false,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: false,
|
||||||
|
result: Err(anyhow!(ERR_INVALID_BLOCK_SIZE)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("some data"),
|
||||||
|
hotplug_probe_data: false,
|
||||||
|
get_block_size: true,
|
||||||
|
get_hotplug: false,
|
||||||
|
result: Err(anyhow!(ERR_INVALID_BLOCK_SIZE)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("some data"),
|
||||||
|
hotplug_probe_data: true,
|
||||||
|
get_block_size: false,
|
||||||
|
get_hotplug: false,
|
||||||
|
result: Ok((0, false)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("100"),
|
||||||
|
hotplug_probe_data: true,
|
||||||
|
get_block_size: false,
|
||||||
|
get_hotplug: false,
|
||||||
|
result: Ok((0, false)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
block_size_data: Some("100"),
|
||||||
|
hotplug_probe_data: true,
|
||||||
|
get_block_size: false,
|
||||||
|
get_hotplug: true,
|
||||||
|
result: Ok((0, true)),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (i, d) in tests.iter().enumerate() {
|
||||||
|
let msg = format!("test[{}]: {:?}", i, d);
|
||||||
|
|
||||||
|
let dir = tempdir().expect("failed to make tempdir");
|
||||||
|
let block_size_path = dir.path().join("block_size_bytes");
|
||||||
|
let hotplug_probe_path = dir.path().join("probe");
|
||||||
|
|
||||||
|
if let Some(block_size_data) = d.block_size_data {
|
||||||
|
fs::write(&block_size_path, block_size_data).unwrap();
|
||||||
|
}
|
||||||
|
if d.hotplug_probe_data {
|
||||||
|
fs::write(&hotplug_probe_path, []).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = get_memory_info(
|
||||||
|
d.get_block_size,
|
||||||
|
d.get_hotplug,
|
||||||
|
block_size_path.to_str().unwrap(),
|
||||||
|
hotplug_probe_path.to_str().unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let msg = format!("{}, result: {:?}", msg, result);
|
||||||
|
|
||||||
|
assert_result!(d.result, result, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_verify_cid() {
|
async fn test_verify_cid() {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
Loading…
Reference in New Issue
Block a user