use crate::inner::Inner;
use std::sync::Arc;
use std::thread;
#[test]
fn new_assigns_starting_weight() {
let inner = Inner::new(13, 5, 0);
assert_eq!(inner.strong_weight(), 5);
}
#[test]
fn weight_can_be_added() {
let inner = Inner::new(13, 5, 0);
inner.add_strong_weight(17);
assert_eq!(inner.strong_weight(), 22);
}
#[test]
fn weight_can_be_dropped() {
let inner = Inner::new(13, 5, 0);
inner.drop_strong_weight(2);
assert_eq!(inner.strong_weight(), 3);
}
#[test]
fn concurrent_weight_modifications_are_atomic() {
let inner = Arc::new(Inner::new(42, 0, 0));
let num_threads = 100;
let ops_per_thread = 1000;
let weight_per_op: usize = 10;
let mut handles = vec![];
for _ in 0..num_threads {
let inner = Arc::clone(&inner);
let handle = thread::spawn(move || {
for _ in 0..ops_per_thread {
inner.add_strong_weight(weight_per_op);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let expected = num_threads * ops_per_thread * weight_per_op;
assert_eq!(inner.strong_weight(), expected);
}
#[test]
fn concurrent_add_and_drop_weight_are_atomic() {
let starting_weight: usize = 1_000_000;
let inner = Arc::new(Inner::new(42, starting_weight, 0));
let num_threads = 50;
let ops_per_thread = 1000;
let weight_per_op: usize = 10;
let mut handles = vec![];
for _ in 0..num_threads {
let inner = Arc::clone(&inner);
let handle = thread::spawn(move || {
for _ in 0..ops_per_thread {
inner.add_strong_weight(weight_per_op);
}
});
handles.push(handle);
}
for _ in 0..num_threads {
let inner = Arc::clone(&inner);
let handle = thread::spawn(move || {
for _ in 0..ops_per_thread {
inner.drop_strong_weight(weight_per_op);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(inner.strong_weight(), starting_weight);
}