mod common;
use common::{records, wait_until};
use ek_core::{MailStats, MainEngine, PluginError, PluginState};
use ek_event::Event;
use std::sync::Arc;
use std::time::Duration;
#[test]
fn hl1_register_validation() {
let eng = MainEngine::new(None);
for bad in ["", "9abc", "bad name", "日本語", &"a".repeat(33)] {
match eng.add_plugin(common::test_plugin(bad).build()) {
Err(PluginError::IllegalName(n)) => assert_eq!(n, bad),
other => panic!("expected IllegalName for {bad:?}, got {other:?}"),
}
}
eng.add_plugin(common::test_plugin("oms").build()).unwrap();
match eng.add_plugin(common::test_plugin("oms").build()) {
Err(PluginError::Duplicate(n)) => assert_eq!(n, "oms"),
other => panic!("expected Duplicate, got {other:?}"),
}
eng.add_plugin(common::test_plugin("x").deps(&["ghost"]).build())
.unwrap();
match eng.add_plugin(common::test_plugin("y").deps(&["y"]).build()) {
Err(PluginError::DepCycle(_)) => {}
other => panic!("expected DepCycle, got {other:?}"),
}
assert_eq!(eng.plugin_names(), vec!["oms".to_string(), "x".to_string()]);
assert_eq!(eng.get_state("oms"), Some(PluginState::Ready));
let info = eng.get_plugin("oms").unwrap();
assert_eq!(info.deps, Vec::<String>::new());
{
let e3 = MainEngine::new(None);
e3.add_plugin(common::test_plugin("x2").deps(&["ghost"]).build())
.unwrap();
match e3.start() {
Err(PluginError::UnknownDep(d)) => assert_eq!(d, "ghost"),
other => panic!("expected UnknownDep at start, got {other:?}"),
}
e3.close_all(Duration::from_secs(1));
}
eng.close_all(Duration::from_secs(1));
}
#[test]
fn hl2_start_close_order() {
let eng = MainEngine::new(None);
let seq = records::<String>();
let mk = |name: &'static str, deps: &'static [&'static str]| {
let seq_start = Arc::clone(&seq);
let seq_stop = Arc::clone(&seq);
common::test_plugin(name)
.deps(deps)
.start_hook(move || common::push_record(&seq_start, format!("start:{name}")))
.stop_hook(move || common::push_record(&seq_stop, format!("stop:{name}")))
.build()
};
eng.add_plugin(mk("b", &[])).unwrap();
eng.add_plugin(mk("a", &["b"])).unwrap();
eng.add_plugin(mk("c", &["a"])).unwrap();
eng.start().unwrap();
eng.close(Duration::from_secs(2));
let got = common::snapshot(&seq);
assert_eq!(
got,
vec![
"start:b".to_string(),
"start:a".to_string(),
"start:c".to_string(),
"stop:c".to_string(),
"stop:a".to_string(),
"stop:b".to_string(),
]
);
assert!(eng.plugin_names().is_empty());
assert_eq!(eng.get_state("b"), None);
}
#[test]
fn hl3_silence_after_close() {
let eng = MainEngine::new(None);
let ticks = common::counter();
let t = Arc::clone(&ticks);
eng.add_plugin(
common::test_plugin("p")
.routes_str(&["eTick."])
.mail(move |_e: &Event| {
common::bump(&t);
})
.build(),
)
.unwrap();
eng.start().unwrap();
for i in 0..3u64 {
eng.event_engine()
.put(Event::with_data("eTick.", Arc::new(i)))
.unwrap();
}
assert!(
wait_until(Duration::from_secs(2), || common::load(&ticks) == 3),
"ticks before close"
);
eng.close(Duration::from_secs(2));
for i in 0..5u64 {
let _ = eng.event_engine().put(Event::new("eTick."));
let _ = i;
}
std::thread::sleep(Duration::from_millis(300));
assert_eq!(common::load(&ticks), 3, "no mails after close");
}
#[test]
fn hl4_no_replay_then_live() {
let eng = MainEngine::new(None);
let bus = Arc::clone(eng.event_engine());
bus.start();
bus.put(Event::new("eTick.")).unwrap();
bus.put(Event::new("eTick.")).unwrap();
assert!(wait_until(Duration::from_secs(1), || bus.pending_events() == 0));
std::thread::sleep(Duration::from_millis(200));
let ticks = common::counter();
let t = Arc::clone(&ticks);
eng.add_plugin(
common::test_plugin("p")
.routes_str(&["eTick."])
.mail(move |_e: &Event| {
common::bump(&t);
})
.build(),
)
.unwrap();
eng.start().unwrap();
assert_eq!(common::load(&ticks), 0, "no replay of pre-start events");
for i in 0..3u64 {
bus.put(Event::with_data("eTick.", Arc::new(i))).unwrap();
}
assert!(wait_until(Duration::from_secs(2), || common::load(&ticks) == 3));
eng.close_all(Duration::from_secs(1));
}
#[test]
fn hl5_info_and_stats() {
let eng = MainEngine::new(None);
eng.add_plugin(
common::test_plugin("m")
.routes_str(&["eTick."])
.mail(|_e: &Event| {})
.build(),
)
.unwrap();
eng.start().unwrap();
assert_eq!(eng.get_state("m"), Some(PluginState::Running));
assert_eq!(
eng.mail_stats("m"),
Some(MailStats {
spilled: 0,
panics: 0
})
);
eng.event_engine().put(Event::new("eTick.")).unwrap();
assert!(wait_until(Duration::from_millis(500), || {
eng.mail_stats("m").map(|s| s.panics).unwrap_or(9) == 0
}));
eng.close_all(Duration::from_secs(1));
}