use crate::LimitedSingleWakerMultiPermit;
#[test]
fn test_basics()
{
let wpc = LimitedSingleWakerMultiPermit::new(2);
assert_eq!(wpc.avalible_permits(), Some(0));
assert!(wpc.add_permit() == Some(true));
assert_eq!(wpc.avalible_permits(), Some(1));
assert!(wpc.add_permit() == Some(true));
assert_eq!(wpc.avalible_permits(), Some(2));
assert!(wpc.remove_permit() == Some(true));
assert_eq!(wpc.avalible_permits(), Some(1));
assert!(wpc.remove_permit() == Some(true));
assert_eq!(wpc.avalible_permits(), Some(0));
wpc.close();
assert!(wpc.is_closed());
assert_eq!(wpc.avalible_permits(), None);
}
#[cfg(feature="tokio")]
mod tokio_tests
{
use std::{sync::Arc, time::Duration};
use futures::join;
use tokio::{task::JoinSet, time::{sleep, timeout}};
use crate::{LimitedSingleWakerMultiPermit, LimitedSingleWakerMultiPermitError, WakerPermitQueueClosedError};
#[tokio::test(flavor = "multi_thread", worker_threads = 3)]
async fn test_1()
{
let wpc = LimitedSingleWakerMultiPermit::new(2);
let arc_wpc = Arc::new(wpc);
let arc_wpc_task = arc_wpc.clone();
let t1 = tokio::spawn(async move
{
let ft = arc_wpc_task.decrement_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
});
let arc_wpc_task = arc_wpc.clone();
let t2 = tokio::spawn(async move
{
let ft = arc_wpc_task.decrement_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
});
assert_eq!(arc_wpc.add_permit(), Some(true));
assert_eq!(arc_wpc.add_permit(), Some(true));
let join_result = join!(t1, t2);
if let (Err(_err1), Err(_err2)) = join_result
{
assert!(false)
}
assert_eq!(arc_wpc.avalible_permits(), Some(0));
assert_eq!(arc_wpc.has_max_permits(), Some(false));
assert_eq!(arc_wpc.add_permit(), Some(true));
assert_eq!(arc_wpc.add_permit(), Some(true));
assert_eq!(arc_wpc.avalible_permits(), Some(2));
assert_eq!(arc_wpc.has_max_permits(), Some(true));
let arc_wpc_task = arc_wpc.clone();
let t3 = tokio::spawn(async move
{
let ft = arc_wpc_task.increment_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
});
let arc_wpc_task = arc_wpc.clone();
let t4 = tokio::spawn(async move
{
let ft = arc_wpc_task.increment_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
});
assert_eq!(arc_wpc.remove_permit(), Some(true));
assert_eq!(arc_wpc.remove_permit(), Some(true));
let join_result = join!(t3, t4);
if let (Err(_err3), Err(_err4)) = join_result
{
assert!(false)
}
assert_eq!(arc_wpc.avalible_permits(), Some(2));
assert_eq!(arc_wpc.has_max_permits(), Some(true));
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn waiting()
{
let wpc = LimitedSingleWakerMultiPermit::new(2);
let arc_wpc = Arc::new(wpc);
let arc_wpc_task = arc_wpc.clone();
let t1 = tokio::spawn(async move
{
let ft = arc_wpc_task.decrement_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
});
let ft = arc_wpc.increment_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
let ft = arc_wpc.increment_permits_or_wait();
let to_ft = timeout(Duration::from_secs(10), ft);
assert_eq!(to_ft.await, Ok(Ok(())));
let join_result = join!(t1);
if let (Err(_err1),) = join_result
{
assert!(false)
}
assert_eq!(arc_wpc.avalible_permits(), Some(1));
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn closing()
{
let wpc = LimitedSingleWakerMultiPermit::new(2);
let arc_wpc = Arc::new(wpc);
let arc_wpc_task = arc_wpc.clone();
let t1 = tokio::spawn(async move
{
let ft = arc_wpc_task.decrement_permits_or_wait();
let to_ft = timeout(Duration::from_mins(1), ft);
assert_eq!(to_ft.await, Ok(Err(LimitedSingleWakerMultiPermitError::Closed)));
});
assert_eq!(arc_wpc.avalible_permits(), Some(0));
arc_wpc.close();
match t1.await
{
Ok(_) => assert!(true),
Err(_) => assert!(false)
}
assert_eq!(arc_wpc.avalible_permits(), None);
}
}