1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-06-01 12:26:17 +02:00
youki/tests/test_framework/src/test_manager.rs

112 lines
3.5 KiB
Rust
Raw Normal View History

//! This exposes the main control wrapper to control the tests
use crate::testable::{TestResult, TestableGroup};
2021-10-18 23:06:50 +02:00
use anyhow::Result;
use crossbeam::thread;
2021-08-05 13:08:11 +02:00
use std::collections::BTreeMap;
type TestableGroupType = dyn TestableGroup + Sync + Send;
2021-08-05 13:08:11 +02:00
/// This manages all test groups, and thus the tests
pub struct TestManager {
test_groups: BTreeMap<&'static str, Box<TestableGroupType>>,
2021-10-18 23:06:50 +02:00
cleanup: Vec<Box<dyn Fn() -> Result<()>>>,
2021-08-05 13:08:11 +02:00
}
impl Default for TestManager {
2021-08-05 13:08:11 +02:00
fn default() -> Self {
Self::new()
}
}
impl TestManager {
2021-08-05 13:08:11 +02:00
/// Create new TestManager
pub fn new() -> Self {
TestManager {
test_groups: BTreeMap::new(),
2021-10-18 23:06:50 +02:00
cleanup: Vec::new(),
2021-08-05 13:08:11 +02:00
}
}
/// add a test group to the test manager
pub fn add_test_group(&mut self, tg: Box<TestableGroupType>) {
2021-08-05 13:08:11 +02:00
self.test_groups.insert(tg.get_name(), tg);
}
2021-10-18 23:06:50 +02:00
pub fn add_cleanup(&mut self, cleaner: Box<dyn Fn() -> Result<()>>) {
self.cleanup.push(cleaner)
}
2021-08-05 13:08:11 +02:00
/// Prints the given test results, usually used to print
/// results of a test group
fn print_test_result(&self, name: &str, res: &[(&'static str, TestResult)]) {
println!("# Start group {name}");
2021-08-05 13:08:11 +02:00
let len = res.len();
for (idx, (name, res)) in res.iter().enumerate() {
print!("{} / {} : {} : ", idx + 1, len, name);
2021-08-05 13:08:11 +02:00
match res {
2021-10-16 12:24:34 +02:00
TestResult::Passed => {
2021-08-05 13:08:11 +02:00
println!("ok");
}
2021-10-16 12:24:34 +02:00
TestResult::Skipped => {
2021-08-05 13:08:11 +02:00
println!("skipped");
}
2021-10-16 12:24:34 +02:00
TestResult::Failed(e) => {
println!("not ok\n\t{e}");
2021-08-05 13:08:11 +02:00
}
}
}
println!("# End group {name}\n");
2021-08-05 13:08:11 +02:00
}
/// Run all tests from all tests group
pub fn run_all(&self) {
thread::scope(|s| {
let mut collector = Vec::with_capacity(self.test_groups.len());
for (name, tg) in &self.test_groups {
let r = s.spawn(move |_| tg.run_all());
collector.push((name, r));
}
for (name, handle) in collector {
self.print_test_result(name, &handle.join().unwrap());
}
})
.unwrap();
2021-10-18 23:06:50 +02:00
for cleaner in &self.cleanup {
if let Err(e) = cleaner() {
print!("Failed to cleanup: {e}");
2021-10-18 23:06:50 +02:00
}
}
2021-08-05 13:08:11 +02:00
}
/// Run only selected tests
pub fn run_selected(&self, tests: Vec<(&str, Option<Vec<&str>>)>) {
thread::scope(|s| {
let mut collector = Vec::with_capacity(tests.len());
for (test_group_name, tests) in &tests {
if let Some(tg) = self.test_groups.get(test_group_name) {
let r = match tests {
None => s.spawn(move |_| tg.run_all()),
Some(tests) => s.spawn(move |_| tg.run_selected(tests)),
};
collector.push((test_group_name, r));
} else {
eprintln!("Error : Test Group {test_group_name} not found, skipping");
2021-08-05 13:08:11 +02:00
}
}
for (name, handle) in collector {
self.print_test_result(name, &handle.join().unwrap());
}
})
.unwrap();
2021-10-18 23:06:50 +02:00
for cleaner in &self.cleanup {
if let Err(e) = cleaner() {
print!("Failed to cleanup: {e}");
2021-10-18 23:06:50 +02:00
}
}
2021-08-05 13:08:11 +02:00
}
2021-12-28 13:40:05 +01:00
pub fn tests_groups(&self) -> Vec<String> {
self.test_groups.iter().map(|tg| tg.0.to_string()).collect()
}
2021-08-05 13:08:11 +02:00
}