use super::*;
use crate::metis::Vouched;
use crate::metis::dot::RawDot;
#[cfg(feature = "instrumentation")]
#[test]
fn the_shadow_profile_accounts_for_every_retained_component() {
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(2)));
weave(
&mut text,
d(1, 2),
locus(
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
rank(1),
),
);
remove(&mut text, d(1, 1));
let moves = movement(d(2, 1), (1, 2), Anchor::Origin, rank(3));
let mut shadow = open_shadow(text, moves);
assert_eq!(shadow.projection().order(), [d(1, 1)]);
let profile = shadow.profile();
assert_eq!(profile.text.skeleton_dots, 2);
assert_eq!(profile.text_context_stations, 1);
assert_eq!(profile.text_context_exceptions, 0);
assert_eq!(profile.testimonies, 1);
assert_eq!(profile.movement_context_stations, 1);
assert_eq!(profile.movement_context_exceptions, 0);
assert_eq!(profile.mapped_dots, 1);
assert_eq!(profile.mapped_ceiling_stations, 2);
assert_eq!(profile.mapped_live_stations, 1);
assert_eq!(profile.recension.sequence.skeleton_dots, 2);
let ancestry = profile.recension.ancestry.unwrap();
assert_eq!(ancestry.resident_nodes, 2);
assert_eq!(ancestry.node_capacity, 3);
assert_eq!(profile.recension.refused, 0);
assert_eq!(profile.recension.pending, 0);
assert_eq!(profile.recension.plays, 1);
assert_eq!(profile.recension.anchored, 1);
assert_eq!(profile.recension.dangling, 0);
assert_eq!(profile.recension.folded, 1);
assert_eq!(profile.recension.woven_mark_stations, 1);
assert_eq!(profile.recension.woven_mark_exceptions, 0);
assert_eq!(profile.recension.visible_mark_stations, 1);
assert_eq!(profile.recension.visible_mark_pages, 1);
assert_eq!(profile.projected_dots, 1);
assert!(profile.projected_capacity >= profile.projected_dots);
}
#[test]
fn the_shadow_preserves_the_old_world_cycle_verdict() {
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(2)));
weave(&mut text, d(1, 2), locus(Anchor::Origin, rank(1)));
let delta = movement(
d(2, 10),
(1, 1),
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(1),
);
assert_eq!(
text.store().recension(delta.store()).order(),
[d(1, 2), d(1, 1)]
);
let mut shadow = open_shadow(text, Moves::new());
assert_eq!(shadow.projection().order(), [d(1, 1), d(1, 2)]);
shadow.deliver_moves(&delta).unwrap();
assert_eq!(shadow.recension().order(), [d(1, 2), d(1, 1)]);
assert_eq!(shadow.recension().refused(), []);
assert_eq!(shadow.projection().order(), [d(1, 2), d(1, 1)]);
}
#[test]
fn the_shadow_keeps_a_swept_anchor_bucket_in_both_arrival_orders() {
let mut text = Text::new();
for (dot, anchor, tag) in [
(d(1, 1), Anchor::Origin, 5),
(
d(1, 2),
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
4,
),
(
d(1, 3),
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
1,
),
(d(1, 4), Anchor::Origin, 0),
(d(1, 5), Anchor::Origin, 0),
] {
weave(&mut text, dot, locus(anchor, rank(tag)));
}
remove(&mut text, d(1, 2));
let high = movement(
d(2, 11),
(1, 4),
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(3),
);
let low = movement(
d(2, 10),
(1, 5),
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(2),
);
let expected = [d(1, 1), d(1, 3), d(1, 4), d(1, 2)];
for deltas in [[&high, &low], [&low, &high]] {
let mut shadow = open_shadow(text.clone(), Moves::new());
shadow.deliver_moves(deltas[0]).unwrap();
shadow.deliver_moves(deltas[1]).unwrap();
assert_eq!(shadow.projection().order(), expected);
}
}
#[test]
fn an_earlier_window_move_redecides_the_retained_record() {
let mut text = Text::new();
for (dot, tag) in [(d(1, 1), 3), (d(1, 2), 2), (d(1, 3), 1)] {
weave(&mut text, dot, locus(Anchor::Origin, rank(tag)));
}
let record = movement(
d(2, 1),
(1, 1),
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(2),
);
let mut shadow = open_shadow(text, record);
assert_eq!(shadow.projection().order(), [d(1, 1), d(1, 2), d(1, 3)]);
shadow
.deliver_moves(&movement(
d(2, 10),
(1, 2),
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
rank(1),
))
.unwrap();
assert_eq!(shadow.recension().refused(), [d(2, 1)]);
assert_eq!(shadow.projection().order(), [d(1, 2), d(1, 1), d(1, 3)]);
}
#[test]
fn native_events_wait_for_exactly_the_adopted_declaration() {
let winner = adopted(d(1, 10));
let loser = adopted(d(2, 10));
let mut ideal: EpochIdeal<char> = EpochIdeal::default();
ideal.insert(Event {
stamp: Kairos::new(1, 0, 1, 0u16),
deps: winner.address(),
payload: 'w',
});
ideal.insert(Event {
stamp: Kairos::new(2, 0, 2, 0u16),
deps: loser.address(),
payload: 'l',
});
assert_eq!(ideal.pop_ready(), None);
ideal.adopt_epoch(&winner).unwrap();
assert_eq!(
ideal.adopt_epoch(&loser).unwrap_err().adopted,
winner.address()
);
assert_eq!(ideal.pending_len(), 1, "the losing address is terminal");
assert_eq!(ideal.pop_ready(), Some('w'));
assert_eq!(ideal.pop_ready(), None);
}
#[test]
fn duplicate_delivery_reads_identically_across_the_seal() {
let mut text = Text::new();
let birth = locus(Anchor::Origin, rank(2));
weave(&mut text, d(1, 1), birth);
let swept = locus(
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
rank(1),
);
weave(&mut text, d(1, 2), swept);
remove(&mut text, d(1, 2));
let mut stability = Stability::new([1]);
let mut vector = VersionVector::new();
vector.observe(1, 2);
let boundary = Cut::from_witnessed(vector);
stability.report_cut(1, &boundary).unwrap();
let mut epochs = Epochs::new([1], NonZeroUsize::new(1).unwrap());
let declaration = epochs
.declare(d(1, 5), rank(5), &stability, &Cut::bottom())
.unwrap();
let delivered = Cut::from_witnessed({
let mut vector = boundary.as_vector().clone();
vector.observe(1, 5);
vector
});
stability.report_cut(1, &delivered).unwrap();
epochs
.confirm(declaration.address(), &Vouched::trust(1, delivered.clone()))
.unwrap();
let adopted = epochs.adopt(1, 5, &stability).unwrap();
let mut shadow = EpochStratum::new(&adopted, text, Moves::new())
.unwrap()
.into_transition()
.shadow;
let before = shadow.projection().clone();
let mut duplicate = Rhapsody::new();
assert!(duplicate.weave(d(1, 2), swept));
shadow.deliver_text(&Dotted::from_store(duplicate)).unwrap();
assert_eq!(shadow.projection(), &before);
assert!(epochs.try_seal(&stability).is_some());
let frozen = shadow.projection().clone();
drop(shadow);
assert_eq!(epochs.recognize(declaration.address(), d(1, 2)), Ok(()));
assert_eq!(frozen, before);
}
#[test]
fn a_swept_at_cut_identity_is_refused_before_mutation() {
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(2)));
let mut covered_elsewhere = DotSet::new();
for dot in 2..=9 {
assert!(covered_elsewhere.insert(d(1, dot)));
}
let moves = Dotted::from_context(covered_elsewhere);
let mut shadow = open_shadow(text, moves);
let before = shadow.projection().clone();
let mut late = Rhapsody::new();
assert!(late.weave(d(1, 5), locus(Anchor::Origin, rank(1))));
let error = shadow
.deliver_text(&Dotted::from_store(late))
.expect_err("the witnessed cut froze the compacted domain");
assert_eq!(error.dot, d(1, 5));
assert_eq!(shadow.projection(), &before);
}
#[test]
fn a_novel_below_cut_tombstone_cannot_activate_a_window_child() {
let mut vector = VersionVector::new();
vector.observe(1, 5);
let adopted = adopted_over(d(1, 6), &Cut::from_witnessed(vector));
let mut receipts = DotSet::new();
for dot in 1..=5 {
assert!(receipts.insert(d(1, dot)));
}
let stratum = EpochStratum::new(&adopted, Text::new(), Dotted::from_context(receipts)).unwrap();
let mut shadow = stratum.into_transition().shadow;
let child = text_delta(
d(1, 10),
locus(
Anchor::After(RawDot {
station: 1,
counter: 5,
}),
rank(10),
),
);
shadow.deliver_text(&child).unwrap();
assert_eq!(shadow.projection().order(), []);
let mut tombstone = Text::new();
weave(&mut tombstone, d(1, 5), locus(Anchor::Origin, rank(5)));
remove(&mut tombstone, d(1, 5));
let error = shadow
.deliver_text(&tombstone)
.expect_err("recording identities are validated even when invisible");
assert_eq!(error.dot, d(1, 5));
assert_eq!(shadow.projection().order(), []);
}
#[test]
fn a_novel_below_cut_testimony_is_refused_before_redecision() {
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(2)));
weave(&mut text, d(1, 2), locus(Anchor::Origin, rank(1)));
let mut movement_receipts = DotSet::new();
for dot in 1..=5 {
assert!(movement_receipts.insert(d(2, dot)));
}
text.merge_from(&Dotted::from_context(movement_receipts));
let mut shadow = open_shadow(text, Moves::new());
let before = shadow.projection().clone();
let error = shadow
.deliver_moves(&movement(
d(2, 5),
(1, 1),
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(1),
))
.expect_err("the confirmation watermark covered this testimony dot");
assert_eq!(error.dot, d(2, 5));
assert_eq!(shadow.projection(), &before);
}
#[test]
fn an_incomplete_below_cut_stratum_is_refused() {
let mut vector = VersionVector::new();
vector.observe(1, 2);
let adopted = adopted_over(d(1, 3), &Cut::from_witnessed(vector));
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(1)));
assert_eq!(
EpochStratum::new(&adopted, text, Moves::new()).unwrap_err(),
crate::metis::EpochStratumError::Incomplete { dot: d(1, 2) }
);
}
#[test]
fn above_cut_state_cannot_shift_the_frozen_map() {
let mut vector = VersionVector::new();
vector.observe(1, 2);
let adopted = adopted_over(d(1, 3), &Cut::from_witnessed(vector));
let mut base = Text::new();
weave(&mut base, d(1, 1), locus(Anchor::Origin, rank(2)));
weave(
&mut base,
d(1, 2),
locus(
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
rank(1),
),
);
let three = text_delta(
d(1, 3),
locus(
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(3),
),
);
let four = text_delta(
d(1, 4),
locus(
Anchor::After(RawDot {
station: 1,
counter: 3,
}),
rank(4),
),
);
let mut current = base.clone();
current.merge_from(&three);
assert_eq!(
EpochStratum::new(&adopted, current, Moves::new()).unwrap_err(),
crate::metis::EpochStratumError::BeyondCut { dot: d(1, 3) }
);
let mut left = EpochStratum::new(&adopted, base.clone(), Moves::new())
.unwrap()
.into_transition()
.shadow;
let mut right = EpochStratum::new(&adopted, base, Moves::new())
.unwrap()
.into_transition()
.shadow;
assert_eq!(left.projection(), right.projection());
left.deliver_text(&three).unwrap();
left.deliver_text(&four).unwrap();
right.deliver_text(&four).unwrap();
right.deliver_text(&three).unwrap();
assert_eq!(left.projection(), right.projection());
assert_eq!(
left.projection().order(),
[d(1, 1), d(1, 2), d(1, 3), d(1, 4)]
);
}
#[test]
fn the_fused_stratum_retains_the_refound_store() {
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(3)));
weave(
&mut text,
d(1, 2),
locus(
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
rank(2),
),
);
weave(
&mut text,
d(1, 3),
locus(
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(1),
),
);
remove(&mut text, d(1, 2));
let moves = movement(d(2, 1), (1, 3), Anchor::Origin, rank(4));
let coverage = text.context().merge(moves.context());
let boundary = Cut::floor_of(&coverage);
let adopted = adopted_over(d(1, boundary.as_vector().get(1) + 1), &boundary);
let stratum = EpochStratum::new(&adopted, text.clone(), moves.clone()).unwrap();
let refounded = text.store().refound(moves.store()).unwrap();
assert_eq!(stratum.pristine(), refounded.store());
assert_eq!(stratum.pristine().order(), [d(1, 1), d(1, 2)]);
}
#[test]
fn a_batch_stops_at_the_first_swept_identity_with_the_surface_current() {
let mut text = Text::new();
weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(2)));
weave(&mut text, d(1, 2), locus(Anchor::Origin, rank(1)));
let mut receipts = DotSet::new();
for dot in 1..=5 {
assert!(receipts.insert(d(2, dot)));
}
text.merge_from(&Dotted::from_context(receipts));
let mut batched = open_shadow(text.clone(), Moves::new());
let mut sequential = open_shadow(text, Moves::new());
let lawful = movement(
d(2, 6),
(1, 1),
Anchor::After(RawDot {
station: 1,
counter: 2,
}),
rank(9),
);
let swept = movement(d(2, 5), (1, 1), Anchor::Origin, rank(8));
let unreached = movement(
d(2, 7),
(1, 2),
Anchor::After(RawDot {
station: 1,
counter: 1,
}),
rank(7),
);
let error = batched
.deliver_moves_batch([&lawful, &swept, &unreached])
.expect_err("the covered testimony dot is swept");
assert_eq!(error.dot, d(2, 5));
sequential.deliver_moves(&lawful).unwrap();
assert_eq!(batched.projection(), sequential.projection());
assert_eq!(batched.recension().order(), sequential.recension().order());
assert_eq!(batched.projection().order(), [d(1, 2), d(1, 1)]);
}