use simple_someip::buffer_pool::BufferPool;
use simple_someip::transport::{BufferProvider, StaticBufferProvider};
static POOL_EXHAUST: BufferPool<2, 16> = BufferPool::new();
static POOL_RETURN: BufferPool<2, 16> = BufferPool::new();
#[test]
fn claim_returns_distinct_zeroed_slices_until_exhausted() {
let mut a = POOL_EXHAUST.claim().expect("slot 0");
let b = POOL_EXHAUST.claim().expect("slot 1");
assert_eq!(a.len(), 16);
assert_eq!(&*b, &[0u8; 16]); a[0] = 0xAB; assert_eq!(a[0], 0xAB);
assert!(
POOL_EXHAUST.claim().is_none(),
"pool of 2 must refuse a 3rd claim"
);
}
#[test]
fn dropping_a_lease_returns_its_slot() {
let a = POOL_RETURN.claim().expect("slot");
drop(a);
assert!(
POOL_RETURN.claim().is_some(),
"slot must be reusable after the lease drops"
);
}
static PROV_POOL: BufferPool<2, 16> = BufferPool::new();
#[test]
fn static_provider_claims_through_a_shared_pool() {
let prov = StaticBufferProvider(&PROV_POOL);
let _a = prov.claim().expect("first");
let _b = prov.claim().expect("second");
assert!(
prov.claim().is_none(),
"provider exposes the pool's capacity"
);
}
#[test]
fn concurrent_claim_hands_out_distinct_non_aliasing_slots() {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Barrier, Mutex};
const N: usize = 8;
static POOL: BufferPool<N, 16> = BufferPool::new();
let success = Arc::new(AtomicUsize::new(0));
let barrier = Arc::new(Barrier::new(N));
let leases = Arc::new(Mutex::new(std::vec::Vec::new()));
let mut handles = std::vec::Vec::new();
for tag in 0..N {
let success = Arc::clone(&success);
let barrier = Arc::clone(&barrier);
let leases = Arc::clone(&leases);
handles.push(std::thread::spawn(move || {
barrier.wait();
if let Some(mut lease) = POOL.claim() {
success.fetch_add(1, Ordering::SeqCst);
let stamp = u8::try_from(tag).unwrap();
lease[0] = stamp;
leases.lock().unwrap().push((stamp, lease));
}
}));
}
for h in handles {
h.join().unwrap();
}
assert_eq!(
success.load(Ordering::SeqCst),
N,
"all {N} concurrent claims should have succeeded against an {N}-slot pool",
);
let leases = leases.lock().unwrap();
assert_eq!(leases.len(), N, "every claim should have produced a lease");
for (stamp, lease) in leases.iter() {
assert_eq!(
lease[0], *stamp,
"lease slot aliased — its stamp byte was clobbered by another lease",
);
}
assert!(
POOL.claim().is_none(),
"an {N}-slot pool with {N} leases outstanding must refuse another claim",
);
}