minerva 0.2.0

Causal ordering for distributed systems
extern crate alloc;

use alloc::vec::Vec;

use crate::metis::{DotSet, Rhapsody, RhapsodyDecodeError};

use super::super::d;
use super::rank;

#[test]
fn test_rhapsody_rejects_non_ascending_loci() {
    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&2u32.to_be_bytes());
    for (station, index, rank_physical) in [(1u32, 2u64, 9u64), (1u32, 1u64, 7u64)] {
        bytes.extend_from_slice(&station.to_be_bytes());
        bytes.extend_from_slice(&index.to_be_bytes());
        bytes.push(0x00);
        bytes.extend_from_slice(&rank(rank_physical).to_bytes());
    }
    bytes.push(0x01u8);
    bytes.extend_from_slice(&0u32.to_be_bytes());
    assert_eq!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::NonAscendingLoci {
            previous: (1, 2),
            found: (1, 1),
        })
    );
}

#[test]
fn test_rhapsody_rejects_zero_index_dot() {
    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&5u32.to_be_bytes());
    bytes.extend_from_slice(&0u64.to_be_bytes());
    bytes.push(0x00);
    bytes.extend_from_slice(&rank(1).to_bytes());
    bytes.push(0x01u8);
    bytes.extend_from_slice(&0u32.to_be_bytes());
    assert_eq!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::ZeroDot { station: 5 })
    );
}

#[test]
fn test_rhapsody_rejects_bad_anchor_tag() {
    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u64.to_be_bytes());
    bytes.push(0x03);
    bytes.extend_from_slice(&rank(1).to_bytes());
    bytes.push(0x01u8);
    bytes.extend_from_slice(&0u32.to_be_bytes());
    assert_eq!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::BadAnchorTag { tag: 0x03 })
    );
}

#[test]
fn test_rhapsody_rejects_visible_without_locus() {
    let mut bytes = Vec::new();
    bytes.push(0x02u8);
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u32.to_be_bytes());
    bytes.extend_from_slice(&1u64.to_be_bytes());
    bytes.push(0x00);
    bytes.extend_from_slice(&rank(1).to_bytes());

    let mut visible = DotSet::new();
    let _ = visible.insert(d(1, 1));
    let _ = visible.insert(d(1, 2));
    bytes.extend_from_slice(&visible.to_bytes());
    assert_eq!(
        Rhapsody::from_bytes(&bytes),
        Err(RhapsodyDecodeError::VisibleWithoutLocus {
            station: 1,
            index: 2,
        })
    );
}