use xpct::{be_empty, be_err, be_ok, contain_element, contain_elements, equal, expect, have_len};
use super::{BlockStoreTestExt, DataBlock};
use crate::{
block::{
store::BlockStore,
types::{Block, FileId},
},
errors::InternalError,
testing::MemoryBlockStore,
};
#[test]
fn list_blocks_when_file_does_not_exist() {
let store = MemoryBlockStore::new();
expect!(store.list_blocks(FileId::from(1)))
.to(be_err())
.to(equal(
InternalError::FileNotFound {
id: FileId::from(1),
}
.into(),
));
}
#[test]
fn insert_and_read_block() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: block_id,
bytes: expected_bytes,
signature: expected_signature,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let mut actual_bytes = Vec::new();
let read_block = expect!(store.read_block(block_id, &mut actual_bytes))
.to(be_ok())
.into_inner();
expect!(actual_bytes).to(equal(expected_bytes));
expect!(read_block.signature).to(equal(expected_signature));
}
#[test]
fn replace_single_block() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: initial_block_id,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let DataBlock {
id: new_block_id,
bytes: new_bytes,
signature: new_signature,
..
} = expect!(store.replace_data(file_id, 0))
.to(be_ok())
.into_inner();
expect!(new_block_id).to_not(equal(initial_block_id));
let mut actual_bytes = Vec::new();
let read_block = expect!(store.read_block(new_block_id, &mut actual_bytes))
.to(be_ok())
.into_inner();
expect!(actual_bytes).to(equal(new_bytes));
expect!(read_block.signature).to(equal(new_signature));
}
#[test]
fn append_block_to_end() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: first_block_id,
signature: first_signature,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let DataBlock {
id: second_block_id,
signature: second_signature,
..
} = expect!(store.insert_data(file_id, 1))
.to(be_ok())
.into_inner();
let block_list = expect!(store.list_blocks(file_id))
.to(be_ok())
.into_inner()
.into_iter()
.collect::<Vec<_>>();
expect!(&block_list).to(have_len(2));
expect!(block_list).to(contain_elements([
Block {
id: first_block_id,
signature: first_signature,
},
Block {
id: second_block_id,
signature: second_signature,
},
]));
}
#[test]
fn prepend_block_to_front() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: second_block_id,
signature: second_signature,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let DataBlock {
id: first_block_id,
signature: first_signature,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let block_list = expect!(store.list_blocks(file_id))
.to(be_ok())
.into_inner()
.into_iter()
.collect::<Vec<_>>();
expect!(&block_list).to(have_len(2));
expect!(block_list).to(contain_elements([
Block {
id: first_block_id,
signature: first_signature,
},
Block {
id: second_block_id,
signature: second_signature,
},
]));
}
#[test]
fn insert_block_in_middle() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: first_block_id,
signature: first_signature,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let DataBlock {
id: third_block_id,
signature: third_signature,
..
} = expect!(store.insert_data(file_id, 1))
.to(be_ok())
.into_inner();
let DataBlock {
id: second_block_id,
signature: second_signature,
..
} = expect!(store.insert_data(file_id, 1))
.to(be_ok())
.into_inner();
let block_list = expect!(store.list_blocks(file_id))
.to(be_ok())
.into_inner()
.into_iter()
.collect::<Vec<_>>();
expect!(&block_list).to(have_len(3));
expect!(block_list).to(contain_elements([
Block {
id: first_block_id,
signature: first_signature,
},
Block {
id: second_block_id,
signature: second_signature,
},
Block {
id: third_block_id,
signature: third_signature,
},
]));
}
#[test]
fn remove_single_block() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock { id: block_id, .. } = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let removed_block_ids = expect!(store.remove_blocks(file_id, 0..1))
.to(be_ok())
.into_inner();
expect!(&removed_block_ids).to(have_len(1));
expect!(removed_block_ids).to(contain_element(block_id));
let block_list = expect!(store.list_blocks(file_id))
.to(be_ok())
.into_inner()
.into_iter()
.collect::<Vec<_>>();
expect!(&block_list).to(be_empty());
}
#[test]
fn remove_all_blocks() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: first_block_id, ..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let DataBlock {
id: second_block_id,
..
} = expect!(store.insert_data(file_id, 1))
.to(be_ok())
.into_inner();
let removed_block_ids = expect!(store.remove_blocks(file_id, 0..2))
.to(be_ok())
.into_inner();
expect!(&removed_block_ids).to(have_len(2));
expect!(removed_block_ids).to(contain_elements([first_block_id, second_block_id]));
let block_list = expect!(store.list_blocks(file_id))
.to(be_ok())
.into_inner()
.into_iter()
.collect::<Vec<_>>();
expect!(&block_list).to(be_empty());
}
#[test]
fn remove_middle_block() {
let mut store = MemoryBlockStore::new();
let file_id = FileId::from(1);
let DataBlock {
id: first_block_id,
signature: first_block_signature,
..
} = expect!(store.insert_data(file_id, 0))
.to(be_ok())
.into_inner();
let DataBlock {
id: second_block_id,
..
} = expect!(store.insert_data(file_id, 1))
.to(be_ok())
.into_inner();
let DataBlock {
id: third_block_id,
signature: third_block_signature,
..
} = expect!(store.insert_data(file_id, 2))
.to(be_ok())
.into_inner();
let removed_block_ids = expect!(store.remove_blocks(file_id, 1..2))
.to(be_ok())
.into_inner();
expect!(&removed_block_ids).to(have_len(1));
expect!(removed_block_ids).to(contain_element(second_block_id));
let block_list = expect!(store.list_blocks(file_id))
.to(be_ok())
.into_inner()
.into_iter()
.collect::<Vec<_>>();
expect!(&block_list).to(have_len(2));
expect!(block_list).to(contain_elements([
Block {
id: first_block_id,
signature: first_block_signature,
},
Block {
id: third_block_id,
signature: third_block_signature,
},
]));
}