1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! common types and traits for working with Transport instances
pub mod error;
pub mod memory_mock;
pub mod protocol;
pub mod transport_crypto;
pub mod transport_trait;

/// a connection identifier
pub type ConnectionId = String;

pub type ConnectionIdRef = str;

///
#[cfg(test)]
pub mod tests {
    #![allow(non_snake_case)]

    use crate::{
        transport::{
            memory_mock::transport_memory, protocol::TransportEvent, transport_trait::Transport,
        },
        transport_wss::{TlsConfig, TransportWss},
    };

    use crate::tests::enable_logging_for_test;
    use url::Url;

    // How many times to call process before asserting if work was done.
    // Empirically verified to work with just 6- raise this value
    // if your transport to be tested requires more iterations.
    const NUM_PROCESS_LOOPS: u8 = 6;

    #[test]
    fn memory_send_test() {
        enable_logging_for_test(true);
        let mut node_A = transport_memory::TransportMemory::new();
        let mut node_B = transport_memory::TransportMemory::new();
        let uri_A = Url::parse("mem://a").unwrap();
        let uri_B = Url::parse("mem://b").unwrap();

        send_test(&mut node_A, &mut node_B, &uri_A, &uri_B);
    }

    #[test]
    fn wss_send_test() {
        enable_logging_for_test(true);
        let mut node_A = TransportWss::with_std_tcp_stream(TlsConfig::Unencrypted);
        let mut node_B = TransportWss::with_std_tcp_stream(TlsConfig::Unencrypted);
        let uri_A = Url::parse("wss://127.0.0.1:64529").unwrap();
        let uri_B = Url::parse("wss://127.0.0.1:64530").unwrap();

        send_test(&mut node_A, &mut node_B, &uri_A, &uri_B);
    }

    #[test]
    fn wss_send_test_tls() {
        enable_logging_for_test(true);
        let mut node_A = TransportWss::with_std_tcp_stream(TlsConfig::FakeServer);
        let mut node_B = TransportWss::with_std_tcp_stream(TlsConfig::FakeServer);
        let uri_A = Url::parse("wss://127.0.0.1:64531").unwrap();
        let uri_B = Url::parse("wss://127.0.0.1:64532").unwrap();

        send_test(&mut node_A, &mut node_B, &uri_A, &uri_B);
    }

    fn send_test(
        node_A: &mut impl Transport,
        node_B: &mut impl Transport,
        uri_A: &Url,
        uri_B: &Url,
    ) {
        // Connect
        let _actual_bind_uri_a = node_A.bind(uri_A).unwrap();
        let actual_bind_uri_b = node_B.bind(uri_B).unwrap();
        let idAB = node_A.connect(&actual_bind_uri_b).unwrap();
        trace!("actual_bind_uri_b: {}, idAB: {}", actual_bind_uri_b, idAB);

        let (_did_work, _event_list) = node_A.process().unwrap();
        let (_did_work, _event_list) = node_B.process().unwrap();

        // Send A -> B
        let payload = [1, 2, 3, 4];
        node_A.send(&[&idAB], &payload).unwrap();
        let mut did_work = false;
        let mut event_list = Vec::new();

        // TODO consider making this a while loop with timeout
        for _x in 0..NUM_PROCESS_LOOPS {
            let (did_work_B, mut event_list_B) = node_B.process().unwrap();
            let (_did_work_A, _event_list_A) = node_A.process().unwrap();
            event_list.append(&mut event_list_B);
            did_work |= did_work_B;
        }
        assert!(did_work);
        assert!(event_list.len() >= 1);
        let recv_event = event_list.last().unwrap().clone();
        let (recv_id, recv_payload) = match recv_event {
            TransportEvent::Received(a, b) => (a, b),
            e => panic!("Received wrong TransportEvent type: {:?}", e),
        };
        assert!(node_A.get_uri(idAB.as_str()).is_some());
        assert!(node_B.get_uri(recv_id.as_str()).is_some());

        debug!(
            "node_A.get_uri({:?}): {:?}",
            idAB,
            node_A.get_uri(idAB.as_str()).unwrap()
        );
        debug!(
            "node_B.get_uri({:?}): {:?}",
            recv_id,
            node_B.get_uri(recv_id.as_str()).unwrap()
        );

        assert_eq!(payload, recv_payload.as_slice());
        let (_did_work, _event_list) = node_A.process().unwrap();

        // Send B -> A
        let payload = [4, 2, 1, 3];
        let id_list = node_B.connection_id_list().unwrap();
        // TODO #159 - When connection event is fully implemented use it instead of
        // referencing node_B's connection list
        let idBA = id_list[0].clone();
        node_B.send(&[&idBA], &payload).unwrap();
        did_work = false;
        event_list.clear();
        for _x in 0..NUM_PROCESS_LOOPS {
            let (did_work_A, mut event_list_A) = node_A.process().unwrap();
            let (_did_work_B, _event_list_B) = node_B.process().unwrap();
            did_work |= did_work_A;
            event_list.append(&mut event_list_A);
        }
        assert!(did_work);
        assert_eq!(event_list.len(), 1);
        let recv_event = event_list[0].clone();
        let (recv_id, recv_payload) = match recv_event {
            TransportEvent::Received(a, b) => (a, b),
            _ => panic!("Received wrong TransportEvent type"),
        };
        assert!(node_A.get_uri(recv_id.as_str()).is_some());
        assert!(node_B.get_uri(idBA.as_str()).is_some());

        assert_eq!(payload, recv_payload.as_slice());
    }
}