use crate::message::DynamicPayload;
use crate::event::{
Event,
DaemonEvent,
DynamicEvent,
PeerEvent,
Filter,
DynamicEventFilter,
DynamicPayloadFilter,
PeerEventFilter,
PeerEventTypeFilter,
Dispatcher,
DispatcherSetup,
handle::{
Handler,
HandlerTask
}
};
use crate::peer::Status;
use super::*;
#[test_log::test(tokio::test(start_paused = true))]
async fn empty() {
let span = info_span!("empty_dispatcher");
let DispatcherSetup {
dispatcher,
event_tx,
query_tx: _,
interest_tx: _
} = Dispatcher::setup(&span);
let task = task::spawn(dispatcher.run());
drop(event_tx);
timeout_100ms(task).await.unwrap();
}
fn plain_task() -> (Task, Replier<()>) {
let (tx, rx) = new_oneshot();
let task = task::spawn(async {rx.await.unwrap()});
(task, tx)
}
fn launch_plain_handler<E: Event>()
-> (HandlerTask<E>, Replier<()>, Receiver<E>)
{
let (plain_tx, plain_rx) = new_channel();
let plain = Handler::Plain {
name: "plain_handler".to_owned(),
filter: None,
channel: plain_tx
};
let (task, task_stopper) = plain_task();
(
HandlerTask::new(plain, task),
task_stopper,
plain_rx
)
}
#[test_log::test(tokio::test(start_paused = true))]
async fn dispatch() {
let span = info_span!("empty_dispatcher");
let DispatcherSetup {
dispatcher,
event_tx,
query_tx: _,
interest_tx
} = Dispatcher::setup(&span);
let task = task::spawn(dispatcher.run());
let (handler, _stopper, mut rx) = launch_plain_handler::<DaemonEvent>();
interest_tx.send(Interest::Daemon(handler)).unwrap();
sleep_ms(10).await;
let evt = DaemonEvent::Start;
event_tx.send(evt.clone().into()).unwrap();
let received = timeout_100ms(rx.recv()).await.unwrap();
assert_eq!(evt, received);
drop(event_tx);
timeout_100ms(task).await.unwrap();
}
#[test_log::test]
fn daemon_filter() {
let daemon1 = DaemonEvent::Start;
let daemon2 = DaemonEvent::Inactive;
let only_start = Some(DaemonEvent::Start);
let only_inactive = Some(DaemonEvent::Inactive);
assert!(only_start.matches(&daemon1));
assert!(!only_inactive.matches(&daemon1));
assert!(!only_start.matches(&daemon2));
assert!(only_inactive.matches(&daemon2));
}
#[test_log::test]
fn dyn_filter() {
let id_correct = NodeID::random();
let id_wrong = NodeID::random();
assert_ne!(id_correct, id_wrong, "lottery win!");
let tag_correct = || "test.tag1".to_owned();
let tag_wrong = || "test.tag2".to_owned();
let pyl1 = DynamicPayload::Push {
tag: tag_correct(),
msg: "message payload Test123 :^)".to_owned()
};
let pyl2 = DynamicPayload::Push {
tag: tag_wrong(),
msg: "message payload Test123 :^)".to_owned()
};
let pyl3 = DynamicPayload::Query {
tag: tag_correct(),
msg: "message payload Test123 :^)".to_owned()
};
let dyn1 = DynamicEvent {
src: id_correct,
pyl: pyl1.clone()
};
let dyn2: DynamicEvent = (id_correct, pyl2).into();
let dyn3: DynamicEvent = (id_wrong, pyl1).into();
let dyn4: DynamicEvent = (id_correct, pyl3).into();
let check_id = Some(id_correct);
let check_tag = || Some(tag_correct());
let only_push = DynamicPayloadFilter::Push;
let only_query = DynamicPayloadFilter::Query;
let dyn_filter1 = DynamicEventFilter::simple(
check_id,
check_tag()
);
let dyn_filter2 = DynamicEventFilter {
from: check_id,
with: None,
typ: only_push
};
let dyn_filter3 = DynamicEventFilter {
from: check_id,
with: None,
typ: only_query
};
let dyn_filter4 = DynamicEventFilter::simple(None, None);
assert!(dyn_filter1.matches(&dyn1), "id & tag correct");
assert!(!dyn_filter1.matches(&dyn2), "id correct, tag wrong");
assert!(!dyn_filter1.matches(&dyn3), "id wrong, tag correct");
assert!(dyn_filter1.matches(&dyn4), "id & tag correct");
assert!(dyn_filter2.matches(&dyn1), "id & typ correct");
assert!(dyn_filter2.matches(&dyn2), "id & typ correct, tag ignored");
assert!(!dyn_filter2.matches(&dyn3), "id wrong, typ correct");
assert!(!dyn_filter2.matches(&dyn4), "id correct, typ wrong");
assert!(!dyn_filter3.matches(&dyn1), "id correct, typ wrong");
assert!(!dyn_filter3.matches(&dyn2), "id correct, typ wrong");
assert!(!dyn_filter3.matches(&dyn3), "id & typ wrong");
assert!(dyn_filter3.matches(&dyn4), "id & typ correct, tag ignored");
assert!(dyn_filter4.matches(&dyn1), "matches everything");
assert!(dyn_filter4.matches(&dyn2), "matches everything");
assert!(dyn_filter4.matches(&dyn3), "matches everything");
assert!(dyn_filter4.matches(&dyn4), "matches everything");
}
#[test_log::test]
fn peer_filter() {
let id1 = NodeID::random();
let id2 = NodeID::random();
assert_ne!(id1, id2, "lottery win!");
let peer1 = PeerEvent::changed(id1, Status::Active);
let peer2 = PeerEvent::new_address(id1, dummy_address(0));
let only_id1 = Some(id1);
let only_id2 = Some(id2);
let only_seen = PeerEventTypeFilter::Seen;
let only_status = PeerEventTypeFilter::StatusChanged;
let peer_filter1 = PeerEventFilter {
from: only_id1,
typ: only_status
};
let peer_filter2 = PeerEventFilter {
from: only_id2,
typ: only_seen
};
let peer_filter3 = PeerEventFilter {
from: None,
typ: only_status
};
let peer_filter4 = PeerEventFilter {
from: None,
typ: PeerEventTypeFilter::Any
};
assert!(peer_filter1.matches(&peer1), "correct id and type");
assert!(!peer_filter1.matches(&peer2), "correct id but wrong type");
assert!(!peer_filter2.matches(&peer1), "wrong id and type");
assert!(!peer_filter2.matches(&peer2), "wrong id and type");
assert!(peer_filter3.matches(&peer1), "id ignored, correct type");
assert!(!peer_filter3.matches(&peer2), "id ignored, wrong type");
assert!(peer_filter4.matches(&peer1), "matches everything");
assert!(peer_filter4.matches(&peer2), "matches everything");
}