#![allow(clippy::unwrap_used, clippy::indexing_slicing)]
use surelock::{key::lock_scope, mutex::Mutex, set::LockSet};
#[test]
fn lockid_monotonicity() {
bolero::check!().with_type::<u8>().for_each(|&count| {
let n = (count as usize).min(64); let mutexes: Vec<Mutex<()>> = (0..n).map(|_| Mutex::new(())).collect();
for window in mutexes.windows(2) {
assert!(
window[0].id() < window[1].id(),
"LockId must be strictly monotonically increasing"
);
}
});
}
#[test]
fn lockset_sort_invariant_2tuple() {
bolero::check!()
.with_type::<(u32, u32, bool)>()
.for_each(|&(val_a, val_b, reverse)| {
let a: Mutex<u32> = Mutex::new(val_a);
let b: Mutex<u32> = Mutex::new(val_b);
let set = if reverse {
LockSet::new((&b, &a))
} else {
LockSet::new((&a, &b))
};
lock_scope(|key| {
let ((g1, g2), _key) = key.lock(&set);
if reverse {
assert_eq!(*g1, val_b, "first guard should match b");
assert_eq!(*g2, val_a, "second guard should match a");
} else {
assert_eq!(*g1, val_a, "first guard should match a");
assert_eq!(*g2, val_b, "second guard should match b");
}
});
});
}
#[test]
fn lockset_slice_preserves_values() {
bolero::check!().with_type::<u8>().for_each(|&count| {
let n = (count as usize).clamp(1, 16);
let mutexes: Vec<Mutex<u64>> = (0..n).map(|i| Mutex::new(i as u64)).collect();
let expected_sum: u64 = (0..n as u64).sum();
let set = LockSet::new(mutexes.as_slice());
lock_scope(|key| {
let (guards, _key) = key.lock(&set);
let actual_sum: u64 = guards.iter().map(|g| **g).sum();
assert_eq!(
actual_sum, expected_sum,
"sum of locked values must match sum of original values"
);
});
});
}