From 34746496b7ff860c570d33bbe53c88f1aad3ff17 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 16 Aug 2022 17:40:30 +0800 Subject: [PATCH] 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 --- src/agent/Cargo.lock | 8 +++ src/agent/Cargo.toml | 1 + src/agent/src/config.rs | 2 +- src/agent/src/main.rs | 5 +- src/agent/src/mount.rs | 6 +- src/agent/src/namespace.rs | 3 +- src/agent/src/netlink.rs | 2 +- src/agent/src/network.rs | 2 +- src/agent/src/random.rs | 2 +- src/agent/src/rpc.rs | 6 +- src/agent/src/sandbox.rs | 3 +- src/agent/src/test_utils.rs | 99 --------------------------- src/agent/src/watcher.rs | 2 +- src/libs/Cargo.lock | 7 ++ src/libs/Cargo.toml | 1 + src/libs/README.md | 1 + src/libs/test-utils/Cargo.toml | 15 +++++ src/libs/test-utils/README.md | 8 +++ src/libs/test-utils/src/lib.rs | 119 +++++++++++++++++++++++++++++++++ 19 files changed, 177 insertions(+), 115 deletions(-) delete mode 100644 src/agent/src/test_utils.rs create mode 100644 src/libs/test-utils/Cargo.toml create mode 100644 src/libs/test-utils/README.md create mode 100644 src/libs/test-utils/src/lib.rs diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index e26f7bd03..69c619284 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -651,6 +651,7 @@ dependencies = [ "slog-stdlog", "sysinfo", "tempfile", + "test-utils", "thiserror", "tokio", "tokio-vsock", @@ -1769,6 +1770,13 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test-utils" +version = "0.1.0" +dependencies = [ + "nix 0.24.2", +] + [[package]] name = "textwrap" version = "0.15.0" diff --git a/src/agent/Cargo.toml b/src/agent/Cargo.toml index 166d080e9..70358585f 100644 --- a/src/agent/Cargo.toml +++ b/src/agent/Cargo.toml @@ -66,6 +66,7 @@ clap = { version = "3.0.1", features = ["derive"] } [dev-dependencies] tempfile = "3.1.0" +test-utils = { path = "../libs/test-utils" } [workspace] members = [ diff --git a/src/agent/src/config.rs b/src/agent/src/config.rs index 0bdf20c2d..9beda9904 100644 --- a/src/agent/src/config.rs +++ b/src/agent/src/config.rs @@ -432,7 +432,7 @@ fn get_container_pipe_size(param: &str) -> Result { #[cfg(test)] mod tests { - use crate::assert_result; + use test_utils::assert_result; use super::*; use anyhow::anyhow; diff --git a/src/agent/src/main.rs b/src/agent/src/main.rs index 1a1bce436..2c1f41def 100644 --- a/src/agent/src/main.rs +++ b/src/agent/src/main.rs @@ -49,8 +49,6 @@ mod pci; pub mod random; mod sandbox; mod signal; -#[cfg(test)] -mod test_utils; mod uevent; mod util; mod version; @@ -401,7 +399,8 @@ use std::os::unix::io::{FromRawFd, RawFd}; #[cfg(test)] mod tests { 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] async fn test_create_logger_task() { diff --git a/src/agent/src/mount.rs b/src/agent/src/mount.rs index 568ea6aef..a94cf9ce9 100644 --- a/src/agent/src/mount.rs +++ b/src/agent/src/mount.rs @@ -1016,8 +1016,6 @@ fn parse_options(option_list: Vec) -> HashMap { #[cfg(test)] mod tests { 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 protocols::agent::FSGroup; use std::fs::File; @@ -1025,6 +1023,10 @@ mod tests { use std::io::Write; use std::path::PathBuf; 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] fn test_mount() { diff --git a/src/agent/src/namespace.rs b/src/agent/src/namespace.rs index dc6ebe63b..876e3d6fd 100644 --- a/src/agent/src/namespace.rs +++ b/src/agent/src/namespace.rs @@ -187,9 +187,10 @@ impl fmt::Debug for NamespaceType { #[cfg(test)] mod tests { use super::{Namespace, NamespaceType}; - use crate::{mount::remove_mounts, skip_if_not_root}; + use crate::mount::remove_mounts; use nix::sched::CloneFlags; use tempfile::Builder; + use test_utils::skip_if_not_root; #[tokio::test] async fn test_setup_persistent_ns() { diff --git a/src/agent/src/netlink.rs b/src/agent/src/netlink.rs index 3869eee00..6dad1a9e1 100644 --- a/src/agent/src/netlink.rs +++ b/src/agent/src/netlink.rs @@ -724,10 +724,10 @@ impl Address { #[cfg(test)] mod tests { use super::*; - use crate::skip_if_not_root; use rtnetlink::packet; use std::iter; use std::process::Command; + use test_utils::skip_if_not_root; #[tokio::test] async fn find_link_by_name() { diff --git a/src/agent/src/network.rs b/src/agent/src/network.rs index 1152fce91..194795a6f 100644 --- a/src/agent/src/network.rs +++ b/src/agent/src/network.rs @@ -76,11 +76,11 @@ fn do_setup_guest_dns(logger: Logger, dns_list: Vec, src: &str, dst: &st #[cfg(test)] mod tests { use super::*; - use crate::skip_if_not_root; use nix::mount; use std::fs::File; use std::io::Write; use tempfile::tempdir; + use test_utils::skip_if_not_root; #[test] fn test_setup_guest_dns() { diff --git a/src/agent/src/random.rs b/src/agent/src/random.rs index 1c83f03f0..f97f0f033 100644 --- a/src/agent/src/random.rs +++ b/src/agent/src/random.rs @@ -53,9 +53,9 @@ pub fn reseed_rng(data: &[u8]) -> Result<()> { #[cfg(test)] mod tests { use super::*; - use crate::skip_if_not_root; use std::fs::File; use std::io::prelude::*; + use test_utils::skip_if_not_root; #[test] fn test_reseed_rng() { diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs index ac07721e2..2a62aedf3 100644 --- a/src/agent/src/rpc.rs +++ b/src/agent/src/rpc.rs @@ -1987,14 +1987,12 @@ fn load_kernel_module(module: &protocols::agent::KernelModule) -> Result<()> { #[cfg(test)] mod tests { use super::*; - use crate::{ - assert_result, namespace::Namespace, protocols::agent_ttrpc_async::AgentService as _, - skip_if_not_root, - }; + use crate::{namespace::Namespace, protocols::agent_ttrpc_async::AgentService as _}; use nix::mount; use nix::sched::{unshare, CloneFlags}; use oci::{Hook, Hooks, Linux, LinuxNamespace}; use tempfile::{tempdir, TempDir}; + use test_utils::{assert_result, skip_if_not_root}; use ttrpc::{r#async::TtrpcContext, MessageHeader}; fn mk_ttrpc_context() -> TtrpcContext { diff --git a/src/agent/src/sandbox.rs b/src/agent/src/sandbox.rs index 36861fc83..8f93fdd5b 100644 --- a/src/agent/src/sandbox.rs +++ b/src/agent/src/sandbox.rs @@ -471,7 +471,7 @@ fn online_memory(logger: &Logger) -> Result<()> { #[cfg(test)] mod tests { use super::*; - use crate::{mount::baremount, skip_if_not_root}; + use crate::mount::baremount; use anyhow::{anyhow, Error}; use nix::mount::MsFlags; use oci::{Linux, Root, Spec}; @@ -484,6 +484,7 @@ mod tests { use std::os::unix::fs::PermissionsExt; use std::path::Path; use tempfile::{tempdir, Builder, TempDir}; + use test_utils::skip_if_not_root; fn bind_mount(src: &str, dst: &str, logger: &Logger) -> Result<(), Error> { let src_path = Path::new(src); diff --git a/src/agent/src/test_utils.rs b/src/agent/src/test_utils.rs deleted file mode 100644 index d25eb129d..000000000 --- a/src/agent/src/test_utils.rs +++ /dev/null @@ -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); - } - }; - } -} diff --git a/src/agent/src/watcher.rs b/src/agent/src/watcher.rs index e42312661..0a6a72f39 100644 --- a/src/agent/src/watcher.rs +++ b/src/agent/src/watcher.rs @@ -528,10 +528,10 @@ impl BindWatcher { mod tests { use super::*; use crate::mount::is_mounted; - use crate::skip_if_not_root; use nix::unistd::{Gid, Uid}; use std::fs; use std::thread; + use test_utils::skip_if_not_root; async fn create_test_storage(dir: &Path, id: &str) -> Result<(protos::Storage, PathBuf)> { let src_path = dir.join(format!("src{}", id)); diff --git a/src/libs/Cargo.lock b/src/libs/Cargo.lock index b82c108c4..22109c31c 100644 --- a/src/libs/Cargo.lock +++ b/src/libs/Cargo.lock @@ -1021,6 +1021,13 @@ dependencies = [ "winapi", ] +[[package]] +name = "test-utils" +version = "0.1.0" +dependencies = [ + "nix 0.24.2", +] + [[package]] name = "thiserror" version = "1.0.30" diff --git a/src/libs/Cargo.toml b/src/libs/Cargo.toml index b485eaa43..b173ae7b7 100644 --- a/src/libs/Cargo.toml +++ b/src/libs/Cargo.toml @@ -6,5 +6,6 @@ members = [ "safe-path", "protocols", "oci", + "test-utils", ] resolver = "2" diff --git a/src/libs/README.md b/src/libs/README.md index bb1a655c3..a7ac0349a 100644 --- a/src/libs/README.md +++ b/src/libs/README.md @@ -10,3 +10,4 @@ Currently it provides following library crates: | [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. | | [safe-path](safe-path/) | Utilities to safely resolve filesystem paths. | +| [test utilities](test-utils/) | Utilities to share test code. | diff --git a/src/libs/test-utils/Cargo.toml b/src/libs/test-utils/Cargo.toml new file mode 100644 index 000000000..2bfb652e4 --- /dev/null +++ b/src/libs/test-utils/Cargo.toml @@ -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 "] +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" diff --git a/src/libs/test-utils/README.md b/src/libs/test-utils/README.md new file mode 100644 index 000000000..a7bf669a3 --- /dev/null +++ b/src/libs/test-utils/README.md @@ -0,0 +1,8 @@ +Test Utilities +==================== + +A library to share test code for Rust. + +## License + +This code is licensed under [Apache-2.0](../../../LICENSE). diff --git a/src/libs/test-utils/src/lib.rs b/src/libs/test-utils/src/lib.rs new file mode 100644 index 000000000..948701304 --- /dev/null +++ b/src/libs/test-utils/src/lib.rs @@ -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" + ) + } +}