ostree/tests/inst/src/insttestmain.rs

112 lines
3.3 KiB
Rust

use anyhow::{bail, Result};
use libtest_mimic::Trial;
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";
macro_rules! test {
($f: path) => {
(stringify!($f), $f)
};
}
type StaticTest = (&'static str, fn() -> Result<()>);
const TESTS: &[StaticTest] = &[
test!(sysroot::itest_sysroot_ro),
test!(sysroot::itest_immutable_bit),
test!(sysroot::itest_tmpfiles),
test!(repobin::itest_basic),
test!(repobin::itest_nofifo),
test!(repobin::itest_extensions),
test!(repobin::itest_pull_basicauth),
];
const DESTRUCTIVE_TESTS: &[StaticTest] = &[test!(destructive::itest_transactionality)];
#[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<String>),
}
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<String> = 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 DESTRUCTIVE_TESTS {
println!("{}", t.0);
}
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<_> = TESTS
.iter()
.map(|(name, fun)| Trial::test(*name, move || fun().map_err(Into::into)))
.collect();
libtest_mimic::run(&libtestargs, tests).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 (tname, f) in DESTRUCTIVE_TESTS {
if *tname == name.as_str() {
(f)()?;
println!("ok destructive test: {}", tname);
return Ok(());
}
}
bail!("Unknown destructive test: {}", name);
}
}
}