mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-27 15:57:09 +00:00
libs/test-utils: share test code by create a new crate
More and more Rust code is introduced, the test utils original in agent should be made easy to share, move it into a new crate will make it easy to share between different crates. Fixes: #4925 Signed-off-by: Bin Liu <bin@hyper.sh>
This commit is contained in:
parent
334c7b3355
commit
34746496b7
8
src/agent/Cargo.lock
generated
8
src/agent/Cargo.lock
generated
@ -651,6 +651,7 @@ dependencies = [
|
|||||||
"slog-stdlog",
|
"slog-stdlog",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
"test-utils",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-vsock",
|
"tokio-vsock",
|
||||||
@ -1769,6 +1770,13 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "test-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nix 0.24.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
|
@ -66,6 +66,7 @@ clap = { version = "3.0.1", features = ["derive"] }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
test-utils = { path = "../libs/test-utils" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
@ -432,7 +432,7 @@ fn get_container_pipe_size(param: &str) -> Result<i32> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::assert_result;
|
use test_utils::assert_result;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
@ -49,8 +49,6 @@ mod pci;
|
|||||||
pub mod random;
|
pub mod random;
|
||||||
mod sandbox;
|
mod sandbox;
|
||||||
mod signal;
|
mod signal;
|
||||||
#[cfg(test)]
|
|
||||||
mod test_utils;
|
|
||||||
mod uevent;
|
mod uevent;
|
||||||
mod util;
|
mod util;
|
||||||
mod version;
|
mod version;
|
||||||
@ -401,7 +399,8 @@ use std::os::unix::io::{FromRawFd, RawFd};
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test_utils::test_utils::TestUserType;
|
use test_utils::TestUserType;
|
||||||
|
use test_utils::{assert_result, skip_if_not_root, skip_if_root};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_create_logger_task() {
|
async fn test_create_logger_task() {
|
||||||
|
@ -1016,8 +1016,6 @@ fn parse_options(option_list: Vec<String>) -> HashMap<String, String> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test_utils::test_utils::TestUserType;
|
|
||||||
use crate::{skip_if_not_root, skip_loop_by_user, skip_loop_if_not_root, skip_loop_if_root};
|
|
||||||
use protobuf::RepeatedField;
|
use protobuf::RepeatedField;
|
||||||
use protocols::agent::FSGroup;
|
use protocols::agent::FSGroup;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@ -1025,6 +1023,10 @@ mod tests {
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
use test_utils::TestUserType;
|
||||||
|
use test_utils::{
|
||||||
|
skip_if_not_root, skip_loop_by_user, skip_loop_if_not_root, skip_loop_if_root,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mount() {
|
fn test_mount() {
|
||||||
|
@ -187,9 +187,10 @@ impl fmt::Debug for NamespaceType {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Namespace, NamespaceType};
|
use super::{Namespace, NamespaceType};
|
||||||
use crate::{mount::remove_mounts, skip_if_not_root};
|
use crate::mount::remove_mounts;
|
||||||
use nix::sched::CloneFlags;
|
use nix::sched::CloneFlags;
|
||||||
use tempfile::Builder;
|
use tempfile::Builder;
|
||||||
|
use test_utils::skip_if_not_root;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_setup_persistent_ns() {
|
async fn test_setup_persistent_ns() {
|
||||||
|
@ -724,10 +724,10 @@ impl Address {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::skip_if_not_root;
|
|
||||||
use rtnetlink::packet;
|
use rtnetlink::packet;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use test_utils::skip_if_not_root;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_link_by_name() {
|
async fn find_link_by_name() {
|
||||||
|
@ -76,11 +76,11 @@ fn do_setup_guest_dns(logger: Logger, dns_list: Vec<String>, src: &str, dst: &st
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::skip_if_not_root;
|
|
||||||
use nix::mount;
|
use nix::mount;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
use test_utils::skip_if_not_root;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_guest_dns() {
|
fn test_setup_guest_dns() {
|
||||||
|
@ -53,9 +53,9 @@ pub fn reseed_rng(data: &[u8]) -> Result<()> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::skip_if_not_root;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
use test_utils::skip_if_not_root;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reseed_rng() {
|
fn test_reseed_rng() {
|
||||||
|
@ -1987,14 +1987,12 @@ fn load_kernel_module(module: &protocols::agent::KernelModule) -> Result<()> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{namespace::Namespace, protocols::agent_ttrpc_async::AgentService as _};
|
||||||
assert_result, namespace::Namespace, protocols::agent_ttrpc_async::AgentService as _,
|
|
||||||
skip_if_not_root,
|
|
||||||
};
|
|
||||||
use nix::mount;
|
use nix::mount;
|
||||||
use nix::sched::{unshare, CloneFlags};
|
use nix::sched::{unshare, CloneFlags};
|
||||||
use oci::{Hook, Hooks, Linux, LinuxNamespace};
|
use oci::{Hook, Hooks, Linux, LinuxNamespace};
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
|
use test_utils::{assert_result, skip_if_not_root};
|
||||||
use ttrpc::{r#async::TtrpcContext, MessageHeader};
|
use ttrpc::{r#async::TtrpcContext, MessageHeader};
|
||||||
|
|
||||||
fn mk_ttrpc_context() -> TtrpcContext {
|
fn mk_ttrpc_context() -> TtrpcContext {
|
||||||
|
@ -471,7 +471,7 @@ fn online_memory(logger: &Logger) -> Result<()> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{mount::baremount, skip_if_not_root};
|
use crate::mount::baremount;
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use nix::mount::MsFlags;
|
use nix::mount::MsFlags;
|
||||||
use oci::{Linux, Root, Spec};
|
use oci::{Linux, Root, Spec};
|
||||||
@ -484,6 +484,7 @@ mod tests {
|
|||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use tempfile::{tempdir, Builder, TempDir};
|
use tempfile::{tempdir, Builder, TempDir};
|
||||||
|
use test_utils::skip_if_not_root;
|
||||||
|
|
||||||
fn bind_mount(src: &str, dst: &str, logger: &Logger) -> Result<(), Error> {
|
fn bind_mount(src: &str, dst: &str, logger: &Logger) -> Result<(), Error> {
|
||||||
let src_path = Path::new(src);
|
let src_path = Path::new(src);
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
// Copyright (c) 2019 Intel Corporation
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
#![allow(clippy::module_inception)]
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod test_utils {
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum TestUserType {
|
|
||||||
RootOnly,
|
|
||||||
NonRootOnly,
|
|
||||||
Any,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! skip_if_root {
|
|
||||||
() => {
|
|
||||||
if nix::unistd::Uid::effective().is_root() {
|
|
||||||
println!("INFO: skipping {} which needs non-root", module_path!());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! skip_if_not_root {
|
|
||||||
() => {
|
|
||||||
if !nix::unistd::Uid::effective().is_root() {
|
|
||||||
println!("INFO: skipping {} which needs root", module_path!());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! skip_loop_if_root {
|
|
||||||
($msg:expr) => {
|
|
||||||
if nix::unistd::Uid::effective().is_root() {
|
|
||||||
println!(
|
|
||||||
"INFO: skipping loop {} in {} which needs non-root",
|
|
||||||
$msg,
|
|
||||||
module_path!()
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! skip_loop_if_not_root {
|
|
||||||
($msg:expr) => {
|
|
||||||
if !nix::unistd::Uid::effective().is_root() {
|
|
||||||
println!(
|
|
||||||
"INFO: skipping loop {} in {} which needs root",
|
|
||||||
$msg,
|
|
||||||
module_path!()
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parameters:
|
|
||||||
//
|
|
||||||
// 1: expected Result
|
|
||||||
// 2: actual Result
|
|
||||||
// 3: string used to identify the test on error
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! assert_result {
|
|
||||||
($expected_result:expr, $actual_result:expr, $msg:expr) => {
|
|
||||||
if $expected_result.is_ok() {
|
|
||||||
let expected_value = $expected_result.as_ref().unwrap();
|
|
||||||
let actual_value = $actual_result.unwrap();
|
|
||||||
assert!(*expected_value == actual_value, "{}", $msg);
|
|
||||||
} else {
|
|
||||||
assert!($actual_result.is_err(), "{}", $msg);
|
|
||||||
|
|
||||||
let expected_error = $expected_result.as_ref().unwrap_err();
|
|
||||||
let expected_error_msg = format!("{:?}", expected_error);
|
|
||||||
|
|
||||||
let actual_error_msg = format!("{:?}", $actual_result.unwrap_err());
|
|
||||||
|
|
||||||
assert!(expected_error_msg == actual_error_msg, "{}", $msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! skip_loop_by_user {
|
|
||||||
($msg:expr, $user:expr) => {
|
|
||||||
if $user == TestUserType::RootOnly {
|
|
||||||
skip_loop_if_not_root!($msg);
|
|
||||||
} else if $user == TestUserType::NonRootOnly {
|
|
||||||
skip_loop_if_root!($msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -528,10 +528,10 @@ impl BindWatcher {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::mount::is_mounted;
|
use crate::mount::is_mounted;
|
||||||
use crate::skip_if_not_root;
|
|
||||||
use nix::unistd::{Gid, Uid};
|
use nix::unistd::{Gid, Uid};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
use test_utils::skip_if_not_root;
|
||||||
|
|
||||||
async fn create_test_storage(dir: &Path, id: &str) -> Result<(protos::Storage, PathBuf)> {
|
async fn create_test_storage(dir: &Path, id: &str) -> Result<(protos::Storage, PathBuf)> {
|
||||||
let src_path = dir.join(format!("src{}", id));
|
let src_path = dir.join(format!("src{}", id));
|
||||||
|
7
src/libs/Cargo.lock
generated
7
src/libs/Cargo.lock
generated
@ -1021,6 +1021,13 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "test-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nix 0.24.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.30"
|
version = "1.0.30"
|
||||||
|
@ -6,5 +6,6 @@ members = [
|
|||||||
"safe-path",
|
"safe-path",
|
||||||
"protocols",
|
"protocols",
|
||||||
"oci",
|
"oci",
|
||||||
|
"test-utils",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
@ -10,3 +10,4 @@ Currently it provides following library crates:
|
|||||||
| [system utilities](kata-sys-util/) | Collection of facilities and helpers to access system services. |
|
| [system utilities](kata-sys-util/) | Collection of facilities and helpers to access system services. |
|
||||||
| [types](kata-types/) | Collection of constants and data types shared by multiple Kata Containers components. |
|
| [types](kata-types/) | Collection of constants and data types shared by multiple Kata Containers components. |
|
||||||
| [safe-path](safe-path/) | Utilities to safely resolve filesystem paths. |
|
| [safe-path](safe-path/) | Utilities to safely resolve filesystem paths. |
|
||||||
|
| [test utilities](test-utils/) | Utilities to share test code. |
|
||||||
|
15
src/libs/test-utils/Cargo.toml
Normal file
15
src/libs/test-utils/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "test-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A library for test Rust code"
|
||||||
|
keywords = ["kata", "container", "test", "utils"]
|
||||||
|
categories = ["testing"]
|
||||||
|
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"]
|
||||||
|
repository = "https://github.com/kata-containers/kata-containers.git"
|
||||||
|
homepage = "https://katacontainers.io/"
|
||||||
|
readme = "README.md"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nix = "0.24.2"
|
8
src/libs/test-utils/README.md
Normal file
8
src/libs/test-utils/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
Test Utilities
|
||||||
|
====================
|
||||||
|
|
||||||
|
A library to share test code for Rust.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This code is licensed under [Apache-2.0](../../../LICENSE).
|
119
src/libs/test-utils/src/lib.rs
Normal file
119
src/libs/test-utils/src/lib.rs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright (c) 2019 Intel Corporation
|
||||||
|
// Copyright (c) 2022 Ant Group
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum TestUserType {
|
||||||
|
RootOnly,
|
||||||
|
NonRootOnly,
|
||||||
|
Any,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! skip_if_root {
|
||||||
|
() => {
|
||||||
|
if nix::unistd::Uid::effective().is_root() {
|
||||||
|
println!("INFO: skipping {} which needs non-root", module_path!());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! skip_if_not_root {
|
||||||
|
() => {
|
||||||
|
if !nix::unistd::Uid::effective().is_root() {
|
||||||
|
println!("INFO: skipping {} which needs root", module_path!());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! skip_loop_if_root {
|
||||||
|
($msg:expr) => {
|
||||||
|
if nix::unistd::Uid::effective().is_root() {
|
||||||
|
println!(
|
||||||
|
"INFO: skipping loop {} in {} which needs non-root",
|
||||||
|
$msg,
|
||||||
|
module_path!()
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! skip_loop_if_not_root {
|
||||||
|
($msg:expr) => {
|
||||||
|
if !nix::unistd::Uid::effective().is_root() {
|
||||||
|
println!(
|
||||||
|
"INFO: skipping loop {} in {} which needs root",
|
||||||
|
$msg,
|
||||||
|
module_path!()
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// 1: expected Result
|
||||||
|
// 2: actual Result
|
||||||
|
// 3: string used to identify the test on error
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! assert_result {
|
||||||
|
($expected_result:expr, $actual_result:expr, $msg:expr) => {
|
||||||
|
if $expected_result.is_ok() {
|
||||||
|
let expected_value = $expected_result.as_ref().unwrap();
|
||||||
|
let actual_value = $actual_result.unwrap();
|
||||||
|
assert!(*expected_value == actual_value, "{}", $msg);
|
||||||
|
} else {
|
||||||
|
assert!($actual_result.is_err(), "{}", $msg);
|
||||||
|
|
||||||
|
let expected_error = $expected_result.as_ref().unwrap_err();
|
||||||
|
let expected_error_msg = format!("{:?}", expected_error);
|
||||||
|
|
||||||
|
let actual_error_msg = format!("{:?}", $actual_result.unwrap_err());
|
||||||
|
|
||||||
|
assert!(expected_error_msg == actual_error_msg, "{}", $msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! skip_loop_by_user {
|
||||||
|
($msg:expr, $user:expr) => {
|
||||||
|
if $user == TestUserType::RootOnly {
|
||||||
|
skip_loop_if_not_root!($msg);
|
||||||
|
} else if $user == TestUserType::NonRootOnly {
|
||||||
|
skip_loop_if_root!($msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{skip_if_not_root, skip_if_root};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_skip_if_not_root() {
|
||||||
|
skip_if_not_root!();
|
||||||
|
assert!(
|
||||||
|
nix::unistd::Uid::effective().is_root(),
|
||||||
|
"normal user should be skipped"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_skip_if_root() {
|
||||||
|
skip_if_root!();
|
||||||
|
assert!(
|
||||||
|
!nix::unistd::Uid::effective().is_root(),
|
||||||
|
"root user should be skipped"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user