blob: db7af2ca651f9233a32946c87113909ee2441ff2 [file] [log] [blame]
//! Let it torture the implementation with some randomized operations.
extern crate arc_swap;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate model;
#[macro_use]
extern crate proptest;
use std::mem;
use std::sync::Arc;
use arc_swap::{ArcSwap, Lease};
#[test]
fn ops() {
model! {
Model => let mut u = 0usize,
Implementation => let a: ArcSwap<usize> = ArcSwap::from(Arc::new(0usize)),
Store(usize)(v in any::<usize>()) => {
u = v;
a.store(Arc::new(v));
},
Load(())(() in any::<()>()) => {
assert_eq!(u, *a.load());
},
Peek(())(() in any::<()>()) => {
assert_eq!(u, *a.peek());
},
PeekSignalSafe(())(() in any::<()>()) => {
assert_eq!(u, *a.peek_signal_safe());
},
Lease(())(() in any::<()>()) => {
assert_eq!(u, *a.lease());
},
Swap(usize)(v in any::<usize>()) => {
let expected = u;
u = v;
let actual = a.swap(Arc::new(v));
assert_eq!(expected, *actual);
}
}
}
const LIMIT: usize = 5;
lazy_static! {
static ref ARCS: Vec<Arc<usize>> = (0..LIMIT).map(|v| Arc::new(v)).collect();
}
#[test]
fn selection() {
model! {
Model => let mut bare = Arc::clone(&ARCS[0]),
Implementation => let a: ArcSwap<usize> = ArcSwap::from(Arc::clone(&ARCS[0])),
Swap(usize)(idx in 0..LIMIT) => {
let mut expected = Arc::clone(&ARCS[idx]);
mem::swap(&mut expected, &mut bare);
let actual = a.swap(Arc::clone(&ARCS[idx]));
assert!(Arc::ptr_eq(&expected, &actual));
},
Cas((usize, usize))((current, new) in (0..LIMIT, 0..LIMIT)) => {
let expected = Arc::clone(&bare);
if bare == ARCS[current] {
bare = Arc::clone(&ARCS[new]);
}
let actual = a.compare_and_swap(&ARCS[current], Arc::clone(&ARCS[new]));
assert!(Arc::ptr_eq(&expected, &Lease::upgrade(&actual)));
}
}
}
#[test]
fn linearize() {
use model::Shared;
linearizable! {
Implementation => let a = Shared::new(ArcSwap::from(Arc::clone(&ARCS[0]))),
Store(usize)(idx in 0..LIMIT) -> () {
a.store(Arc::clone(&ARCS[idx]));
},
Peek(())(() in any::<()>()) -> usize {
*a.peek()
},
Cas((usize, usize))((current, new) in (0..LIMIT, 0..LIMIT)) -> usize {
let new = Arc::clone(&ARCS[new]);
*a.compare_and_swap(&ARCS[current], new)
}
}
}