use crate::{size::ByteSize, BlockDB};
use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct ChunkCount {
pub used: usize,
pub free: usize,
}
#[derive(Debug, Clone, Default)]
pub struct TestState {
pub data_file_count: usize,
pub block_db_byte_size: ByteSize,
pub data_file_byte_size_map: HashMap<String, ByteSize>,
pub data_file_chunk_count_map: HashMap<String, ChunkCount>,
}
impl TestState {
pub async fn assert_against_block_db(&self, block_db: &BlockDB) -> Result<(), String> {
let free_chunk_count = block_db.free_chunk_count().await;
let expected_free_chunk_count = self
.data_file_chunk_count_map
.iter()
.map(|(_, ChunkCount { free, .. })| *free)
.sum::<usize>();
if free_chunk_count != expected_free_chunk_count {
return Err(format!("{free_chunk_count} != {expected_free_chunk_count} \n Invalid BlockDB free chunk count"));
}
let used_chunk_count = block_db.used_chunk_count().await;
let expected_used_chunk_count = self
.data_file_chunk_count_map
.iter()
.map(|(_, ChunkCount { used, .. })| *used)
.sum::<usize>();
if used_chunk_count != expected_used_chunk_count {
return Err(format!("{used_chunk_count} != {expected_used_chunk_count} \n Invalid BlockDB used chunk count"));
}
let expected_data_file_count = block_db.data_files.read().await.len();
if self.data_file_count != expected_data_file_count {
return Err(format!(
"{} != {expected_data_file_count} \n Invalid DataFiles count",
self.data_file_count
));
}
let expected_block_db_byte_size = block_db.byte_size().await;
if self.block_db_byte_size != expected_block_db_byte_size {
return Err(format!(
"{:?} != {expected_block_db_byte_size:?} \n Invalid BlockDB ByteSize",
self.block_db_byte_size
));
}
for (data_file_id, data_file_byte_size) in self.data_file_byte_size_map.iter() {
let data_files = block_db.data_files.read().await;
let data_file = data_files.get(data_file_id).unwrap().clone();
let expected_data_file_byte_size = data_file.read().await.byte_size();
if data_file_byte_size != &expected_data_file_byte_size {
return Err(format!(
"{data_file_byte_size:?} != {expected_data_file_byte_size:?} \n Invalid DataFile {data_file_id} ByteSize"
));
}
}
for (data_file_id, ChunkCount { used, free }) in self.data_file_chunk_count_map.iter() {
let data_files = block_db.data_files.read().await;
let data_file = data_files.get(data_file_id).unwrap().clone();
let expected_used_chunk_count = data_file.read().await.used_chunk_count();
if *used != expected_used_chunk_count {
return Err(format!("{used} != {expected_used_chunk_count} \n Invalid DataFile {data_file_id} used chunk count"));
}
let expected_free_chunk_count = data_file.read().await.free_chunk_count();
if *free != expected_free_chunk_count {
return Err(format!("{free} != {expected_free_chunk_count} \n Invalid DataFile {data_file_id} free chunk count"));
}
}
Ok(())
}
}