extern crate alloc;
use super::super::support::{arb_history, deliverable, drain, perm_of};
use crate::metis::{CausalIdeal, VersionVector};
use alloc::vec::Vec;
use proptest::prelude::*;
proptest! {
#[test]
fn prop_release_respects_causality(
(history, perm) in arb_history()
.prop_flat_map(|history| {
let perm = perm_of(history.len());
(Just(history), perm)
}),
) {
let mut buf = CausalIdeal::new();
for &index in &perm {
buf.insert(history[index].clone());
}
let released = drain(&mut buf);
let mut delivered = VersionVector::new();
for &payload in &released {
let event = &history[payload as usize];
prop_assert!(deliverable(event, &delivered));
delivered = delivered.merge(&event.deps);
}
}
#[test]
fn prop_every_event_released_once(
(history, perm) in arb_history()
.prop_flat_map(|history| {
let perm = perm_of(history.len());
(Just(history), perm)
}),
) {
let mut buf = CausalIdeal::new();
for &index in &perm {
buf.insert(history[index].clone());
}
let mut released = drain(&mut buf);
prop_assert_eq!(buf.pending_len(), 0);
prop_assert_eq!(released.len(), history.len());
released.sort_unstable();
let n = u32::try_from(history.len()).unwrap();
prop_assert_eq!(released, (0..n).collect::<Vec<u32>>());
}
#[test]
fn prop_duplicates_dropped(
(history, perm) in arb_history()
.prop_flat_map(|history| {
let perm = perm_of(history.len() * 2);
(Just(history), perm)
}),
) {
let n = history.len();
let mut buf = CausalIdeal::new();
for &index in &perm {
buf.insert(history[index % n].clone());
}
let mut released = drain(&mut buf);
prop_assert_eq!(released.len(), n);
released.sort_unstable();
released.dedup();
prop_assert_eq!(released.len(), n);
}
#[test]
fn prop_release_order_is_permutation_invariant(
(history, perm_a, perm_b) in arb_history()
.prop_flat_map(|history| {
let len = history.len();
(Just(history), perm_of(len), perm_of(len))
}),
) {
let release = |perm: &[usize]| {
let mut buf = CausalIdeal::new();
for &index in perm {
buf.insert(history[index].clone());
}
drain(&mut buf)
};
prop_assert_eq!(release(&perm_a), release(&perm_b));
}
}