use super::*;
use crate::config::NetworkChoice;
use crate::index::PadStatus;
use mutant_protocol::{StorageMode, MEDIUM_SCRATCHPAD_SIZE};
use std::path::PathBuf;
const DEFAULT_SCRATCHPAD_SIZE: usize = MEDIUM_SCRATCHPAD_SIZE;
fn setup_test_environment() -> (PathBuf, MasterIndex) {
let mutant_data_dir = utils::get_mutant_data_dir().unwrap();
std::fs::remove_file(mutant_data_dir.join("master_index_devnet.cbor")).unwrap_or_default();
let index = MasterIndex::new(NetworkChoice::Devnet);
(mutant_data_dir, index)
}
#[test]
fn test_new_master_index() {
let (_td, index) = setup_test_environment();
assert!(index.index.is_empty());
assert!(index.free_pads.is_empty());
assert!(index.pending_verification_pads.is_empty());
}
#[test]
fn test_create_private_key_new() {
let (_td, mut index) = setup_test_environment();
let data = vec![0u8; DEFAULT_SCRATCHPAD_SIZE * 2 + 10]; let key_name = "test_key";
let (pads, _) = index
.create_key(key_name, &data, StorageMode::Medium, false)
.unwrap();
assert_eq!(pads.len(), 3); assert!(index.contains_key(key_name));
if let Some(IndexEntry::PrivateKey(stored_pads)) = index.index.get(key_name) {
assert_eq!(stored_pads.len(), 3);
assert_eq!(stored_pads[0].status, PadStatus::Generated);
assert_eq!(stored_pads[1].status, PadStatus::Generated);
assert_eq!(stored_pads[2].status, PadStatus::Generated);
} else {
panic!("Key not found or not a PrivateKey entry");
}
}
#[test]
fn test_create_private_key_existing() {
let (_td, mut index) = setup_test_environment();
let data = vec![1u8; 10];
let key_name = "test_key";
index
.create_key(key_name, &data, StorageMode::Medium, false)
.unwrap();
let result = index.create_key(key_name, &data, StorageMode::Medium, false);
assert!(matches!(
result,
Err(crate::error::Error::Index(crate::index::error::IndexError::KeyAlreadyExists(_)))
));
}
#[test]
fn test_update_pad_status_private() {
let (_td, mut index) = setup_test_environment();
let data = vec![0u8; DEFAULT_SCRATCHPAD_SIZE];
let key_name = "test_key";
let (pads, _) = index
.create_key(key_name, &data, StorageMode::Medium, false)
.unwrap();
let pad_address = pads[0].address;
index
.update_pad_status(key_name, &pad_address, PadStatus::Confirmed, None)
.unwrap();
if let Some(IndexEntry::PrivateKey(updated_pads)) = index.index.get(key_name) {
assert_eq!(updated_pads[0].status, PadStatus::Confirmed);
} else {
panic!("Key not found or not a PrivateKey entry");
}
}
#[test]
fn test_contains_key() {
let (_td, mut index) = setup_test_environment();
let data = vec![1u8; 10];
let key_name = "test_key";
assert!(!index.contains_key(key_name));
index
.create_key(key_name, &data, StorageMode::Medium, false)
.unwrap();
assert!(index.contains_key(key_name));
assert!(!index.contains_key("other_key"));
}
#[test]
fn test_remove_key_moves_pads() {
let (_td, mut index) = setup_test_environment();
let data_gen = vec![0u8; DEFAULT_SCRATCHPAD_SIZE];
let data_conf = vec![1u8; DEFAULT_SCRATCHPAD_SIZE];
let key_gen = "key_gen";
let key_conf = "key_conf";
let (pads_gen, _) = index
.create_key(key_gen, &data_gen, StorageMode::Medium, false)
.unwrap();
let pad_gen_addr = pads_gen[0].address;
let (pads_conf, _) = index
.create_key(key_conf, &data_conf, StorageMode::Medium, false)
.unwrap();
let pad_conf_addr = pads_conf[0].address;
index
.update_pad_status(key_conf, &pad_conf_addr, PadStatus::Confirmed, None)
.unwrap();
index.remove_key(key_gen).unwrap();
assert!(!index.contains_key(key_gen));
assert_eq!(index.pending_verification_pads.len(), 1);
assert_eq!(index.pending_verification_pads[0].address, pad_gen_addr);
assert_eq!(index.free_pads.len(), 0);
index.remove_key(key_conf).unwrap();
assert!(!index.contains_key(key_conf));
assert_eq!(index.pending_verification_pads.len(), 1); assert_eq!(index.free_pads.len(), 1);
assert_eq!(index.free_pads[0].address, pad_conf_addr);
assert_eq!(index.free_pads[0].status, PadStatus::Free);
}
#[test]
fn test_is_finished() {
let (_td, mut index) = setup_test_environment();
let data = vec![0u8; DEFAULT_SCRATCHPAD_SIZE * 2];
let key_name = "test_key";
let (pads, _) = index
.create_key(key_name, &data, StorageMode::Medium, false)
.unwrap();
assert!(!index.is_finished(key_name));
index
.update_pad_status(key_name, &pads[0].address, PadStatus::Confirmed, None)
.unwrap();
assert!(!index.is_finished(key_name));
index
.update_pad_status(key_name, &pads[1].address, PadStatus::Confirmed, None)
.unwrap();
assert!(index.is_finished(key_name));
assert!(!index.is_finished("non_existent_key")); }
#[test]
fn test_verify_checksum_private() {
let (_td, mut index) = setup_test_environment();
let data = vec![0u8; DEFAULT_SCRATCHPAD_SIZE + 5];
let key_name = "test_key";
index
.create_key(key_name, &data, StorageMode::Medium, false)
.unwrap();
assert!(index.verify_checksum(key_name, &data, StorageMode::Medium));
let wrong_data_len = vec![0u8; DEFAULT_SCRATCHPAD_SIZE];
assert!(!index.verify_checksum(key_name, &wrong_data_len, StorageMode::Medium));
let mut wrong_data_content = data.clone();
wrong_data_content[0] = 1; assert!(!index.verify_checksum(key_name, &wrong_data_content, StorageMode::Medium));
assert!(!index.verify_checksum("non_existent_key", &data, StorageMode::Medium));
}
#[test]
fn test_list() {
let (_td, mut index) = setup_test_environment();
assert!(index.list().is_empty());
index
.create_key("key1", &[1], StorageMode::Medium, false)
.unwrap();
index
.create_key("key2", &[2], StorageMode::Medium, false)
.unwrap();
let keys = index.list();
assert_eq!(keys.keys().collect::<Vec<_>>(), vec!["key1", "key2"]);
}
#[test]
fn test_acquire_pads_reuse_free() {
let (_td, mut index) = setup_test_environment();
let data1 = vec![1u8; DEFAULT_SCRATCHPAD_SIZE];
let data2 = vec![2u8; DEFAULT_SCRATCHPAD_SIZE];
let key1 = "key1";
let key2 = "key2";
let (pads1, _) = index
.create_key(key1, &data1, StorageMode::Medium, false)
.unwrap();
assert_eq!(pads1.len(), 1);
let pad1_addr = pads1[0].address;
index
.update_pad_status(key1, &pad1_addr, PadStatus::Confirmed, None)
.unwrap();
index.remove_key(key1).unwrap();
assert_eq!(index.free_pads.len(), 1);
assert_eq!(index.pending_verification_pads.len(), 0);
assert_eq!(index.free_pads[0].address, pad1_addr);
assert_eq!(index.free_pads[0].status, PadStatus::Free);
let (pads2, _) = index
.create_key(key2, &data2, StorageMode::Medium, false)
.unwrap();
assert_eq!(pads2.len(), 1);
assert_eq!(pads2[0].address, pad1_addr); assert_eq!(pads2[0].status, PadStatus::Free); assert_eq!(pads2[0].checksum, PadInfo::checksum(&data2)); assert!(index.free_pads.is_empty()); }
#[test]
fn test_acquire_pads_generate_new() {
let (_td, mut index) = setup_test_environment();
let data = vec![1u8; DEFAULT_SCRATCHPAD_SIZE * 2];
let key = "key";
assert!(index.free_pads.is_empty());
let (pads, _) = index
.create_key(key, &data, StorageMode::Medium, false)
.unwrap();
assert_eq!(pads.len(), 2);
assert_ne!(pads[0].address, pads[1].address); assert!(index.free_pads.is_empty()); }
#[test]
fn test_acquire_pads_mix_free_and_new() {
let (_td, mut index) = setup_test_environment();
let data1 = vec![1u8; DEFAULT_SCRATCHPAD_SIZE];
let data3 = vec![3u8; DEFAULT_SCRATCHPAD_SIZE * 3]; let key1 = "key1";
let key3 = "key3";
let (pads1, _) = index
.create_key(key1, &data1, StorageMode::Medium, false)
.unwrap();
let pad1_addr = pads1[0].address;
index
.update_pad_status(key1, &pad1_addr, PadStatus::Confirmed, None)
.unwrap();
index.remove_key(key1).unwrap();
assert_eq!(index.free_pads.len(), 1);
let (pads3, _) = index
.create_key(key3, &data3, StorageMode::Medium, false)
.unwrap();
assert_eq!(pads3.len(), 3);
assert!(index.free_pads.is_empty());
assert_eq!(pads3[0].address, pad1_addr);
assert_eq!(pads3[0].status, PadStatus::Free);
assert_eq!(
pads3[0].checksum,
PadInfo::checksum(&data3[0..DEFAULT_SCRATCHPAD_SIZE])
);
assert_ne!(pads3[1].address, pad1_addr);
assert_ne!(pads3[2].address, pad1_addr);
assert_eq!(pads3[1].status, PadStatus::Generated);
assert_eq!(pads3[2].status, PadStatus::Generated);
assert_eq!(
pads3[1].checksum,
PadInfo::checksum(&data3[DEFAULT_SCRATCHPAD_SIZE..DEFAULT_SCRATCHPAD_SIZE * 2])
);
assert_eq!(
pads3[2].checksum,
PadInfo::checksum(&data3[DEFAULT_SCRATCHPAD_SIZE * 2..])
);
if let Some(IndexEntry::PrivateKey(stored_pads)) = index.index.get(key3) {
assert_eq!(stored_pads.len(), 3);
} else {
panic!("Key not found or not a PrivateKey entry");
}
}
#[test]
fn test_load_non_existent_file() {
let (_td, index) = setup_test_environment(); assert!(index.index.is_empty()); }