use crate::atomic::AtomicRingBuf;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize};
use std::sync::atomic::{AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize};
use std::sync::{Arc, Barrier};
use std::thread;
#[test]
fn test_push_pop_alternating_pattern() {
let buf: AtomicRingBuf<AtomicU64, 32, true> = AtomicRingBuf::new(4);
for i in 0..100 {
buf.push(i, Ordering::Relaxed);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), i);
assert!(buf.is_empty());
}
}
#[test]
fn test_push_pop_stress_wrapping() {
let buf: AtomicRingBuf<AtomicU64, 64, true> = AtomicRingBuf::new(8);
for cycle in 0..50 {
for i in 0..8 {
buf.push(cycle * 100 + i, Ordering::Relaxed);
}
for i in 0..4 {
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), cycle * 100 + i);
}
}
}
#[test]
fn test_overwrite_mode_exact_capacity() {
let buf: AtomicRingBuf<AtomicU64, 32, true> = AtomicRingBuf::new(4);
for i in 0..4 {
assert_eq!(buf.push(i, Ordering::Relaxed), None);
}
assert!(buf.is_full());
for i in 4..20 {
let overwritten = buf.push(i, Ordering::Relaxed);
assert_eq!(overwritten, Some(i - 4));
assert_eq!(buf.len(), 4);
assert!(buf.is_full());
}
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 16);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 17);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 18);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 19);
}
#[test]
fn test_non_overwrite_mode_exactly_full() {
let buf: AtomicRingBuf<AtomicU64, 32, false> = AtomicRingBuf::new(8);
for i in 0..8 {
assert!(buf.push(i, Ordering::Relaxed).is_ok());
}
assert!(buf.is_full());
assert_eq!(buf.len(), 8);
assert_eq!(buf.push(99, Ordering::Relaxed), Err(99));
assert_eq!(buf.len(), 8);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 0);
assert!(!buf.is_full());
assert!(buf.push(99, Ordering::Relaxed).is_ok());
for i in 1..8 {
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), i);
}
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 99);
}
#[test]
fn test_pop_until_empty_with_refill() {
let buf: AtomicRingBuf<AtomicU64, 32, true> = AtomicRingBuf::new(16);
for round in 0..10 {
for i in 0..16 {
buf.push(round * 100 + i, Ordering::Relaxed);
}
for i in 0..16 {
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), round * 100 + i);
}
assert!(buf.is_empty());
assert_eq!(buf.len(), 0);
}
}
#[test]
fn test_peek_consistency_during_operations() {
let buf: AtomicRingBuf<AtomicU64, 32, true> = AtomicRingBuf::new(8);
assert_eq!(buf.peek(Ordering::Relaxed), None);
buf.push(10, Ordering::Relaxed);
assert_eq!(buf.peek(Ordering::Relaxed), Some(10));
assert_eq!(buf.len(), 1);
buf.push(20, Ordering::Relaxed);
buf.push(30, Ordering::Relaxed);
assert_eq!(buf.peek(Ordering::Relaxed), Some(10));
buf.pop(Ordering::Relaxed).unwrap();
assert_eq!(buf.peek(Ordering::Relaxed), Some(20));
buf.pop(Ordering::Relaxed).unwrap();
assert_eq!(buf.peek(Ordering::Relaxed), Some(30));
buf.pop(Ordering::Relaxed).unwrap();
assert_eq!(buf.peek(Ordering::Relaxed), None);
}
#[test]
fn test_clear_with_various_states() {
let buf: AtomicRingBuf<AtomicU64, 32, true> = AtomicRingBuf::new(8);
buf.clear();
assert!(buf.is_empty());
buf.push(1, Ordering::Relaxed);
buf.push(2, Ordering::Relaxed);
buf.push(3, Ordering::Relaxed);
buf.clear();
assert!(buf.is_empty());
for i in 0..8 {
buf.push(i, Ordering::Relaxed);
}
assert!(buf.is_full());
buf.clear();
assert!(buf.is_empty());
buf.push(100, Ordering::Relaxed);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 100);
}
#[test]
fn test_read_all_various_sizes() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values.len(), 0);
for i in 0..5 {
buf.push(i * 10, Ordering::Relaxed);
}
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values, vec![0, 10, 20, 30, 40]);
assert_eq!(buf.len(), 5);
buf.clear();
for i in 0..8 {
buf.push(i, Ordering::Relaxed);
}
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values, vec![0, 1, 2, 3, 4, 5, 6, 7]);
}
#[test]
fn test_read_all_after_wrapping() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
for i in 0..15 {
buf.push(i, Ordering::Relaxed);
}
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values, vec![7, 8, 9, 10, 11, 12, 13, 14]);
}
#[test]
fn test_iter_basic_iteration() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
for i in 0..5 {
buf.push(i * 100, Ordering::Relaxed);
}
let values: Vec<u64> = buf
.iter()
.map(|atom| atom.load(Ordering::Acquire))
.collect();
assert_eq!(values, vec![0, 100, 200, 300, 400]);
}
#[test]
fn test_iter_with_wrapped_buffer() {
let buf: AtomicRingBuf<AtomicU64, 64, true> = AtomicRingBuf::new(8);
for i in 0..15 {
buf.push(i, Ordering::Relaxed);
}
let values: Vec<u64> = buf
.iter()
.map(|atom| atom.load(Ordering::Acquire))
.collect();
assert_eq!(values, vec![7, 8, 9, 10, 11, 12, 13, 14]);
}
#[test]
fn test_iter_size_hints() {
let buf: AtomicRingBuf<AtomicU64, 64, true> = AtomicRingBuf::new(16);
for i in 0..8 {
buf.push(i, Ordering::Relaxed);
}
let mut iter = buf.iter();
assert_eq!(iter.len(), 8);
iter.next();
assert_eq!(iter.len(), 7);
iter.next();
iter.next();
assert_eq!(iter.len(), 5);
}
#[test]
fn test_iter_chaining_and_filtering() {
let buf: AtomicRingBuf<AtomicU64, 64, true> = AtomicRingBuf::new(16);
for i in 0..10 {
buf.push(i, Ordering::Relaxed);
}
let result: Vec<u64> = buf
.iter()
.map(|atom| atom.load(Ordering::Acquire))
.filter(|&x| x % 2 == 0)
.map(|x| x * 10)
.collect();
assert_eq!(result, vec![0, 20, 40, 60, 80]);
}
#[test]
fn test_memory_ordering_relaxed() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(42, Ordering::Relaxed);
buf.push(99, Ordering::Relaxed);
assert_eq!(buf.pop(Ordering::Relaxed), Some(42));
assert_eq!(buf.pop(Ordering::Relaxed), Some(99));
}
#[test]
fn test_memory_ordering_acquire_release() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(100, Ordering::Release);
buf.push(200, Ordering::Release);
assert_eq!(buf.peek(Ordering::Acquire), Some(100));
assert_eq!(buf.pop(Ordering::Acquire), Some(100));
assert_eq!(buf.pop(Ordering::Acquire), Some(200));
}
#[test]
fn test_memory_ordering_seq_cst() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(42, Ordering::SeqCst);
let value = buf.pop(Ordering::SeqCst);
assert_eq!(value, Some(42));
}
#[test]
fn test_get_unchecked_direct_access() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(10, Ordering::Relaxed);
buf.push(20, Ordering::Relaxed);
buf.push(30, Ordering::Relaxed);
unsafe {
let elem0 = buf.get_unchecked(0);
assert_eq!(elem0.load(Ordering::Acquire), 10);
let elem1 = buf.get_unchecked(1);
assert_eq!(elem1.load(Ordering::Acquire), 20);
let elem2 = buf.get_unchecked(2);
assert_eq!(elem2.load(Ordering::Acquire), 30);
}
}
#[test]
fn test_fetch_add_at_basic() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(10, Ordering::Relaxed);
buf.push(20, Ordering::Relaxed);
buf.push(30, Ordering::Relaxed);
let old = unsafe { buf.fetch_add_at(0, 5, Ordering::Relaxed) };
assert_eq!(old, 10);
assert_eq!(buf.peek(Ordering::Acquire).unwrap(), 15);
let old = unsafe { buf.fetch_add_at(1, 100, Ordering::Relaxed) };
assert_eq!(old, 20);
let old = unsafe { buf.fetch_add_at(2, 7, Ordering::Relaxed) };
assert_eq!(old, 30);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 15);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 120);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 37);
}
#[test]
fn test_fetch_sub_at_basic() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(100, Ordering::Relaxed);
buf.push(200, Ordering::Relaxed);
buf.push(50, Ordering::Relaxed);
let old = unsafe { buf.fetch_sub_at(0, 10, Ordering::Relaxed) };
assert_eq!(old, 100);
assert_eq!(buf.peek(Ordering::Acquire).unwrap(), 90);
let old = unsafe { buf.fetch_sub_at(1, 150, Ordering::Relaxed) };
assert_eq!(old, 200);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 90);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 50);
}
#[test]
fn test_fetch_add_sub_alternating() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
buf.push(100, Ordering::Relaxed);
for _ in 0..10 {
unsafe { buf.fetch_add_at(0, 10, Ordering::Relaxed) };
unsafe { buf.fetch_sub_at(0, 5, Ordering::Relaxed) };
}
assert_eq!(buf.peek(Ordering::Acquire).unwrap(), 150);
}
#[test]
fn test_fetch_operations_with_signed_types() {
let buf: AtomicRingBuf<AtomicI64, 32> = AtomicRingBuf::new(8);
buf.push(50, Ordering::Relaxed);
buf.push(-30, Ordering::Relaxed);
let old = unsafe { buf.fetch_add_at(0, 20, Ordering::Relaxed) };
assert_eq!(old, 50);
assert_eq!(buf.peek(Ordering::Acquire).unwrap(), 70);
let old = unsafe { buf.fetch_sub_at(1, -10, Ordering::Relaxed) };
assert_eq!(old, -30);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 70);
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), -20);
}
#[test]
fn test_fetch_operations_multiple_elements() {
let buf: AtomicRingBuf<AtomicU32, 64> = AtomicRingBuf::new(16);
for i in 0..8 {
buf.push(i * 10, Ordering::Relaxed);
}
for i in (0..8).step_by(2) {
unsafe { buf.fetch_add_at(i, 1000, Ordering::Relaxed) };
}
for i in (1..8).step_by(2) {
unsafe { buf.fetch_sub_at(i, 5, Ordering::Relaxed) };
}
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values[0], 1000); assert_eq!(values[1], 5); assert_eq!(values[2], 1020); assert_eq!(values[3], 25); }
#[test]
fn test_atomic_u8_operations() {
let buf: AtomicRingBuf<AtomicU8, 32> = AtomicRingBuf::new(8);
buf.push(100u8, Ordering::Relaxed);
buf.push(200u8, Ordering::Relaxed);
assert_eq!(buf.pop(Ordering::Relaxed), Some(100u8));
assert_eq!(buf.pop(Ordering::Relaxed), Some(200u8));
}
#[test]
fn test_atomic_u16_operations() {
let buf: AtomicRingBuf<AtomicU16, 32> = AtomicRingBuf::new(8);
buf.push(1000u16, Ordering::Relaxed);
buf.push(2000u16, Ordering::Relaxed);
let old = unsafe { buf.fetch_add_at(0, 500, Ordering::Relaxed) };
assert_eq!(old, 1000);
assert_eq!(buf.pop(Ordering::Relaxed), Some(1500u16));
}
#[test]
fn test_atomic_usize_operations() {
let buf: AtomicRingBuf<AtomicUsize, 32> = AtomicRingBuf::new(8);
buf.push(1000usize, Ordering::Relaxed);
buf.push(2000usize, Ordering::Relaxed);
assert_eq!(buf.len(), 2);
assert_eq!(buf.pop(Ordering::Relaxed), Some(1000usize));
}
#[test]
fn test_concurrent_push_overwrite_mode() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 256, true>::new(64));
let mut handles = vec![];
for thread_id in 0..8 {
let buf_clone = Arc::clone(&buf);
let handle = thread::spawn(move || {
for i in 0..50 {
let value = (thread_id as u64) * 1000 + i;
buf_clone.push(value, Ordering::SeqCst);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(buf.len(), 64);
}
#[test]
fn test_concurrent_push_pop() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 128, true>::new(64));
let mut handles = vec![];
for thread_id in 0..4 {
let buf_clone = Arc::clone(&buf);
let handle = thread::spawn(move || {
for i in 0..100 {
buf_clone.push((thread_id as u64) * 1000 + i, Ordering::Release);
thread::sleep(std::time::Duration::from_micros(1));
}
});
handles.push(handle);
}
let popped_count = Arc::new(AtomicUsize::new(0));
for _ in 0..4 {
let buf_clone = Arc::clone(&buf);
let count_clone = Arc::clone(&popped_count);
let handle = thread::spawn(move || {
for _ in 0..50 {
if buf_clone.pop(Ordering::Acquire).is_some() {
count_clone.fetch_add(1, Ordering::Relaxed);
}
thread::sleep(std::time::Duration::from_micros(1));
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let total_popped = popped_count.load(Ordering::Acquire);
let remaining = buf.len();
assert!(total_popped > 0);
assert!(remaining <= 64);
}
#[test]
fn test_concurrent_non_overwrite_mode() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 128, false>::new(64));
let mut handles = vec![];
let success_count = Arc::new(AtomicUsize::new(0));
for thread_id in 0..8 {
let buf_clone = Arc::clone(&buf);
let count_clone = Arc::clone(&success_count);
let handle = thread::spawn(move || {
let mut local_success = 0;
for i in 0..50 {
let value = (thread_id as u64) * 1000 + i;
if buf_clone.push(value, Ordering::SeqCst).is_ok() {
local_success += 1;
}
}
count_clone.fetch_add(local_success, Ordering::Relaxed);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let success = success_count.load(Ordering::Acquire);
assert_eq!(buf.len(), success.min(64));
assert!(success <= 64);
}
#[test]
fn test_concurrent_read_all() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 128, true>::new(64));
let mut handles = vec![];
let buf_clone = Arc::clone(&buf);
let writer = thread::spawn(move || {
for i in 0..200 {
buf_clone.push(i, Ordering::Release);
thread::sleep(std::time::Duration::from_micros(10));
}
});
for _ in 0..4 {
let buf_clone = Arc::clone(&buf);
let handle = thread::spawn(move || {
for _ in 0..50 {
let _values = buf_clone.read_all(Ordering::Acquire);
thread::sleep(std::time::Duration::from_micros(20));
}
});
handles.push(handle);
}
writer.join().unwrap();
for handle in handles {
handle.join().unwrap();
}
assert_eq!(buf.len(), 64);
}
#[test]
fn test_concurrent_fetch_operations() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 64, true>::new(8));
for _ in 0..8 {
buf.push(0, Ordering::Relaxed);
}
let mut handles = vec![];
for _ in 0..4 {
let buf_clone = Arc::clone(&buf);
let handle = thread::spawn(move || {
for _ in 0..100 {
for offset in 0..8 {
unsafe {
buf_clone.fetch_add_at(offset, 1, Ordering::SeqCst);
}
}
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let values = buf.read_all(Ordering::Acquire);
for value in values {
assert_eq!(value, 400);
}
}
#[test]
fn test_concurrent_iterator_access() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 128, true>::new(32));
for i in 0..32 {
buf.push(i * 10, Ordering::Relaxed);
}
let mut handles = vec![];
for _ in 0..8 {
let buf_clone = Arc::clone(&buf);
let handle = thread::spawn(move || {
for _ in 0..100 {
let sum: u64 = buf_clone
.iter()
.map(|atom| atom.load(Ordering::Acquire))
.sum();
assert!(sum > 0);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
#[test]
fn test_barrier_synchronized_access() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 128, true>::new(64));
let barrier = Arc::new(Barrier::new(4));
let mut handles = vec![];
for thread_id in 0..4 {
let buf_clone = Arc::clone(&buf);
let barrier_clone = Arc::clone(&barrier);
let handle = thread::spawn(move || {
barrier_clone.wait();
for i in 0..50 {
buf_clone.push((thread_id as u64) * 1000 + i, Ordering::SeqCst);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(buf.len(), 64);
}
#[test]
fn test_stress_alternating_push_pop_multithread() {
let buf = Arc::new(AtomicRingBuf::<AtomicU64, 128, true>::new(32));
let mut handles = vec![];
for thread_id in 0..4 {
let buf_clone = Arc::clone(&buf);
let handle = thread::spawn(move || {
for i in 0..200 {
buf_clone.push((thread_id as u64) * 10000 + i, Ordering::Release);
if i % 3 == 0 {
buf_clone.pop(Ordering::Acquire);
}
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert!(buf.len() <= 32);
}
#[test]
fn test_capacity_power_of_two_rounding() {
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(1);
assert_eq!(buf.capacity(), 1);
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(2);
assert_eq!(buf.capacity(), 2);
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(3);
assert_eq!(buf.capacity(), 4);
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(7);
assert_eq!(buf.capacity(), 8);
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(15);
assert_eq!(buf.capacity(), 16);
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(100);
assert_eq!(buf.capacity(), 128);
}
#[test]
fn test_minimum_capacity() {
let buf: AtomicRingBuf<AtomicU64, 32, true> = AtomicRingBuf::new(1);
assert_eq!(buf.capacity(), 1);
buf.push(42, Ordering::Relaxed);
assert!(buf.is_full());
assert_eq!(buf.len(), 1);
assert_eq!(buf.push(99, Ordering::Relaxed), Some(42));
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 99);
}
#[test]
fn test_very_large_capacity() {
let buf: AtomicRingBuf<AtomicU64, 128> = AtomicRingBuf::new(8192);
assert_eq!(buf.capacity(), 8192);
let buf: AtomicRingBuf<AtomicU8, 128> = AtomicRingBuf::new(65536);
assert_eq!(buf.capacity(), 65536);
}
#[test]
fn test_wrapping_index_overflow() {
let buf: AtomicRingBuf<AtomicU64, 64, true> = AtomicRingBuf::new(8);
for i in 0..10000u64 {
buf.push(i, Ordering::Relaxed);
if i % 2 == 0 {
buf.pop(Ordering::Relaxed);
}
}
assert!(buf.len() <= 8);
}
#[test]
fn test_peek_does_not_modify_buffer() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
for i in 0..5 {
buf.push(i, Ordering::Relaxed);
}
let initial_len = buf.len();
for _ in 0..10 {
assert_eq!(buf.peek(Ordering::Acquire), Some(0));
assert_eq!(buf.len(), initial_len);
}
assert_eq!(buf.pop(Ordering::Relaxed).unwrap(), 0);
assert_eq!(buf.len(), initial_len - 1);
}
#[test]
fn test_read_all_does_not_modify_buffer() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
for i in 0..5 {
buf.push(i * 10, Ordering::Relaxed);
}
let initial_len = buf.len();
for _ in 0..10 {
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values.len(), initial_len);
assert_eq!(buf.len(), initial_len);
}
}
#[test]
fn test_multiple_clear_operations() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
for round in 0..5 {
for i in 0..8 {
buf.push(round * 100 + i, Ordering::Relaxed);
}
assert_eq!(buf.len(), 8);
buf.clear();
assert!(buf.is_empty());
assert_eq!(buf.len(), 0);
}
}
#[test]
fn test_atomic_bool_comprehensive() {
let buf: AtomicRingBuf<AtomicBool, 32, true> = AtomicRingBuf::new(8);
for i in 0..16 {
buf.push(i % 2 == 0, Ordering::Relaxed);
}
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values.len(), 8);
for (idx, &val) in values.iter().enumerate() {
assert_eq!(val, idx % 2 == 0);
}
}
#[test]
fn test_different_atomic_types_mixed() {
let buf_i8: AtomicRingBuf<AtomicI8, 32> = AtomicRingBuf::new(4);
buf_i8.push(-10i8, Ordering::Relaxed);
buf_i8.push(20i8, Ordering::Relaxed);
assert_eq!(buf_i8.pop(Ordering::Relaxed), Some(-10i8));
let buf_i16: AtomicRingBuf<AtomicI16, 32> = AtomicRingBuf::new(4);
buf_i16.push(-1000i16, Ordering::Relaxed);
buf_i16.push(2000i16, Ordering::Relaxed);
assert_eq!(buf_i16.pop(Ordering::Relaxed), Some(-1000i16));
let buf_i32: AtomicRingBuf<AtomicI32, 32> = AtomicRingBuf::new(4);
buf_i32.push(-100000i32, Ordering::Relaxed);
buf_i32.push(200000i32, Ordering::Relaxed);
assert_eq!(buf_i32.pop(Ordering::Relaxed), Some(-100000i32));
let buf_isize: AtomicRingBuf<AtomicIsize, 32> = AtomicRingBuf::new(4);
buf_isize.push(-500isize, Ordering::Relaxed);
buf_isize.push(600isize, Ordering::Relaxed);
assert_eq!(buf_isize.pop(Ordering::Relaxed), Some(-500isize));
}
#[test]
fn test_stack_allocation_threshold() {
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(32);
assert_eq!(buf.capacity(), 32);
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(128);
assert_eq!(buf.capacity(), 128);
let buf: AtomicRingBuf<AtomicU64, 256> = AtomicRingBuf::new(200);
assert_eq!(buf.capacity(), 256);
}
#[test]
fn test_empty_buffer_operations() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
assert!(buf.is_empty());
assert_eq!(buf.len(), 0);
assert_eq!(buf.pop(Ordering::Relaxed), None);
assert_eq!(buf.peek(Ordering::Relaxed), None);
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values.len(), 0);
let iter = buf.iter();
assert_eq!(iter.len(), 0);
}
#[test]
fn test_full_buffer_operations() {
let buf: AtomicRingBuf<AtomicU64, 32, false> = AtomicRingBuf::new(4);
for i in 0..4 {
assert!(buf.push(i, Ordering::Relaxed).is_ok());
}
assert!(buf.is_full());
assert_eq!(buf.len(), 4);
assert_eq!(buf.push(99, Ordering::Relaxed), Err(99));
assert_eq!(buf.len(), 4);
assert_eq!(buf.peek(Ordering::Acquire), Some(0));
let values = buf.read_all(Ordering::Acquire);
assert_eq!(values.len(), 4);
}
#[test]
fn test_iterator_empty_buffer() {
let buf: AtomicRingBuf<AtomicU64, 32> = AtomicRingBuf::new(8);
let mut iter = buf.iter();
assert!(iter.next().is_none());
assert_eq!(iter.len(), 0);
}
#[test]
fn test_sequential_ordering_consistency() {
let buf: AtomicRingBuf<AtomicU64, 64> = AtomicRingBuf::new(16);
for i in 0..100 {
buf.push(i, Ordering::Release);
}
let start = 100 - buf.capacity() as u64;
for expected in start..100 {
assert_eq!(buf.pop(Ordering::Acquire).unwrap(), expected);
}
assert!(buf.is_empty());
}