use pretty_assertions::assert_eq;
use run_down::{RundownError, RundownGuard, RundownRef};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
#[test]
#[allow(clippy::drop_bounds)]
fn test_rundown_guard_implements_drop() {
fn is_droppable<T: Drop>() {}
is_droppable::<RundownGuard>();
assert!(std::mem::needs_drop::<RundownGuard>());
}
#[test]
fn test_acquisition_when_not_rundown() {
let rundown = RundownRef::new();
let result = rundown.try_acquire();
assert!(result.is_ok());
let _guard: RundownGuard = result.unwrap();
}
#[test]
fn test_acquisition_when_rundown() {
let rundown_ref = RundownRef::new();
rundown_ref.wait_for_rundown();
let result = rundown_ref.try_acquire();
assert_eq!(result.err(), Some(RundownError::RundownInProgress));
}
#[test]
fn test_multiple_successive_waits() {
let rundown_ref = RundownRef::new();
for _ in 0..10 {
rundown_ref.wait_for_rundown();
}
}
#[test]
fn test_re_init() {
let rundown_ref = RundownRef::new();
rundown_ref.wait_for_rundown();
rundown_ref.re_init();
rundown_ref.wait_for_rundown();
}
#[test]
#[should_panic]
fn test_re_init_panic_without_rundown() {
let rundown_ref = RundownRef::new();
rundown_ref.re_init();
}
#[test]
#[should_panic]
fn test_re_init_panic_on_ref() {
let rundown_ref = RundownRef::new();
let _guard = rundown_ref.try_acquire().unwrap();
rundown_ref.re_init();
}
#[test]
fn test_usage_with_concurrency() {
let mut children = vec![];
let rundown = Arc::new(RundownRef::new());
for _ in 0..20 {
let rundown_clone = Arc::clone(&rundown);
children.push(thread::spawn(move || {
if let Ok(_guard) = rundown_clone.try_acquire() {
thread::sleep(Duration::from_millis(10));
}
}));
}
rundown.wait_for_rundown();
for child in children {
let _ = child.join();
}
}