use std::cell::Cell;
use std::future::poll_fn;
use std::panic::AssertUnwindSafe;
use std::panic::catch_unwind;
use std::pin::pin;
use std::task::Poll;
use super::Group;
use crate::test_support::poll_once;
fn entry_count<K, V, S>(group: &Group<K, V, S>) -> usize {
group.entries.lock().len()
}
#[test]
fn panicked_work_removes_empty_entry() {
let group = Group::<&str, String>::new();
let result = catch_unwind(AssertUnwindSafe(|| {
let mut work = pin!(group.work("key", || async {
panic!("oops");
}));
let _ = poll_once(work.as_mut());
}));
assert!(result.is_err());
assert_eq!(entry_count(&group), 0);
let mut retry = pin!(group.work("key", || async { "success".to_owned() }));
assert_eq!(poll_once(retry.as_mut()), Poll::Ready("success".to_owned()));
}
#[test]
fn cancelled_work_removes_empty_entry() {
let group = Group::<&str, &str>::new();
{
let mut work = pin!(group.work("key", || async { std::future::pending::<&str>().await }));
assert!(poll_once(work.as_mut()).is_pending());
assert_eq!(entry_count(&group), 1);
}
assert_eq!(entry_count(&group), 0);
}
#[test]
fn failed_try_work_removes_empty_entry() {
let group = Group::new();
let mut work = pin!(group.try_work("key", || async { Err::<&str, &str>("error") }));
assert_eq!(poll_once(work.as_mut()), Poll::Ready(Err("error")));
assert_eq!(entry_count(&group), 0);
let mut retry = pin!(group.try_work("key", || async { Ok::<&str, ()>("success") }));
assert_eq!(poll_once(retry.as_mut()), Poll::Ready(Ok("success")));
}
#[test]
fn failed_try_work_preserves_entry_for_waiter_retry() {
let group = Group::new();
let released = Cell::new(false);
let first = group.try_work("key", || async {
poll_fn(|_| {
released
.get()
.then_some(())
.map_or(Poll::Pending, Poll::Ready)
})
.await;
Err::<&str, &str>("fail")
});
let mut first = pin!(first);
assert!(poll_once(first.as_mut()).is_pending());
let retry = group.try_work("key", || async { Ok::<&str, &str>("success") });
let mut retry = pin!(retry);
assert!(poll_once(retry.as_mut()).is_pending());
released.set(true);
assert_eq!(poll_once(first.as_mut()), Poll::Ready(Err("fail")));
assert_eq!(entry_count(&group), 1);
assert_eq!(poll_once(retry.as_mut()), Poll::Ready(Ok("success")));
assert_eq!(entry_count(&group), 0);
}