use crate::worker::{operate, ReadWrapper, WriteWrapper}; use std::io::{self, Read, Write}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread::JoinHandle; enum Request { Read(u32, usize, Sender>), Write(Vec), } struct FakeReader { channel: Sender, number: u32, } impl Read for FakeReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { let (tx, rx) = channel(); self.channel.send(Request::Read( self.number, buf.len(), tx, )).unwrap(); let result = rx.recv().unwrap(); buf[0..result.len()].copy_from_slice(&result[..]); Ok(result.len()) } } struct FakeWriter { channel: Sender, } impl Write for FakeWriter { fn write(&mut self, buf: &[u8]) -> io::Result { self.channel.send(Request::Write( Vec::from(buf), )).unwrap(); Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } struct Test { join_handle: JoinHandle>, recv: Receiver, } impl Test { fn new() -> Test { let (tx, rx) = channel(); let rd1 = FakeReader { channel: tx.clone(), number: 0 }; let rd2 = FakeReader { channel: tx.clone(), number: 1, }; let wr = FakeWriter { channel: tx, }; let join_handle = std::thread::spawn(move || -> Result<(), String> { let in1 = ReadWrapper { stream: rd1, name: "reader1", }; let in2 = ReadWrapper { stream: rd2, name: "reader2", }; let out = WriteWrapper { stream: wr, name: "writer", }; operate(in1, in2, out) }); Test { join_handle, recv: rx, } } fn reading(&mut self, reader_nr: u32, size: usize, data: Vec) { let req = self.recv.recv().unwrap(); match req { Request::Read(req_nr, req_size, back) => { assert_eq!(reader_nr, req_nr); assert_eq!(size, req_size); back.send(data).unwrap(); }, _ => panic!("Unexpected behaviour"), } } fn writing(&mut self, data: Vec) { let req = self.recv.recv().unwrap(); match req { Request::Write(req_data) => { assert_eq!(req_data, data); }, _ => panic!("Unexpected behaviour"), } } fn terminate(self, return_val: Result<(), String>) { let result = self.join_handle.join().unwrap(); assert_eq!(return_val, result); } } #[test] fn parallel_reading() { let mut t = Test::new(); t.reading(0, 65536, vec![0x01, 0x02, 0x03]); t.reading(1, 3, vec![0x50, 0x60, 0x70]); t.writing(vec![0x51, 0x62, 0x73]); t.reading(0, 65536, vec![]); t.terminate(Ok(())); } #[test] #[should_panic] fn panic_on_wrong_reader() { let mut t = Test::new(); t.reading(0, 65536, vec![0x01, 0x02, 0x03]); t.reading(1, 3, vec![0x50, 0x60, 0x70]); t.writing(vec![0x51, 0x62, 0x73]); t.reading(1, 65536, vec![]); t.terminate(Ok(())); } #[test] #[should_panic] fn panic_on_wrong_reading_size() { let mut t = Test::new(); t.reading(0, 65536, vec![0x01, 0x02, 0x03]); t.reading(1, 4, vec![0x50, 0x60, 0x70]); t.writing(vec![0x51, 0x62, 0x73]); t.reading(0, 65536, vec![]); t.terminate(Ok(())); } #[test] #[should_panic] fn panic_on_wrong_output_data() { let mut t = Test::new(); t.reading(0, 65536, vec![0x01, 0x02, 0x03]); t.reading(1, 3, vec![0x50, 0x60, 0x70]); t.writing(vec![0x51, 0x62, 0x74]); t.reading(0, 65536, vec![]); t.terminate(Ok(())); } #[test] fn left_reads_more() { let mut t = Test::new(); t.reading(0, 65536, vec![0x01, 0x02, 0x03]); t.reading(1, 3, vec![0x50]); t.writing(vec![0x51]); t.reading(1, 2, vec![0x60]); t.writing(vec![0x62]); t.reading(1, 1, vec![0x70]); t.writing(vec![0x73]); t.reading(0, 65536, vec![]); t.terminate(Ok(())); } #[test] fn left_is_larger() { let mut t = Test::new(); t.reading(0, 65536, vec![0x01, 0x02, 0x03]); t.reading(1, 3, vec![0x50, 0x60, 0x70]); t.writing(vec![0x51, 0x62, 0x73]); t.reading(0, 65536, vec![0x04, 0x05, 0x06]); t.reading(1, 3, vec![]); t.writing(vec![0x04, 0x05, 0x06]); t.reading(0, 65536, vec![0x07, 0x08, 0x09]); t.writing(vec![0x07, 0x08, 0x09]); t.reading(0, 65536, vec![]); t.terminate(Ok(())); }