pipecircuit 0.0.23

Correct. Robust. Fast. Portable. Pick four.
Documentation
use super::super::tests::{Key, index_state, insert_membership};
use super::{SecondaryIndex, SecondaryIndexInconsistency, SecondaryIndexRemoveError};
use crate::storage::warp_table::secondary_index::StableSlot;

#[test]
fn missing_bucket_storage_refuses_removal_without_changing_memberships() -> Result<(), &'static str>
{
    let slot = StableSlot::new(13);
    let mut index = SecondaryIndex::try_new(2).map_err(|_| "index unavailable")?;
    insert_membership(&mut index, Key(7), slot)?;
    let before = index_state(&index);
    assert!(matches!(index.bucket_for_removal(Key(11), slot, 1),
        Err(SecondaryIndexRemoveError::Inconsistent {
            secondary_key: Key(11), slot: actual_slot,
            reason: SecondaryIndexInconsistency::SlotSetUnavailable { row: 1 },
        }) if actual_slot == slot));
    assert_eq!(index_state(&index), before);
    Ok(())
}

#[test]
fn bucket_removal_preserves_the_exact_invalid_preparation_coordinates() -> Result<(), &'static str>
{
    let slot = StableSlot::new(13);
    let mut index = SecondaryIndex::try_new(2).map_err(|_| "index unavailable")?;
    assert_eq!(
        index.prepare_bucket_removal(Key(7), slot, 19),
        Err(SecondaryIndexRemoveError::Inconsistent {
            secondary_key: Key(7),
            slot,
            reason: SecondaryIndexInconsistency::KeyUnavailable { row: 19 },
        })
    );
    insert_membership(&mut index, Key(7), slot)?;
    for (key, row, reason) in [
        (
            Key(11),
            23,
            SecondaryIndexInconsistency::PreparedRemovalAbsent { row: 23 },
        ),
        (
            Key(7),
            29,
            SecondaryIndexInconsistency::PreparedRemovalRowMismatch {
                found_row: 29,
                prepared_row: 0,
            },
        ),
    ] {
        let before = index_state(&index);
        assert_eq!(
            index.prepare_bucket_removal(key, slot, row),
            Err(SecondaryIndexRemoveError::Inconsistent {
                secondary_key: key,
                slot,
                reason,
            })
        );
        assert_eq!(index_state(&index), before);
    }
    insert_membership(&mut index, Key(17), StableSlot::new(31))?;
    index.secondary_keys.pop();
    let before = index_state(&index);
    assert_eq!(
        index.prepare_bucket_removal(Key(7), slot, 0),
        Err(SecondaryIndexRemoveError::Inconsistent {
            secondary_key: Key(7),
            slot,
            reason: SecondaryIndexInconsistency::KeyUnavailable { row: 1 },
        })
    );
    assert_eq!(index_state(&index), before);
    Ok(())
}