use std::path::Path;
use std::process::Command;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Mutex, Once};
const SUBMODULE_PATH: &str = "tests/component-interposition";
static TEST_LOCK: Mutex<()> = Mutex::new(());
static FIXTURES_BUILT: Once = Once::new();
static FIXTURES_BUILD_OK: AtomicBool = AtomicBool::new(false);
fn submodule_ready() -> bool {
let run_sh = Path::new(SUBMODULE_PATH).join("run.sh");
if !run_sh.exists() {
eprintln!("Submodule not initialized. Run:\n git submodule update --init");
return false;
}
true
}
fn ensure_fixtures_built() {
FIXTURES_BUILT.call_once(|| {
let status = match Command::new("./run.sh")
.arg("build")
.current_dir(SUBMODULE_PATH)
.status()
{
Ok(s) => s,
Err(e) => {
eprintln!("ensure_fixtures_built: spawn ./run.sh build: {e}");
return;
}
};
if !status.success() {
eprintln!(
"ensure_fixtures_built: ./run.sh build failed with exit code {:?}",
status.code()
);
return;
}
FIXTURES_BUILD_OK.store(true, Ordering::Relaxed);
});
assert!(
FIXTURES_BUILD_OK.load(Ordering::Relaxed),
"fixture build failed — see the first FAILED integration_* test's \
output for the actual `./run.sh build` error"
);
}
fn run_config(opt: &str) {
let _guard = TEST_LOCK.lock().unwrap_or_else(|p| p.into_inner());
if !submodule_ready() {
panic!("component-interposition submodule not ready");
}
ensure_fixtures_built();
let status = Command::new("./run.sh")
.arg("all")
.arg(format!("--{}", opt))
.arg("--skip-build")
.current_dir(SUBMODULE_PATH)
.status()
.unwrap_or_else(|e| panic!("failed to run ./run.sh all --{}: {}", opt, e));
assert!(
status.success(),
"run.sh all --{} failed with exit code {:?}",
opt,
status.code()
);
}
#[test]
#[ignore]
fn integration_single() {
run_config("single");
}
#[test]
#[ignore]
fn integration_multiple() {
run_config("multiple");
}
#[test]
#[ignore]
fn integration_chain() {
run_config("chain");
}
#[test]
#[ignore]
fn integration_chain1() {
run_config("chain1");
}
#[test]
#[ignore]
fn integration_chain_n() {
run_config("chainN");
}
#[test]
#[ignore]
fn integration_nested() {
run_config("nested");
}
#[test]
#[ignore]
fn integration_inner_nested1() {
run_config("inner-nested1");
}
#[test]
#[ignore]
fn integration_inner_nested_n() {
run_config("inner-nestedN");
}
#[test]
#[ignore]
fn integration_pre_nested1() {
run_config("pre-nested1");
}
#[test]
#[ignore]
fn integration_pre_nested_n() {
run_config("pre-nestedN");
}
#[test]
#[ignore]
fn integration_inner_pre_nested1() {
run_config("inner+pre-nested1");
}
#[test]
#[ignore]
fn integration_inner_pre_nested_n() {
run_config("inner+pre-nestedN");
}
#[test]
#[ignore]
fn integration_fanin() {
run_config("fanin");
}
#[test]
#[ignore]
fn integration_fanin1() {
run_config("fanin1");
}
#[test]
#[ignore]
fn integration_fanin_n() {
run_config("faninN");
}
#[test]
#[ignore]
fn integration_fanin_all1() {
run_config("fanin-all1");
}
#[test]
#[ignore]
fn integration_fanin_all_n() {
run_config("fanin-allN");
}
#[test]
#[ignore]
fn integration_block1() {
run_config("block1");
}
#[test]
#[ignore]
fn integration_block_n() {
run_config("blockN");
}
#[test]
#[ignore]
fn integration_nonblock1() {
run_config("nonblock1");
}
#[test]
#[ignore]
fn integration_nonblock_n() {
run_config("nonblockN");
}