minerva 0.2.0

Causal ordering for distributed systems
//! Typed refusals at the consignment trust boundary.

use super::*;
use crate::metis::dot::RawDot;

/// A seal cannot consign until every covered window delta is present.
#[test]
fn a_seal_covering_a_withheld_delta_refuses_then_the_delivery_cures() {
    let mut text = Text::new();
    weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(1)));
    let boundary = Cut::floor_of(text.context());
    // The seal proves (2, 1) was delivered everywhere, but this shadow
    // has not received it yet.
    let (adopted, sealed) = seal_mill(1, &boundary, &[(2, 1)]);
    let shadow = EpochStratum::new(&adopted, text, Moves::new())
        .unwrap()
        .into_transition()
        .shadow;
    let (shadow, refusal) = shadow.consign(&sealed).unwrap_err();
    let mut shadow = *shadow;
    assert_eq!(
        refusal,
        EpochConsignmentError::Incomplete {
            dot: RawDot::new(2, 1)
        }
    );

    shadow
        .deliver_text(&text_delta(
            d(2, 1),
            locus(
                Anchor::After(RawDot {
                    station: 1,
                    counter: 1,
                }),
                Kairos::new(5, 0, 2, 0u16),
            ),
        ))
        .unwrap();
    let projection = shadow.projection().clone();
    let consignment = shadow.consign(&sealed).unwrap().0;
    assert_eq!(consignment.text().store().order(), projection.order());
    assert_eq!(consignment.text().store().order(), [d(1, 1), d(2, 1)]);
}

/// Traffic above the sealed join cannot enter the consignment.
#[test]
fn post_seal_traffic_cannot_enter_the_consignment() {
    let mut text = Text::new();
    weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(1)));
    let boundary = Cut::floor_of(text.context());
    let (adopted, sealed) = seal_mill(1, &boundary, &[(2, 1)]);
    let mut shadow = EpochStratum::new(&adopted, text, Moves::new())
        .unwrap()
        .into_transition()
        .shadow;
    shadow
        .deliver_text(&text_delta(
            d(2, 1),
            locus(
                Anchor::After(RawDot {
                    station: 1,
                    counter: 1,
                }),
                Kairos::new(5, 0, 2, 0u16),
            ),
        ))
        .unwrap();
    shadow
        .deliver_text(&text_delta(
            d(2, 5),
            locus(
                Anchor::After(RawDot {
                    station: 1,
                    counter: 1,
                }),
                Kairos::new(6, 0, 2, 0u16),
            ),
        ))
        .unwrap();
    assert_eq!(
        shadow.consign(&sealed).unwrap_err().1,
        EpochConsignmentError::BeyondSeal {
            dot: RawDot::new(2, 5)
        }
    );
}

/// A seal for another epoch cannot authorize consignment.
#[test]
fn a_foreign_seal_cannot_consign() {
    let mut text = Text::new();
    weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(1)));
    let boundary = Cut::floor_of(text.context());
    let (adopted, _) = seal_mill(1, &boundary, &[]);
    let (_, foreign) = seal_mill(2, &boundary, &[]);
    let shadow = EpochStratum::new(&adopted, text, Moves::new())
        .unwrap()
        .into_transition()
        .shadow;
    let epoch = adopted.address();
    assert_eq!(
        shadow.consign(&foreign).unwrap_err().1,
        EpochConsignmentError::ForeignSeal {
            sealed: foreign.declaration(),
            shadow: epoch,
        }
    );
}

/// Window state without a lawful place is refused rather than guessed.
#[test]
fn an_unfoldable_window_is_refused_at_the_consignment() {
    let mut text = Text::new();
    weave(&mut text, d(1, 1), locus(Anchor::Origin, rank(1)));
    let boundary = Cut::floor_of(text.context());

    let (adopted, sealed) = seal_mill(1, &boundary, &[(2, 1)]);
    let mut shadow = EpochStratum::new(&adopted, text.clone(), Moves::new())
        .unwrap()
        .into_transition()
        .shadow;
    shadow
        .deliver_moves(&movement(d(2, 1), (9, 9), Anchor::Origin, rank(1)))
        .unwrap();
    assert_eq!(
        shadow.consign(&sealed).unwrap_err().1,
        EpochConsignmentError::Unfoldable { dot: d(2, 1) }
    );

    let (adopted, sealed) = seal_mill(1, &boundary, &[(2, 1)]);
    let mut shadow = EpochStratum::new(&adopted, text, Moves::new())
        .unwrap()
        .into_transition()
        .shadow;
    shadow
        .deliver_text(&text_delta(
            d(2, 1),
            locus(
                Anchor::After(RawDot {
                    station: 9,
                    counter: 9,
                }),
                Kairos::new(5, 0, 2, 0u16),
            ),
        ))
        .unwrap();
    assert_eq!(
        shadow.consign(&sealed).unwrap_err().1,
        EpochConsignmentError::Unfoldable { dot: d(2, 1) }
    );
}