use super::*; struct TestPinManager { input_pins: Vec, pulse_recv: Arc>>, } impl InputPinManager for TestPinManager { fn set_input_config(&mut self, input_pins: Vec) { *&mut self.input_pins = input_pins; } fn get_channel_recv(&self) -> &Arc>> { &self.pulse_recv } fn get_pins(&self) -> &Vec { &self.input_pins } fn close_inputs(&mut self) {} } impl TestPinManager { fn new(cmd_rx: mpsc::Receiver) -> TestPinManager { let (pulse_tx, pulse_rx) = mpsc::channel::(); thread::spawn(move || loop { match cmd_rx.recv() { Ok(cmd) => { if cmd.timestamp_ns == 0u64 { break; } else { &pulse_tx.send(cmd); } } Err(_) => break, } }); Self { input_pins: vec![], pulse_recv: Arc::new(Mutex::new(pulse_rx)), } } } #[test] fn new_creates_instance() { let (_, cmd_rx) = mpsc::channel(); let test_pin_manager_box: Box = Box::new(TestPinManager::new(cmd_rx)); let mut input_pins = Vec::new(); input_pins.push(PinConfiguration { id: 1, gpio: 11 }); input_pins.push(PinConfiguration { id: 3, gpio: 33 }); let input_pins_copy = &input_pins.clone(); let testee = PulseCounter::new(test_pin_manager_box, input_pins); let testee_pins = &testee.pin_mgr.get_pins(); assert_eq!(testee_pins.len(), input_pins_copy.len()); assert_eq!(testee_pins[0], input_pins_copy[0]); assert_eq!(testee_pins[1], input_pins_copy[1]); } #[test] fn start_and_stop_thread() { let (_, cmd_rx) = mpsc::channel(); let test_pin_manager_box: Box = Box::new(TestPinManager::new(cmd_rx)); let mut input_pins = Vec::new(); input_pins.push(PinConfiguration { id: 1, gpio: 11 }); input_pins.push(PinConfiguration { id: 3, gpio: 33 }); let mut testee = PulseCounter::new(test_pin_manager_box, input_pins); assert!(testee.start().is_ok()); std::thread::sleep(std::time::Duration::from_millis(10)); testee.stop(); } #[test] fn start_thread_twice() { // ATTENTION: Do NOT use _ as name of the tx channel because the channel would be closed // immediately and the thread would exit before it will be started the second time! let (_usused_but_required_tx, cmd_rx) = mpsc::channel(); let test_pin_manager_box = Box::new(TestPinManager::new(cmd_rx)); let mut input_pins = Vec::new(); input_pins.push(PinConfiguration { id: 1, gpio: 11 }); input_pins.push(PinConfiguration { id: 3, gpio: 33 }); let mut testee = PulseCounter::new(test_pin_manager_box, input_pins); assert!(testee.start().is_ok()); std::thread::sleep(std::time::Duration::from_millis(10)); let result = testee.start(); assert!(&result.is_err()); std::thread::sleep(std::time::Duration::from_millis(10)); } #[test] fn start_thread_and_send_pulses() { let millis_to_wait = 1u64; let (cmd_tx, cmd_rx) = mpsc::channel(); let test_pin_manager_box: Box = Box::new(TestPinManager::new(cmd_rx)); let mut input_pins = Vec::new(); input_pins.push(PinConfiguration { id: 1, gpio: 11 }); input_pins.push(PinConfiguration { id: 3, gpio: 33 }); let mut testee = PulseCounter::new(test_pin_manager_box, input_pins); assert!(testee.start().is_ok()); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); assert_eq!(testee.get_pulses_count_by_channel(1), 0); assert_eq!(testee.get_pulses_count_by_channel(3), 0); &cmd_tx.send(PulseInfo { timestamp_ns: 1234u64, pin_id: 1, level: true, }); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); assert_eq!(testee.get_pulses_count_by_channel(1), 1); assert_eq!(testee.get_pulses_count_by_channel(3), 0); &cmd_tx.send(PulseInfo { timestamp_ns: 1235u64, pin_id: 1, level: false, }); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); assert_eq!(testee.get_pulses_count_by_channel(1), 2); assert_eq!(testee.get_pulses_count_by_channel(3), 0); &cmd_tx.send(PulseInfo { timestamp_ns: 1280u64, pin_id: 3, level: true, }); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); assert_eq!(testee.get_pulses_count_by_channel(1), 2); assert_eq!(testee.get_pulses_count_by_channel(3), 1); &cmd_tx.send(PulseInfo { timestamp_ns: 1288u64, pin_id: 3, level: false, }); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); assert_eq!(testee.get_pulses_count_by_channel(1), 2); assert_eq!(testee.get_pulses_count_by_channel(3), 2); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); testee.stop(); } #[test] fn retrieve_pulses_by_channel() { let millis_to_wait = 1u64; let (cmd_tx, cmd_rx) = mpsc::channel(); let test_pin_manager_box: Box = Box::new(TestPinManager::new(cmd_rx)); let mut input_pins = Vec::new(); input_pins.push(PinConfiguration { id: 1, gpio: 11 }); input_pins.push(PinConfiguration { id: 3, gpio: 33 }); let mut testee = PulseCounter::new(test_pin_manager_box, input_pins); assert!(testee.start().is_ok()); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); &cmd_tx.send(PulseInfo { timestamp_ns: 1234u64, pin_id: 1, level: true, }); &cmd_tx.send(PulseInfo { timestamp_ns: 1235u64, pin_id: 1, level: false, }); &cmd_tx.send(PulseInfo { timestamp_ns: 1280u64, pin_id: 3, level: true, }); &cmd_tx.send(PulseInfo { timestamp_ns: 1288u64, pin_id: 3, level: false, }); std::thread::sleep(std::time::Duration::from_millis(millis_to_wait)); assert_eq!(testee.get_pulses_count_by_channel(1), 2); assert_eq!(testee.get_pulses_count_by_channel(3), 2); let pulses_ch1 = testee.get_pulses_by_channel(1); assert_eq!(pulses_ch1.len(), 2); assert_eq!(pulses_ch1[0].timestamp_ns, 1234u64); assert_eq!(pulses_ch1[0].pin_id, 1); assert_eq!(pulses_ch1[0].level, true); assert_eq!(pulses_ch1[1].timestamp_ns, 1235u64); assert_eq!(pulses_ch1[1].pin_id, 1); assert_eq!(pulses_ch1[1].level, false); let pulses_ch1 = testee.get_pulses_by_channel(1); assert_eq!(pulses_ch1.len(), 0); let pulses_ch1 = testee.get_pulses_by_channel(3); assert_eq!(pulses_ch1.len(), 2); assert_eq!(pulses_ch1[0].timestamp_ns, 1280u64); assert_eq!(pulses_ch1[0].pin_id, 3); assert_eq!(pulses_ch1[0].level, true); assert_eq!(pulses_ch1[1].timestamp_ns, 1288u64); assert_eq!(pulses_ch1[1].pin_id, 3); assert_eq!(pulses_ch1[1].level, false); let pulses_ch1 = testee.get_pulses_by_channel(3); assert_eq!(pulses_ch1.len(), 0); }