use std::collections::BTreeMap;
use std::sync::Arc;
use camel_integration_test::runner::fill_bind_vars;
use camel_integration_test::{
DirectStimulus, DocumentOutcome, EndpointRef, LayeredEnv, PartnerAdapter, PartnerRouter,
ScenarioAction, ScenarioTarget, ScenarioVars, ambient_std, boot_scenario,
ensure_capture_subscriber, parse_scenario_document, run_scenario_document,
};
pub static RUN_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
pub fn lock_run() -> std::sync::MutexGuard<'static, ()> {
RUN_LOCK
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
pub async fn run_logs_document(doc_yaml: &str, fixture: &str) -> DocumentOutcome {
ensure_capture_subscriber();
let dir = tempfile::tempdir().expect("temp dir");
let root = dir.path();
std::fs::write(root.join("Camel.toml"), "log_level = \"info\"\n").expect("write Camel.toml");
let fixture_path = format!(
"{}/tests/fixtures/logs/{fixture}",
env!("CARGO_MANIFEST_DIR")
);
std::fs::copy(&fixture_path, root.join("routes.yaml")).expect("copy route fixture");
let path = root.join("case.test.yaml");
std::fs::write(&path, doc_yaml).expect("write case file");
let doc = parse_scenario_document(&path).expect("document must load");
let env = LayeredEnv::new(
doc.env.clone().unwrap_or_default(),
BTreeMap::new(),
doc.env_passthrough.clone().unwrap_or_default(),
ambient_std(),
);
let run = boot_scenario(&doc, root, &env)
.await
.expect("the full boot must succeed");
let ctx = Arc::new(tokio::sync::Mutex::new(run.ctx));
let mut adapters: BTreeMap<String, Box<dyn PartnerAdapter>> = BTreeMap::new();
adapters.insert(
"direct:start".to_string(),
Box::new(DirectStimulus::new(Arc::clone(&ctx))),
);
let router = PartnerRouter::new(adapters);
let wired = wired_refs(&doc);
let mut vars = ScenarioVars::new();
fill_bind_vars(&wired, &router, &mut vars);
let outcome = run_scenario_document(&doc, &router, &mut vars, None).await;
let mut guard = ctx.lock().await;
run.boot
.shutdown(&mut guard)
.await
.expect("clean shutdown must complete");
outcome
}
fn wired_refs(doc: &camel_integration_test::ScenarioDocument) -> Vec<EndpointRef> {
doc.scenario
.iter()
.filter_map(|action| match action {
ScenarioAction::Send { to, .. } => Some(to.clone()),
ScenarioAction::Receive { from, .. } => Some(from.clone()),
ScenarioAction::Validate {
target: ScenarioTarget::LastReceived(endpoint),
..
} => Some(endpoint.clone()),
_ => None,
})
.collect()
}