use super::crust::{CrustEventSender, CrustUser, Event, Service};
use super::support::{Config, Network};
use maidsafe_utilities::event_sender::{MaidSafeEventCategory, MaidSafeObserver};
use std::collections::HashSet;
use std::sync::mpsc::{self, Receiver};
fn get_event_sender() -> (CrustEventSender, Receiver<MaidSafeEventCategory>, Receiver<Event>) {
let (category_tx, category_rx) = mpsc::channel();
let (event_tx, event_rx) = mpsc::channel();
(MaidSafeObserver::new(event_tx, MaidSafeEventCategory::Crust, category_tx),
category_rx,
event_rx)
}
macro_rules! expect_event {
($rx:expr, $pattern:pat) => {
match unwrap!($rx.try_recv()) {
$pattern => (),
e => panic!("unexpected event {:?}", e),
}
};
($rx:expr, $pattern:pat => $arm:expr) => {
match unwrap!($rx.try_recv()) {
$pattern => $arm,
e => panic!("unexpected event {:?}", e),
}
}
}
#[test]
fn start_two_services_bootstrap_communicate_exit() {
let min_section_size = 8;
let network = Network::new(min_section_size, None);
let endpoint0 = network.gen_endpoint(None);
let endpoint1 = network.gen_endpoint(None);
let config = Config::with_contacts(&[endpoint0, endpoint1]);
let handle0 = network.new_service_handle(Some(config.clone()), Some(endpoint0));
let handle1 = network.new_service_handle(Some(config.clone()), Some(endpoint1));
let (event_sender_0, _category_rx_0, event_rx_0) = get_event_sender();
let (event_sender_1, _category_rx_1, event_rx_1) = get_event_sender();
let mut service_0 = unwrap!(Service::with_handle(&handle0, event_sender_0));
unwrap!(service_0.start_listening_tcp());
expect_event!(event_rx_0, Event::ListenerStarted(..));
service_0.start_service_discovery();
let mut service_1 = unwrap!(Service::with_handle(&handle1, event_sender_1));
unwrap!(service_1.start_bootstrap(HashSet::new(), CrustUser::Node));
let id_0 = expect_event!(event_rx_1, Event::BootstrapConnect(id, _) => id);
let id_1 = expect_event!(event_rx_0, Event::BootstrapAccept(id, CrustUser::Node) => id);
assert_ne!(id_0, id_1);
let data_sent = vec![0, 1, 255, 254, 222, 1];
unwrap!(service_0.send(id_1, data_sent.clone(), 0));
let (data_recvd, peer_id) =
expect_event!(event_rx_1,
Event::NewMessage(their_id, msg) => (msg, their_id));
assert_eq!(data_recvd, data_sent);
assert_eq!(peer_id, id_0);
let data_sent = vec![10, 11, 155, 214, 202];
unwrap!(service_1.send(id_0, data_sent.clone(), 0));
let (data_recvd, peer_id) =
expect_event!(event_rx_0,
Event::NewMessage(their_id, msg) => (msg, their_id));
assert_eq!(data_recvd, data_sent);
assert_eq!(peer_id, id_1);
assert!(service_0.disconnect(id_1));
expect_event!(event_rx_1, Event::LostPeer(id) => assert_eq!(id, id_0));
}
#[test]
fn start_two_services_rendezvous_connect() {
const PREPARE_CI_TOKEN: u32 = 1;
let min_section_size = 8;
let network = Network::new(min_section_size, None);
let handle0 = network.new_service_handle(None, None);
let handle1 = network.new_service_handle(None, None);
let (event_sender_0, _category_rx_0, event_rx_0) = get_event_sender();
let (event_sender_1, _category_rx_1, event_rx_1) = get_event_sender();
let service_0 = unwrap!(Service::with_handle(&handle0, event_sender_0));
let service_1 = unwrap!(Service::with_handle(&handle1, event_sender_1));
service_0.prepare_connection_info(PREPARE_CI_TOKEN);
let our_ci_0 = expect_event!(event_rx_0, Event::ConnectionInfoPrepared(cir) => {
assert_eq!(cir.result_token, PREPARE_CI_TOKEN);
unwrap!(cir.result)
});
service_1.prepare_connection_info(PREPARE_CI_TOKEN);
let our_ci_1 = expect_event!(event_rx_1, Event::ConnectionInfoPrepared(cir) => {
assert_eq!(cir.result_token, PREPARE_CI_TOKEN);
unwrap!(cir.result)
});
let their_ci_0 = our_ci_0.to_pub_connection_info();
let their_ci_1 = our_ci_1.to_pub_connection_info();
unwrap!(service_0.connect(our_ci_0, their_ci_1));
unwrap!(service_1.connect(our_ci_1, their_ci_0));
let id_1 = expect_event!(event_rx_0, Event::ConnectSuccess(id) => id);
let id_0 = expect_event!(event_rx_1, Event::ConnectSuccess(id) => id);
let data_sent = vec![0, 1, 255, 254, 222, 1];
unwrap!(service_0.send(id_1, data_sent.clone(), 0));
let (data_recvd, peer_id) =
expect_event!(event_rx_1,
Event::NewMessage(their_id, msg) => (msg, their_id));
assert_eq!(data_recvd, data_sent);
assert_eq!(peer_id, id_0);
let data_sent = vec![10, 11, 155, 214, 202];
unwrap!(service_1.send(id_0, data_sent.clone(), 0));
let (data_recvd, peer_id) =
expect_event!(event_rx_0,
Event::NewMessage(their_id, msg) => (msg, their_id));
assert_eq!(data_recvd, data_sent);
assert_eq!(peer_id, id_1);
}
#[test]
fn unidirectional_rendezvous_connect() {
const PREPARE_CI_TOKEN: u32 = 1;
let min_section_size = 8;
let network = Network::new(min_section_size, None);
let handle0 = network.new_service_handle(None, None);
let handle1 = network.new_service_handle(None, None);
let (event_tx_0, _category_rx_0, event_rx_0) = get_event_sender();
let (event_tx_1, _category_rx_1, event_rx_1) = get_event_sender();
let service_0 = unwrap!(Service::with_handle(&handle0, event_tx_0));
let service_1 = unwrap!(Service::with_handle(&handle1, event_tx_1));
service_0.prepare_connection_info(PREPARE_CI_TOKEN);
let our_ci_0 = expect_event!(event_rx_0, Event::ConnectionInfoPrepared(cir) => {
unwrap!(cir.result)
});
service_1.prepare_connection_info(PREPARE_CI_TOKEN);
let our_ci_1 = expect_event!(event_rx_1, Event::ConnectionInfoPrepared(cir) => {
unwrap!(cir.result)
});
let their_ci_1 = our_ci_1.to_pub_connection_info();
unwrap!(service_0.connect(our_ci_0, their_ci_1));
expect_event!(event_rx_0, Event::ConnectSuccess(_));
expect_event!(event_rx_1, Event::ConnectSuccess(_));
}
#[test]
fn drop() {
use std::mem;
let min_section_size = 8;
let network = Network::new(min_section_size, None);
let handle0 = network.new_service_handle(None, None);
let config = Config::with_contacts(&[handle0.endpoint()]);
let handle1 = network.new_service_handle(Some(config), None);
let (event_sender_0, _category_rx_0, event_rx_0) = get_event_sender();
let (event_sender_1, _category_rx_1, event_rx_1) = get_event_sender();
let mut service_0 = unwrap!(Service::with_handle(&handle0, event_sender_0));
unwrap!(service_0.start_listening_tcp());
expect_event!(event_rx_0, Event::ListenerStarted(_));
let mut service_1 = unwrap!(Service::with_handle(&handle1, event_sender_1));
unwrap!(service_1.start_bootstrap(HashSet::new(), CrustUser::Node));
let id_0 = expect_event!(event_rx_1, Event::BootstrapConnect(id, _) => id);
expect_event!(event_rx_0, Event::BootstrapAccept(..));
mem::drop(service_0);
expect_event!(event_rx_1, Event::LostPeer(id) => assert_eq!(id, id_0));
}