use turkos_os_init_reaper::{Cause, Error, Outcome, Pid, Reaper, WaitAdapter}; #[derive(Default)] struct Fake { waits: Vec, fail_once: bool } impl WaitAdapter for Fake { fn wait_child(&mut self, pid: Pid) -> Result { self.waits.push(pid); if self.fail_once { self.fail_once = false; Err(Cause::Busy) } else if pid == Pid(2) { Ok(Outcome::Fault(0x9000_0000)) } else { Ok(Outcome::Exited(42)) } } } #[test] fn os_init_reaper_collects_exit_and_fault_in_registration_order() { let mut reaper = Reaper::<3>::new(); reaper.track(Pid(1)).unwrap(); reaper.track(Pid(2)).unwrap(); reaper.track(Pid(3)).unwrap(); reaper.observe_exit(Pid(2)).unwrap(); reaper.observe_exit(Pid(1)).unwrap(); let mut adapter = Fake::default(); assert_eq!(reaper.reap_next(&mut adapter), Ok(Some((Pid(1), Outcome::Exited(42))))); assert_eq!(reaper.reap_next(&mut adapter), Ok(Some((Pid(2), Outcome::Fault(0x9000_0000))))); assert_eq!(reaper.reap_next(&mut adapter), Ok(None)); assert_eq!(reaper.owned(), 1); assert_eq!(reaper.ready(), 0); assert_eq!(adapter.waits, [Pid(1), Pid(2)]); } #[test] fn os_init_reaper_rejects_duplicate_unknown_and_capacity() { let mut reaper = Reaper::<1>::new(); assert_eq!(reaper.track(Pid(0)), Err(Error::InvalidPid)); reaper.track(Pid(7)).unwrap(); assert_eq!(reaper.track(Pid(7)), Err(Error::Duplicate)); assert_eq!(reaper.track(Pid(8)), Err(Error::Full)); assert_eq!(reaper.observe_exit(Pid(8)), Err(Error::Unknown)); reaper.observe_exit(Pid(7)).unwrap(); assert_eq!(reaper.observe_exit(Pid(7)), Err(Error::AlreadyObserved)); let mut adapter = Fake::default(); assert_eq!(reaper.reap_next(&mut adapter), Ok(Some((Pid(7), Outcome::Exited(42))))); assert_eq!(reaper.track(Pid(7)), Ok(())); } #[test] fn os_init_reaper_wait_failure_retains_child_for_retry() { let mut reaper = Reaper::<2>::new(); reaper.track(Pid(2)).unwrap(); reaper.observe_exit(Pid(2)).unwrap(); let mut adapter = Fake {fail_once: true, ..Fake::default()}; assert_eq!(reaper.reap_next(&mut adapter), Err(Error::Wait(Cause::Busy))); assert!(reaper.contains(Pid(2))); assert_eq!((reaper.owned(), reaper.ready()), (1, 1)); assert_eq!(reaper.reap_next(&mut adapter), Ok(Some((Pid(2), Outcome::Fault(0x9000_0000))))); assert_eq!((reaper.owned(), reaper.ready()), (0, 0)); assert_eq!(adapter.waits, [Pid(2), Pid(2)]); }