use crate::SwmrCell;
use std::prelude::v1::*;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
use std::format;
use std::vec;
#[test]
fn test_guard_lifetime_constraint() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let guard = local.pin();
assert_eq!(*guard, 42);
}
#[test]
fn test_multiple_guards_simultaneously_active() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let guard1 = local.pin();
let guard2 = local.pin();
assert_eq!(*guard1, 42);
assert_eq!(*guard2, 42);
}
#[test]
fn test_guard_nested_scopes() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
{
let guard1 = local.pin();
assert_eq!(*guard1, 42);
{
let guard2 = local.pin();
assert_eq!(*guard2, 42);
}
let guard1_again = local.pin();
assert_eq!(*guard1_again, 42);
}
}
#[test]
fn test_reader_isolation_across_threads() {
let mut cell = SwmrCell::new(0i32);
let mut handles = vec![];
for _ in 0..3 {
let local = cell.local_reader();
handles.push(thread::spawn(move || {
let guard = local.pin();
assert!(*guard >= 0);
}));
}
cell.store(1);
for h in handles {
h.join().unwrap();
}
}
#[test]
fn test_writer_uniqueness() {
}
#[test]
fn test_garbage_collection_memory_safety() {
let mut cell = SwmrCell::new(vec![1, 2, 3]);
let local = cell.local_reader();
cell.store(vec![4, 5, 6]);
cell.store(vec![7, 8, 9]);
let _guard = local.pin();
cell.collect();
let _guard2 = local.pin();
}
#[test]
fn test_swmr_drop_implementation() {
{
let _c = SwmrCell::new(String::from("test"));
}
}
#[test]
fn test_multiple_swmr_independence() {
let c1 = SwmrCell::new(10i32);
let c2 = SwmrCell::new(20i32);
let c3 = SwmrCell::new(30i32);
let r1 = c1.local_reader();
let r2 = c2.local_reader();
let r3 = c3.local_reader();
let g1 = r1.pin();
let g2 = r2.pin();
let g3 = r3.pin();
assert_eq!(*g1, 10);
assert_eq!(*g2, 20);
assert_eq!(*g3, 30);
}
#[test]
fn test_reader_creation_safety() {
let cell = SwmrCell::new(0i32);
let r1 = cell.local_reader();
let r2 = cell.local_reader();
let r3 = cell.local_reader();
let _g1 = r1.pin();
let _g2 = r2.pin();
let _g3 = r3.pin();
}
#[test]
fn test_epoch_advancement_correctness() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(*guard, 0);
}
cell.store(1);
{
let guard = local.pin();
assert_eq!(*guard, 1);
}
}
#[test]
fn test_concurrent_read_consistency() {
let cell = SwmrCell::new(42i32);
let check = Arc::new(AtomicUsize::new(0));
let mut handles = vec![];
for _ in 0..10 {
let local = cell.local_reader();
let c = check.clone();
handles.push(thread::spawn(move || {
for _ in 0..100 {
let guard = local.pin();
if *guard == 42 {
c.fetch_add(1, Ordering::Relaxed);
}
}
}));
}
for h in handles {
h.join().unwrap();
}
assert_eq!(check.load(Ordering::Relaxed), 1000);
}
#[test]
fn test_reader_exit_cleanup() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
let t = thread::spawn(move || {
let _guard = local.pin();
});
t.join().unwrap();
cell.collect();
}
#[test]
fn test_large_garbage_safe_reclamation() {
let mut cell = SwmrCell::new(0i32);
for i in 0..1000 {
cell.store(i);
}
cell.collect();
}
#[test]
fn test_complex_type_lifetime_management() {
#[derive(Debug)]
struct ComplexData {
id: usize,
values: Vec<i32>,
name: String,
}
let data = ComplexData {
id: 1,
values: vec![1, 2, 3, 4, 5],
name: String::from("test"),
};
let cell = SwmrCell::new(data);
let local = cell.local_reader();
let guard = local.pin();
assert_eq!(guard.id, 1);
assert_eq!(guard.values.len(), 5);
assert_eq!(guard.name, "test");
}
#[test]
fn test_data_visibility_across_epochs() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
let g1 = local.pin();
assert_eq!(*g1, 0);
cell.store(1);
let g2 = local.pin();
assert_eq!(*g2, 1);
assert_eq!(*g1, 0);
let g1_new = local.pin();
assert_eq!(*g1_new, 1);
}
#[test]
fn test_rapid_reader_switching() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
for _ in 0..100 {
let guard = local.pin();
assert_eq!(*guard, 42);
drop(guard);
let guard = local.pin();
assert_eq!(*guard, 42);
}
}
#[test]
fn test_writer_garbage_management() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
{
let _guard = local.pin();
for i in 0..50 {
cell.store(i);
}
}
cell.collect();
}
#[test]
fn test_multiple_readers_garbage_protection() {
let mut cell = SwmrCell::new(0i32);
let r1 = cell.local_reader();
let r2 = cell.local_reader();
let r3 = cell.local_reader();
let _g1 = r1.pin();
let _g2 = r2.pin();
let _g3 = r3.pin();
for i in 0..100 {
cell.store(i);
}
cell.collect();
}
#[test]
fn test_complete_lifecycle_scenario() {
let mut cell = SwmrCell::new(String::from("initial"));
let mut readers = vec![];
for _ in 0..5 {
readers.push(cell.local_reader());
}
for round in 0..3 {
let guards: Vec<_> = readers
.iter()
.map(|r: &crate::LocalReader<String>| r.pin())
.collect();
for guard in &guards {
assert!(!(*guard).is_empty());
}
cell.store(format!("round_{}", round));
for i in 0..50 {
cell.store(format!("garbage_{}", i));
}
cell.collect();
}
}
#[test]
fn test_get_lifetime_bound_to_cell() {
let cell = SwmrCell::new(42i32);
let value_ref = cell.get();
assert_eq!(*value_ref, 42);
}
#[test]
fn test_update_preserves_previous() {
let mut cell = SwmrCell::new(1i32);
cell.update(|v| v + 1);
assert_eq!(cell.previous(), Some(&1));
cell.update(|v| v * 2);
assert_eq!(cell.previous(), Some(&2));
}
#[test]
fn test_version_consistency_lifecycle() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
for i in 0..10 {
assert_eq!(cell.version(), i);
assert_eq!(local.version(), i);
let guard = local.pin();
assert_eq!(guard.version(), i);
drop(guard);
cell.store(i as i32 + 1);
}
}
#[test]
fn test_is_pinned_lifecycle_with_clone() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
assert!(!local.is_pinned());
let guard1 = local.pin();
assert!(local.is_pinned());
let guard2 = guard1.clone();
assert!(local.is_pinned());
drop(guard1);
assert!(local.is_pinned());
drop(guard2);
assert!(!local.is_pinned());
}
#[test]
fn test_pin_guard_version_preserved() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
let guard = local.pin();
let initial_version = guard.version();
for i in 1..=10 {
cell.store(i);
}
assert_eq!(guard.version(), initial_version);
assert_eq!(*guard, 0);
}
#[test]
fn test_default_trait_lifecycle() {
let mut cell: SwmrCell<Vec<i32>> = SwmrCell::default();
let local = cell.local_reader();
assert!(cell.get().is_empty());
assert_eq!(cell.version(), 0);
cell.update(|v: &Vec<i32>| {
let mut new_v = v.clone();
new_v.push(1);
new_v
});
assert_eq!(*cell.get(), vec![1]);
assert_eq!(cell.version(), 1);
let guard = local.pin();
assert_eq!(*guard, vec![1]);
}