#[path = "../../../os-waitset/teardown/close.rs"] mod close; use close::{Error, Kind, ObjectKey, SubscriptionId, Teardown}; fn objects() -> [ObjectKey; 3] { [ObjectKey {kind: Kind::Channel, id: 11}, ObjectKey {kind: Kind::Task, id: 12}, ObjectKey {kind: Kind::File, id: 13}] } #[test] fn os_waitsets_teardown_positive() { let mut set = Teardown::::new(7); let [channel, task, file] = objects(); let ids = [set.subscribe(7, channel).unwrap(), set.subscribe(7, task).unwrap(), set.subscribe(7, file).unwrap()]; assert_eq!(set.snapshot().resources, 3); for (index, id) in ids.into_iter().enumerate() { assert_eq!(id.raw() as u32, (index + 1) as u32); } assert_eq!(set.close(7), Ok(3)); let after = set.snapshot(); assert!(after.closed); assert_eq!(after.close_epoch, 1); assert_eq!(after.rows, [None; 3]); assert_eq!(after.resources, 0); assert_eq!(set.close(7), Err(Error::Closed)); assert_eq!(set.subscribe(7, channel), Err(Error::Closed)); assert_eq!(set.snapshot(), after); } #[test] fn os_waitsets_teardown_negative() { let mut set = Teardown::::new(9); let [channel, task, file] = objects(); let first = set.subscribe(9, channel).unwrap(); set.subscribe(9, task).unwrap(); set.subscribe(9, file).unwrap(); let callback = set.begin_peer_callback(first).unwrap(); let before = set.snapshot(); assert_eq!(set.close(8), Err(Error::Access)); assert_eq!(set.snapshot(), before); assert_eq!(set.close(9), Ok(3)); let closed = set.snapshot(); assert_eq!(set.finish_peer_callback(callback), Err(Error::Closed)); assert_eq!(set.begin_peer_callback(first), Err(Error::Closed)); assert_eq!(set.snapshot(), closed); assert_eq!(closed.resources, 0); let mut event_first = Teardown::::new(9); let first = event_first.subscribe(9, channel).unwrap(); event_first.subscribe(9, task).unwrap(); event_first.subscribe(9, file).unwrap(); let callback = event_first.begin_peer_callback(first).unwrap(); event_first.finish_peer_callback(callback).unwrap(); assert!(event_first.snapshot().rows[0].unwrap().peer_dead); assert_eq!(event_first.close(9), Ok(3)); assert_eq!(event_first.snapshot().resources, 0); } #[test] fn duplicate_full_and_stale_callback_denials_are_atomic() { let mut set = Teardown::::new(1); let [channel, task, _] = objects(); let first = set.subscribe(1, channel).unwrap(); let before = set.snapshot(); assert_eq!(set.subscribe(1, channel), Err(Error::Exists)); assert_eq!(set.subscribe(1, task), Err(Error::Full)); assert_eq!(set.begin_peer_callback(SubscriptionId::from_raw(0)), Err(Error::Stale)); assert_eq!(set.snapshot(), before); let callback = set.begin_peer_callback(first).unwrap(); set.finish_peer_callback(callback).unwrap(); assert!(set.snapshot().rows[0].unwrap().peer_dead); assert_eq!(set.close(1), Ok(1)); assert_eq!(set.snapshot().resources, 0); }