From e4116bb9d7b76adbd05683297fae8d37d70000c1 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sat, 13 Apr 2024 21:43:31 -0700 Subject: [PATCH] feat: Make sure loom tests actually exist Signed-off-by: John Nunley --- tests/loom.rs | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 tests/loom.rs diff --git a/tests/loom.rs b/tests/loom.rs new file mode 100644 index 0000000..9a6ef7e --- /dev/null +++ b/tests/loom.rs @@ -0,0 +1,212 @@ +#![cfg(loom)] +use std::future::Future; +use std::pin::Pin; +use std::sync::{Arc, Mutex}; +use std::task::Context; +use std::usize; + +use event_listener::{Event, EventListener}; +use waker_fn::waker_fn; + +#[cfg(target_family = "wasm")] +use wasm_bindgen_test::wasm_bindgen_test as test; + +fn is_notified(listener: &mut EventListener) -> bool { + let waker = waker_fn(|| ()); + Pin::new(listener) + .poll(&mut Context::from_waker(&waker)) + .is_ready() +} + +#[test] +fn notify() { + loom::model(|| { + let event = Event::new(); + + let mut l1 = event.listen(); + let mut l2 = event.listen(); + let mut l3 = event.listen(); + + assert!(!is_notified(&mut l1)); + assert!(!is_notified(&mut l2)); + assert!(!is_notified(&mut l3)); + + assert_eq!(event.notify(2), 2); + assert_eq!(event.notify(1), 0); + + assert!(is_notified(&mut l1)); + assert!(is_notified(&mut l2)); + assert!(!is_notified(&mut l3)); + }); +} + +#[test] +fn notify_additional() { + loom::model(|| { + let event = Event::new(); + + let mut l1 = event.listen(); + let mut l2 = event.listen(); + let mut l3 = event.listen(); + + assert_eq!(event.notify_additional(1), 1); + assert_eq!(event.notify(1), 0); + assert_eq!(event.notify_additional(1), 1); + + assert!(is_notified(&mut l1)); + assert!(is_notified(&mut l2)); + assert!(!is_notified(&mut l3)); + }) +} + +#[test] +fn notify_one() { + loom::model(|| { + let event = Event::new(); + + let mut l1 = event.listen(); + let mut l2 = event.listen(); + + assert!(!is_notified(&mut l1)); + assert!(!is_notified(&mut l2)); + + assert_eq!(event.notify(1), 1); + assert!(is_notified(&mut l1)); + assert!(!is_notified(&mut l2)); + + assert_eq!(event.notify(1), 1); + assert!(is_notified(&mut l2)); + }); +} + +#[test] +fn notify_all() { + loom::model(|| { + let event = Event::new(); + + let mut l1 = event.listen(); + let mut l2 = event.listen(); + + assert!(!is_notified(&mut l1)); + assert!(!is_notified(&mut l2)); + + assert_eq!(event.notify(usize::MAX), 2); + assert!(is_notified(&mut l1)); + assert!(is_notified(&mut l2)); + }); +} + +#[test] +fn drop_notified() { + loom::model(|| { + let event = Event::new(); + + let l1 = event.listen(); + let mut l2 = event.listen(); + let mut l3 = event.listen(); + + assert_eq!(event.notify(1), 1); + drop(l1); + assert!(is_notified(&mut l2)); + assert!(!is_notified(&mut l3)); + }); +} + +#[test] +fn drop_notified2() { + loom::model(|| { + let event = Event::new(); + + let l1 = event.listen(); + let mut l2 = event.listen(); + let mut l3 = event.listen(); + + assert_eq!(event.notify(2), 2); + drop(l1); + assert!(is_notified(&mut l2)); + assert!(!is_notified(&mut l3)); + }); +} + +#[test] +fn drop_notified_additional() { + loom::model(|| { + let event = Event::new(); + + let l1 = event.listen(); + let mut l2 = event.listen(); + let mut l3 = event.listen(); + let mut l4 = event.listen(); + + assert_eq!(event.notify_additional(1), 1); + assert_eq!(event.notify(2), 1); + drop(l1); + assert!(is_notified(&mut l2)); + assert!(is_notified(&mut l3)); + assert!(!is_notified(&mut l4)); + }); +} + +#[test] +fn drop_non_notified() { + loom::model(|| { + let event = Event::new(); + + let mut l1 = event.listen(); + let mut l2 = event.listen(); + let l3 = event.listen(); + + assert_eq!(event.notify(1), 1); + drop(l3); + assert!(is_notified(&mut l1)); + assert!(!is_notified(&mut l2)); + }) +} + +#[test] +fn notify_all_fair() { + loom::model(|| { + let event = Event::new(); + let v = Arc::new(Mutex::new(vec![])); + + let mut l1 = event.listen(); + let mut l2 = event.listen(); + let mut l3 = event.listen(); + + let waker1 = { + let v = v.clone(); + waker_fn(move || v.lock().unwrap().push(1)) + }; + let waker2 = { + let v = v.clone(); + waker_fn(move || v.lock().unwrap().push(2)) + }; + let waker3 = { + let v = v.clone(); + waker_fn(move || v.lock().unwrap().push(3)) + }; + + assert!(Pin::new(&mut l1) + .poll(&mut Context::from_waker(&waker1)) + .is_pending()); + assert!(Pin::new(&mut l2) + .poll(&mut Context::from_waker(&waker2)) + .is_pending()); + assert!(Pin::new(&mut l3) + .poll(&mut Context::from_waker(&waker3)) + .is_pending()); + + assert_eq!(event.notify(usize::MAX), 3); + assert_eq!(&*v.lock().unwrap(), &[1, 2, 3]); + + assert!(Pin::new(&mut l1) + .poll(&mut Context::from_waker(&waker1)) + .is_ready()); + assert!(Pin::new(&mut l2) + .poll(&mut Context::from_waker(&waker2)) + .is_ready()); + assert!(Pin::new(&mut l3) + .poll(&mut Context::from_waker(&waker3)) + .is_ready()); + }) +} \ No newline at end of file