extern crate alloc;
use alloc::vec::Vec;
use core::num::NonZeroU32;
use super::super::d;
use super::{Seq, clock, woven};
use crate::metis::dot::RawDot;
use crate::metis::{Anchor, Dot, Dotted, Locus, Rhapsody};
fn reserve(station: u32, len: u32) -> crate::kairos::KairosRun {
clock(station).now_run(
NonZeroU32::new(len).expect("test lengths are nonzero"),
0u16,
)
}
#[test]
fn test_weave_run_refuses_whole() {
let mut rhapsody = Rhapsody::new();
assert!(Dot::from_parts(1, 0).is_err());
assert_eq!(rhapsody.skeleton_len(), 0);
assert!(!rhapsody.weave_run(d(1, u64::MAX - 1), Anchor::Origin, reserve(1, 3)));
assert_eq!(rhapsody.skeleton_len(), 0);
let occupant = Locus {
anchor: Anchor::Origin,
rank: clock(2).now(0u16),
};
assert!(rhapsody.weave(d(1, 2), occupant));
assert!(!rhapsody.weave_run(d(1, 1), Anchor::Origin, reserve(1, 3)));
assert_eq!(rhapsody.skeleton_len(), 1);
assert!(!rhapsody.is_visible(d(1, 1)));
assert!(!rhapsody.is_visible(d(1, 3)));
assert!(rhapsody.weave_run(d(1, u64::MAX - 2), Anchor::Origin, reserve(1, 3)));
assert!(rhapsody.is_visible(d(1, u64::MAX)));
let absurd = clock(1).now_run(NonZeroU32::new(u32::MAX).expect("nonzero"), 0u16);
let before = rhapsody.skeleton_len();
assert!(!rhapsody.weave_run(d(2, 1), Anchor::Origin, absurd));
assert_eq!(
rhapsody.skeleton_len(),
before,
"a refused run changes nothing"
);
}
#[test]
fn test_a_dangling_run_parks_whole_and_repairs_whole() {
let mut replica: Seq = Dotted::new();
let clk = clock(1);
let anchor_rank = clk.now(0u16);
let run = clock(2).now_run(NonZeroU32::new(70).expect("nonzero"), 0u16);
let mut fragment = Rhapsody::new();
assert!(fragment.weave_run(
d(2, 1),
Anchor::After(RawDot {
station: 1,
counter: 1
}),
run
));
fragment.check_order_thread();
assert!(!fragment.is_reachable(d(2, 1)));
assert!(!fragment.is_reachable(d(2, 70)));
assert_eq!(fragment.order_len(), 0);
assert_eq!(fragment.offset_of(d(2, 35)), None);
assert!(fragment.order_walk_after(d(2, 1)).is_none());
replica = replica.merge(&Dotted::from_store(fragment));
assert!(replica.store().is_visible(d(2, 1)));
assert!(replica.store().is_visible(d(2, 70)));
assert!(!replica.store().is_reachable(d(2, 1)));
assert_eq!(replica.store().order(), Vec::<Dot>::new());
replica = replica.merge(&woven(
d(1, 1),
Locus {
anchor: Anchor::Origin,
rank: anchor_rank,
},
));
replica.store().check_order_thread();
assert_eq!(replica.store().order_len(), 71);
assert_eq!(replica.store().order_at(0), Some(d(1, 1)));
assert_eq!(replica.store().order_at(1), Some(d(2, 1)));
assert_eq!(replica.store().order_at(70), Some(d(2, 70)));
}
#[test]
fn test_a_self_anchored_run_parks_whole() {
let run = reserve(1, 4);
let members: Vec<_> = run.iter().collect();
let mut bulk = Rhapsody::new();
assert!(bulk.weave_run(
d(1, 1),
Anchor::After(RawDot {
station: 1,
counter: 3
}),
run
));
bulk.check_order_thread();
let mut pointwise = Rhapsody::new();
let mut prev = (1u32, 1u64);
for k in 0..4u32 {
let dot = d(1, 1 + u64::from(k));
let locus = Locus {
anchor: if k == 0 {
Anchor::After(RawDot {
station: 1,
counter: 3,
})
} else {
Anchor::After(prev.into())
},
rank: members[k as usize],
};
assert!(pointwise.weave(dot, locus));
prev = dot.into();
}
assert_eq!(bulk, pointwise);
assert_eq!(bulk.order(), Vec::<Dot>::new(), "a cycle never places");
assert!(!bulk.is_reachable(d(1, 1)));
assert!(bulk.is_visible(d(1, 4)));
}
#[test]
fn test_a_parked_waiter_inside_the_run_degrades_and_repairs() {
let mut replica: Seq = Dotted::new();
let waiter_rank = clock(3).now(0u16);
replica = replica.merge(&woven(
d(3, 1),
Locus {
anchor: Anchor::After(RawDot {
station: 1,
counter: 5,
}),
rank: waiter_rank,
},
));
assert!(!replica.store().is_reachable(d(3, 1)));
let run = reserve(1, 8);
let members: Vec<_> = run.iter().collect();
let mut bulk = replica.store().clone();
assert!(bulk.weave_run(d(1, 1), Anchor::Origin, run));
bulk.check_order_thread();
let mut pointwise = replica.store().clone();
let mut prev = (1u32, 1u64);
for k in 0..8u32 {
let dot = d(1, 1 + u64::from(k));
let locus = Locus {
anchor: if k == 0 {
Anchor::Origin
} else {
Anchor::After(prev.into())
},
rank: members[k as usize],
};
assert!(pointwise.weave(dot, locus));
prev = dot.into();
}
assert_eq!(bulk, pointwise);
assert_eq!(bulk.order(), pointwise.order());
assert!(bulk.is_reachable(d(3, 1)));
assert_eq!(bulk.offset_of(d(3, 1)), Some(8));
assert_eq!(bulk.order_at(8), Some(d(3, 1)));
}
#[test]
fn test_a_pasted_run_coalesces_by_birthright() {
let clk = clock(1);
let mut bulk = Rhapsody::new();
let mut pointwise = Rhapsody::new();
let mut prev: Option<RawDot> = None;
for index in 1..=64u64 {
let locus = Locus {
anchor: prev.map_or(Anchor::Origin, Anchor::After),
rank: clk.now(0u16),
};
assert!(bulk.weave(d(1, index), locus));
assert!(pointwise.weave(d(1, index), locus));
prev = Some(RawDot::new(1, index));
}
let run = clk.now_run(NonZeroU32::new(256).expect("nonzero"), 0u16);
let members: Vec<_> = run.iter().collect();
assert!(bulk.weave_run(
d(1, 65),
Anchor::After(RawDot {
station: 1,
counter: 64
}),
run
));
let mut prev = (1u32, 64u64);
for k in 0..256u32 {
let dot = d(1, 65 + u64::from(k));
let locus = Locus {
anchor: Anchor::After(prev.into()),
rank: members[k as usize],
};
assert!(pointwise.weave(dot, locus));
prev = dot.into();
}
assert_eq!(bulk, pointwise);
bulk.check_order_thread();
assert_eq!(
bulk.to_snapshot_bytes(),
pointwise.to_snapshot_bytes(),
"byte identity survives the bulk path"
);
assert_eq!(
bulk.order_thread_region_segments(),
1,
"the paste extended the typed chain's one segment"
);
assert_eq!(
bulk.order_thread_fragments(),
5,
"320 slots tile five fragments"
);
}