use ranked_semaphore::RankedSemaphore;
use std::sync::Arc;
use std::time::Duration;
use tokio::time;
#[tokio::test]
async fn test_try_acquire_fast_path_no_contention() {
let sem = Arc::new(RankedSemaphore::new_fifo(1));
let permit = sem.try_acquire().unwrap();
assert_eq!(permit.num_permits(), 1);
assert!(sem.try_acquire().is_err(), "Should not be able to acquire more permits");
}
#[tokio::test]
async fn test_concurrent_add_permits_and_close() {
let sem = Arc::new(RankedSemaphore::new_fifo(0));
let sem_clone1 = sem.clone();
let sem_clone2 = sem.clone();
let sem_clone3 = sem.clone();
let acquire_task = tokio::spawn(async move {
sem_clone1.acquire_owned().await
});
time::sleep(Duration::from_millis(50)).await;
let add_permits_task = tokio::spawn(async move {
sem_clone2.add_permits(1);
});
let close_task = tokio::spawn(async move {
sem_clone3.close();
});
let _ = tokio::join!(add_permits_task, close_task);
let result = acquire_task.await.unwrap();
assert!(result.is_err(), "Acquire should fail when the semaphore is closed");
}
#[tokio::test]
async fn test_acquire_future_dropped_from_wait_queue() {
let sem = Arc::new(RankedSemaphore::new_fifo(0));
let sem_clone = sem.clone();
let acquire_task = tokio::spawn(async move {
sem_clone.acquire_owned().await
});
time::sleep(Duration::from_millis(50)).await;
acquire_task.abort();
time::sleep(Duration::from_millis(10)).await;
sem.add_permits(1);
let permit = sem.try_acquire().expect("Should be able to acquire a permit");
assert_eq!(permit.num_permits(), 1);
}
#[test]
#[should_panic(expected = "would overflow MAX_PERMITS")]
fn test_add_permits_overflow_panic() {
let sem = RankedSemaphore::new_fifo(RankedSemaphore::MAX_PERMITS);
sem.add_permits(1); }