summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/fakes/fake_input.rs153
-rw-r--r--src/tests/fakes/fake_output.rs108
-rw-r--r--src/tests/fakes/mod.rs5
-rw-r--r--src/tests/mod.rs793
-rw-r--r--src/tests/snapshots/tests__basic_startup.snap55
-rw-r--r--src/tests/snapshots/tests__bi_directional_traffic-2.snap55
-rw-r--r--src/tests/snapshots/tests__bi_directional_traffic.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_connections_from_remote_ip-2.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_connections_from_remote_ip.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_packets_of_traffic_from_different_connections-2.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_packets_of_traffic_from_different_connections.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_packets_of_traffic_from_single_connection-2.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_packets_of_traffic_from_single_connection.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_processes_with_multiple_connections-2.snap55
-rw-r--r--src/tests/snapshots/tests__multiple_processes_with_multiple_connections.snap55
-rw-r--r--src/tests/snapshots/tests__one_packet_of_traffic-2.snap55
-rw-r--r--src/tests/snapshots/tests__one_packet_of_traffic.snap55
-rw-r--r--src/tests/snapshots/tests__one_process_with_multiple_connections-2.snap55
-rw-r--r--src/tests/snapshots/tests__one_process_with_multiple_connections.snap55
-rw-r--r--src/tests/snapshots/tests__sustained_traffic_from_multiple_processes-2.snap55
-rw-r--r--src/tests/snapshots/tests__sustained_traffic_from_multiple_processes.snap55
-rw-r--r--src/tests/snapshots/tests__sustained_traffic_from_multiple_processes_bi_directional-2.snap55
-rw-r--r--src/tests/snapshots/tests__sustained_traffic_from_multiple_processes_bi_directional.snap55
-rw-r--r--src/tests/snapshots/tests__sustained_traffic_from_one_process-2.snap55
-rw-r--r--src/tests/snapshots/tests__sustained_traffic_from_one_process.snap55
-rw-r--r--src/tests/snapshots/tests__traffic_with_host_names-2.snap55
-rw-r--r--src/tests/snapshots/tests__traffic_with_host_names.snap55
27 files changed, 2324 insertions, 0 deletions
diff --git a/src/tests/fakes/fake_input.rs b/src/tests/fakes/fake_input.rs
new file mode 100644
index 0000000..6007b71
--- /dev/null
+++ b/src/tests/fakes/fake_input.rs
@@ -0,0 +1,153 @@
+use ::ipnetwork::IpNetwork;
+use ::pnet::datalink::DataLinkReceiver;
+use ::pnet::datalink::NetworkInterface;
+use ::std::collections::HashMap;
+use ::std::net::{IpAddr, Ipv4Addr, SocketAddr};
+use ::std::{thread, time};
+use ::termion::event::Event;
+
+use crate::network::{Connection, Protocol};
+
+pub struct KeyboardEvents {
+ pub events: Vec<Option<Event>>,
+}
+
+impl KeyboardEvents {
+ pub fn new(mut events: Vec<Option<Event>>) -> Self {
+ events.reverse(); // this is so that we do not have to shift the array
+ KeyboardEvents { events }
+ }
+}
+impl Iterator for KeyboardEvents {
+ type Item = Event;
+ fn next(&mut self) -> Option<Event> {
+ match self.events.pop() {
+ Some(ev) => {
+ match ev {
+ Some(ev) => Some(ev), // TODO: better
+ None => {
+ thread::sleep(time::Duration::from_secs(1));
+ self.next()
+ }
+ }
+ }
+ None => None,
+ }
+ }
+}
+
+pub struct NetworkFrames {
+ pub packets: Vec<Option<Vec<u8>>>,
+ pub current_index: usize,
+}
+
+impl NetworkFrames {
+ pub fn new(packets: Vec<Option<Vec<u8>>>) -> Box<Self> {
+ Box::new(NetworkFrames {
+ packets,
+ current_index: 0,
+ })
+ }
+ fn next_packet(&mut self) -> &Option<Vec<u8>> {
+ let next_index = self.current_index;
+ self.current_index += 1;
+ &self.packets[next_index]
+ }
+}
+impl DataLinkReceiver for NetworkFrames {
+ fn next(&mut self) -> Result<&[u8], std::io::Error> {
+ if self.current_index == 0 {
+ // make it less likely to have a race condition with the display loop
+ // this is so the tests pass consistently
+ thread::sleep(time::Duration::from_millis(500));
+ }
+ match self.current_index < self.packets.len() {
+ true => {
+ let action = self.next_packet();
+ match action {
+ Some(packet) => {
+ Ok(&packet[..]) // TODO: better
+ }
+ None => {
+ thread::sleep(time::Duration::from_secs(1));
+ Ok(&[][..])
+ }
+ }
+ }
+ false => {
+ thread::sleep(time::Duration::from_secs(1));
+ Ok(&[][..])
+ }
+ }
+ }
+}
+
+pub fn get_open_sockets() -> HashMap<Connection, String> {
+ let mut open_sockets = HashMap::new();
+ open_sockets.insert(
+ Connection::new(
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 443),
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 12345),
+ Protocol::Tcp,
+ )
+ .unwrap(),
+ String::from("1"),
+ );
+ open_sockets.insert(
+ Connection::new(
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 443),
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(2, 2, 2, 2)), 54321),
+ Protocol::Tcp,
+ )
+ .unwrap(),
+ String::from("4"),
+ );
+ open_sockets.insert(
+ Connection::new(
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 443),
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(3, 3, 3, 3)), 1337),
+ Protocol::Tcp,
+ )
+ .unwrap(),
+ String::from("5"),
+ );
+ open_sockets.insert(
+ Connection::new(
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 443),
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(4, 4, 4, 4)), 1337),
+ Protocol::Tcp,
+ )
+ .unwrap(),
+ String::from("2"),
+ );
+ open_sockets.insert(
+ Connection::new(
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 443),
+ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 12346),
+ Protocol::Tcp,
+ )
+ .unwrap(),
+ String::from("3"),
+ );
+ open_sockets
+}
+
+pub fn get_interface() -> NetworkInterface {
+ let interface = NetworkInterface {
+ name: String::from("foo"),
+ index: 42,
+ mac: None,
+ ips: vec![IpNetwork::V4("10.0.0.2".parse().unwrap())],
+ flags: 42,
+ };
+ interface
+}
+
+pub fn create_fake_lookup_addr(
+ ips_to_hosts: HashMap<IpAddr, String>,
+) -> Box<Fn(&IpAddr) -> Option<String> + Send + Sync + 'static> {
+ Box::new(move |ip| match ips_to_hosts.get(ip) {
+ Some(host) => Some(host.clone()),
+ None => None,
+ })
+}
diff --git a/src/tests/fakes/fake_output.rs b/src/tests/fakes/fake_output.rs
new file mode 100644
index 0000000..6fb356c
--- /dev/null
+++ b/src/tests/fakes/fake_output.rs
@@ -0,0 +1,108 @@
+use ::std::collections::HashMap;
+use ::std::io;
+use ::std::sync::{Arc, Mutex};
+use ::tui::backend::Backend;
+use ::tui::buffer::Cell;
+use ::tui::layout::Rect;
+
+#[derive(Hash, Debug, PartialEq)]
+pub enum TerminalEvent {
+ Clear,
+ HideCursor,
+ ShowCursor,
+ GetCursor,
+ Flush,
+ Draw,
+}
+
+pub struct TestBackend {
+ pub events: Arc<Mutex<Vec<TerminalEvent>>>,
+ pub draw_events: Arc<Mutex<Vec<String>>>,
+ terminal_width: u16,
+ terminal_height: u16,
+}
+
+impl TestBackend {
+ pub fn new(
+ log: Arc<Mutex<Vec<TerminalEvent>>>,
+ draw_log: Arc<Mutex<Vec<String>>>,
+ ) -> TestBackend {
+ TestBackend {
+ events: log,
+ draw_events: draw_log,
+ terminal_width: 190,
+ terminal_height: 50,
+ }
+ }
+}
+
+#[derive(Hash, Eq, PartialEq)]
+struct Point {
+ x: u16,
+ y: u16,
+}
+
+impl Backend for TestBackend {
+ fn clear(&mut self) -> io::Result<()> {
+ self.events.lock().unwrap().push(TerminalEvent::Clear);
+ Ok(())
+ }
+
+ fn hide_cursor(&mut self) -> io::Result<()> {
+ self.events.lock().unwrap().push(TerminalEvent::HideCursor);
+ Ok(())
+ }
+
+ fn show_cursor(&mut self) -> io::Result<()> {
+ self.events.lock().unwrap().push(TerminalEvent::ShowCursor);
+ Ok(())
+ }
+
+ fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
+ self.events.lock().unwrap().push(TerminalEvent::GetCursor);
+ Ok((0, 0))
+ }
+
+ fn set_cursor(&mut self, _x: u16, _y: u16) -> io::Result<()> {
+ Ok(())
+ }
+
+ fn draw<'a, I>(&mut self, content: I) -> io::Result<()>
+ where
+ I: Iterator<Item = (u16, u16, &'a Cell)>,
+ {
+ // use std::fmt::Write;
+ self.events.lock().unwrap().push(TerminalEvent::Draw);
+ let mut string = String::with_capacity(content.size_hint().0 * 3);
+ let mut coordinates = HashMap::new();
+ for (x, y, cell) in content {
+ coordinates.insert(Point { x, y }, cell);
+ }
+ for y in 0..self.terminal_height {
+ for x in 0..self.terminal_width {
+ match coordinates.get(&Point { x, y }) {
+ Some(cell) => {
+ // this will contain no style information at all
+ // should be good enough for testing
+ string.push_str(&cell.symbol);
+ }
+ None => {
+ string.push_str(" ");
+ }
+ }
+ }
+ string.push_str("\n");
+ }
+ self.draw_events.lock().unwrap().push(string);
+ Ok(())
+ }
+
+ fn size(&self) -> io::Result<Rect> {
+ Ok(Rect::new(0, 0, self.terminal_width, self.terminal_height))
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.events.lock().unwrap().push(TerminalEvent::Flush);
+ Ok(())
+ }
+}
diff --git a/src/tests/fakes/mod.rs b/src/tests/fakes/mod.rs
new file mode 100644
index 0000000..dcd441b
--- /dev/null
+++ b/src/tests/fakes/mod.rs
@@ -0,0 +1,5 @@
+mod fake_input;
+mod fake_output;
+
+pub use fake_input::*;
+pub use fake_output::*;
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
new file mode 100644
index 0000000..b3a5d9d
--- /dev/null
+++ b/src/tests/mod.rs
@@ -0,0 +1,793 @@
+mod fakes;
+
+use fakes::TerminalEvent::*;
+use fakes::{
+ create_fake_lookup_addr, get_interface, get_open_sockets, KeyboardEvents, NetworkFrames,
+ TestBackend,
+};
+
+use ::insta::assert_snapshot;
+use ::std::sync::{Arc, Mutex};
+use ::termion::event::{Event, Key};
+
+use ::std::collections::HashMap;
+use ::std::net::IpAddr;
+
+use packet_builder::payload::PayloadData;
+use packet_builder::*;
+use pnet::packet::Packet;
+use pnet_base::MacAddr;
+
+fn build_tcp_packet(
+ source_ip: &str,
+ destination_ip: &str,
+ source_port: u16,
+ destination_port: u16,
+ payload: &'static [u8],
+) -> Vec<u8> {
+ let mut pkt_buf = [0u8; 1500];
+ let pkt = packet_builder!(
+ pkt_buf,
+ ether({set_destination => MacAddr(0,0,0,0,0,0), set_source => MacAddr(0,0,0,0,0,0)}) /
+ ipv4({set_source => ipv4addr!(source_ip), set_destination => ipv4addr!(destination_ip) }) /
+ tcp({set_source => source_port, set_destination => destination_port }) /
+ payload(payload)
+ );
+ pkt.packet().to_vec()
+}
+
+struct LogWithMirror<T> {
+ pub write: Arc<Mutex<T>>,
+ pub mirror: Arc<Mutex<T>>,
+}
+
+impl<T> LogWithMirror<T> {
+ pub fn new(log: T) -> Self {
+ let write = Arc::new(Mutex::new(log));
+ let mirror = write.clone();
+ LogWithMirror { write, mirror }
+ }
+}
+
+#[test]
+fn basic_startup() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ None, // sleep
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 1);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+}
+
+#[test]
+fn one_packet_of_traffic() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![Some(build_tcp_packet(
+ "10.0.0.2",
+ "1.1.1.1",
+ 443,
+ 12345,
+ b"I am a fake tcp packet",
+ ))]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn bi_directional_traffic() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "10.0.0.2",
+ "1.1.1.1",
+ 443,
+ 12345,
+ b"I am a fake tcp upload packet",
+ )),
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I am a fake tcp download packet",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn multiple_packets_of_traffic_from_different_connections() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ Some(build_tcp_packet(
+ "2.2.2.2",
+ "10.0.0.2",
+ 54321,
+ 443,
+ b"I come from 2.2.2.2",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn multiple_packets_of_traffic_from_single_connection() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I've come from 1.1.1.1 too!",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn one_process_with_multiple_connections() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ Some(build_tcp_packet(
+ "3.3.3.3",
+ "10.0.0.2",
+ 1337,
+ 443,
+ b"Funny that, I'm from 3.3.3.3",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn multiple_processes_with_multiple_connections() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ Some(build_tcp_packet(
+ "3.3.3.3",
+ "10.0.0.2",
+ 1337,
+ 443,
+ b"Awesome, I'm from 3.3.3.3",
+ )),
+ Some(build_tcp_packet(
+ "2.2.2.2",
+ "10.0.0.2",
+ 54321,
+ 443,
+ b"You know, 2.2.2.2 is really nice!",
+ )),
+ Some(build_tcp_packet(
+ "4.4.4.4",
+ "10.0.0.2",
+ 1337,
+ 443,
+ b"I'm partial to 4.4.4.4",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn multiple_connections_from_remote_ip() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12346,
+ 443,
+ b"Me too, but on a different port",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 2);
+ assert_snapshot!(&terminal_draw_events_mirror[0]);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+}
+
+#[test]
+fn sustained_traffic_from_one_process() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ None, // sleep
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"Same here, but one second later",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..]);
+
+ assert_eq!(terminal_draw_events_mirror.len(), 3);
+ assert_snapshot!(&terminal_draw_events_mirror[1]);
+ assert_snapshot!(&terminal_draw_events_mirror[2]);
+}
+
+#[test]
+fn sustained_traffic_from_multiple_processes() {
+ let keyboard_events = Box::new(KeyboardEvents::new(vec![
+ None, // sleep
+ None, // sleep
+ None, // sleep
+ Some(Event::Key(Key::Ctrl('c'))),
+ ]));
+ let network_frames = NetworkFrames::new(vec![
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1",
+ )),
+ Some(build_tcp_packet(
+ "3.3.3.3",
+ "10.0.0.2",
+ 1337,
+ 443,
+ b"I come from 3.3.3.3",
+ )),
+ None, // sleep
+ Some(build_tcp_packet(
+ "1.1.1.1",
+ "10.0.0.2",
+ 12345,
+ 443,
+ b"I have come from 1.1.1.1 one second later",
+ )),
+ Some(build_tcp_packet(
+ "3.3.3.3",
+ "10.0.0.2",
+ 1337,
+ 443,
+ b"I come 3.3.3.3 one second later",
+ )),
+ ]);
+
+ let terminal_events = LogWithMirror::new(Vec::new());
+ let terminal_draw_events = LogWithMirror::new(Vec::new());
+
+ let backend = TestBackend::new(terminal_events.write, terminal_draw_events.write);
+ let network_interface = get_interface();
+ let lookup_addr = create_fake_lookup_addr(HashMap::new());
+
+ let os_input = crate::OsInput {
+ network_interface,
+ network_frames,
+ get_open_sockets,
+ keyboard_events,
+ lookup_addr,
+ };
+ crate::start(backend, os_input);
+
+ let terminal_events_mirror = terminal_events.mirror.lock().unwrap();
+ let terminal_draw_events_mirror = terminal_draw_events.mirror.lock().unwrap();
+
+ let expected_terminal_events = vec![
+ Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor,
+ ];
+ assert_eq!(&terminal_events_mirror[..], &expected_terminal_events[..])