use anyhow::{bail, Result}; use structopt::StructOpt; mod destructive; mod repobin; mod sysroot; mod test; mod treegen; // Written by Ignition const DESTRUCTIVE_TEST_STAMP: &str = "/etc/ostree-destructive-test-ok"; #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] #[allow(clippy::enum_variant_names)] /// Main options struct enum Opt { /// List the destructive tests ListDestructive, /// Run a destructive test (requires ostree-based host, may break it!) RunDestructive { name: String }, /// Run the non-destructive tests NonDestructive(NonDestructiveOpts), } #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] enum NonDestructiveOpts { #[structopt(external_subcommand)] Args(Vec), } fn libtest_from_test(t: &'static test::Test) -> test::TestImpl { libtest_mimic::Test { name: t.name.into(), kind: "".into(), is_ignored: false, is_bench: false, data: t, } } fn run_test(test: &test::TestImpl) -> libtest_mimic::Outcome { if let Err(e) = (test.data.f)() { libtest_mimic::Outcome::Failed { msg: Some(e.to_string()), } } else { libtest_mimic::Outcome::Passed } } fn main() -> Result<()> { // Ensure we're always in tempdir so we can rely on it globally. // We use /var/tmp to ensure we have storage space in the destructive // case. let tmp_dir = tempfile::Builder::new() .prefix("ostree-insttest-top") .tempdir_in("/var/tmp")?; std::env::set_current_dir(tmp_dir.path())?; procspawn::init(); let args: Vec = std::env::args().collect(); let opt = { if args.len() == 1 { println!("No arguments provided, running non-destructive tests"); Opt::NonDestructive(NonDestructiveOpts::Args(Vec::new())) } else { Opt::from_iter(args.iter()) } }; match opt { Opt::ListDestructive => { for t in test::DESTRUCTIVE_TESTS.iter() { println!("{}", t.name); } Ok(()) } Opt::NonDestructive(subopt) => { // FIXME add method to parse subargs let NonDestructiveOpts::Args(iter) = subopt; let libtestargs = libtest_mimic::Arguments::from_iter(iter); let tests: Vec<_> = test::NONDESTRUCTIVE_TESTS .iter() .map(libtest_from_test) .collect(); libtest_mimic::run_tests(&libtestargs, tests, run_test).exit(); } Opt::RunDestructive { name } => { if !std::path::Path::new(DESTRUCTIVE_TEST_STAMP).exists() { bail!( "This is a destructive test; signal acceptance by creating {}", DESTRUCTIVE_TEST_STAMP ) } if !std::path::Path::new("/run/ostree-booted").exists() { bail!("An ostree-based host is required") } for t in test::DESTRUCTIVE_TESTS.iter() { if t.name == name { (t.f)()?; println!("ok destructive test: {}", t.name); return Ok(()); } } bail!("Unknown destructive test: {}", name); } } }