tests
This commit is contained in:
parent
b13d2f04cd
commit
61de195658
1 changed files with 338 additions and 0 deletions
|
|
@ -202,3 +202,341 @@ impl <T>Store<T> {
|
||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::segments::entry::{Entry, EntryDetailed};
|
||||||
|
use crate::cursor::{ReadCursor, WriteCursor, CursorWithStoreHeader, CursorWithWriteAccessToIndex, CursorWithAccessToIndex};
|
||||||
|
|
||||||
|
impl <T>Drop for Store<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("DROPPING TEST FOLDER");
|
||||||
|
let table_folder = self.header.table_folder.clone();
|
||||||
|
// Seems no one has figured out how to do AsyncDrop yet.
|
||||||
|
std::fs::remove_dir_all(table_folder).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_create() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_0";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.number_of_columns == number_of_columns);
|
||||||
|
assert!(store.header.total_count == 0);
|
||||||
|
assert!(store.header.deleted_count == 0);
|
||||||
|
assert!(store.header.primary_column == primary_column);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_insert() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_1";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, 2, 3, 4, 5]);
|
||||||
|
cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_select_next() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_2";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, 2, 3, 4, 5]);
|
||||||
|
cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.read_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0 = cursor.next().await.unwrap().unwrap();
|
||||||
|
let entry1 = cursor.next().await.unwrap().unwrap();
|
||||||
|
|
||||||
|
assert!(entry0.data == vec![1,2,3,4,5]);
|
||||||
|
assert!(entry1.data == vec![6,7,8,9,10]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_select_all() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_3";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, 2, 3, 4, 5]);
|
||||||
|
cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.read_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let mut entries = vec![];
|
||||||
|
while let Some(entry) = cursor.next().await.unwrap() {
|
||||||
|
entries.push(entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(entries.len() == 2);
|
||||||
|
assert!(entries[0].data == vec![1,2,3,4,5]);
|
||||||
|
assert!(entries[1].data == vec![6,7,8,9,10]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_select_eq() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_4";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
let value = 200;
|
||||||
|
{
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, value, 3, 4, 5]);
|
||||||
|
cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
let entry2: Entry<Data> = Entry::new(vec![11, 2, 10, 10, 10]);
|
||||||
|
cursor.insert_entry(entry2).await.unwrap();
|
||||||
|
|
||||||
|
let entry3: Entry<Data> = Entry::new(vec![1, value, 100, 50, 40]);
|
||||||
|
cursor.insert_entry(entry3).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.read_cursor().await.unwrap();
|
||||||
|
let column = 1;
|
||||||
|
|
||||||
|
let entries = cursor.select_entries_where_eq(column, &value).await.unwrap();
|
||||||
|
|
||||||
|
assert!(entries.len() == 2);
|
||||||
|
assert!(entries[0].data == vec![1, value, 3, 4, 5]);
|
||||||
|
assert!(entries[1].data == vec![1, value, 100, 50, 40]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_select_eq_indexed() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_5";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
let column: Column = 1;
|
||||||
|
|
||||||
|
assert!(store.indexes[column as usize].is_none());
|
||||||
|
store.attach_index(column).await.unwrap();
|
||||||
|
assert!(store.indexes[column as usize].is_some());
|
||||||
|
|
||||||
|
let value = 200;
|
||||||
|
{
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, value, 3, 4, 5]);
|
||||||
|
cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
let entry2: Entry<Data> = Entry::new(vec![11, 2, 10, 10, 10]);
|
||||||
|
cursor.insert_entry(entry2).await.unwrap();
|
||||||
|
|
||||||
|
let entry3: Entry<Data> = Entry::new(vec![1, value, 100, 50, 40]);
|
||||||
|
cursor.insert_entry(entry3).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cursor = store.read_cursor().await.unwrap();
|
||||||
|
let column = 1;
|
||||||
|
|
||||||
|
let entries = cursor.select_entries_where_eq(column, &value).await.unwrap();
|
||||||
|
assert!(entries.len() == 2);
|
||||||
|
// Order may be non-deterministic.
|
||||||
|
assert!(entries[0].data[column as usize] == value);
|
||||||
|
assert!(entries[1].data[column as usize] == value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_delete_entry() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_6";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
let value = 200;
|
||||||
|
let (_file_position0, file_position1, _file_position2, _file_position3) = {
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, value, 3, 4, 5]);
|
||||||
|
let file_position0 = cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
let file_position1 = cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
let entry2: Entry<Data> = Entry::new(vec![11, 2, 10, 10, 10]);
|
||||||
|
let file_position2 = cursor.insert_entry(entry2).await.unwrap();
|
||||||
|
|
||||||
|
let entry3: Entry<Data> = Entry::new(vec![1, value, 100, 50, 40]);
|
||||||
|
let file_position3 = cursor.insert_entry(entry3).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 4);
|
||||||
|
(file_position0, file_position1, file_position2, file_position3)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
assert!(store.header.deleted_count == 0);
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
cursor.mark_deleted_at(file_position1, false).await.unwrap();
|
||||||
|
assert!(store.header.deleted_count == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_delete_where_eq() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_7";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
let column: Column = 1;
|
||||||
|
|
||||||
|
assert!(store.indexes[column as usize].is_none());
|
||||||
|
store.attach_index(column).await.unwrap();
|
||||||
|
assert!(store.indexes[column as usize].is_some());
|
||||||
|
|
||||||
|
let value = 200;
|
||||||
|
|
||||||
|
let (_file_position0, _file_position1, _file_position2, _file_position3) = {
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, value, 3, 4, 5]);
|
||||||
|
let file_position0 = cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
let file_position1 = cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
let entry2: Entry<Data> = Entry::new(vec![11, 2, 10, 10, 10]);
|
||||||
|
let file_position2 = cursor.insert_entry(entry2).await.unwrap();
|
||||||
|
|
||||||
|
let entry3: Entry<Data> = Entry::new(vec![1, value, 100, 50, 40]);
|
||||||
|
let file_position3 = cursor.insert_entry(entry3).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 4);
|
||||||
|
(file_position0, file_position1, file_position2, file_position3)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
assert!(store.header.deleted_count == 0);
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
cursor.delete_entries_where_eq(column, &value, false).await.unwrap();
|
||||||
|
assert!(store.header.deleted_count == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_garbage_collection() {
|
||||||
|
type Data = u32;
|
||||||
|
|
||||||
|
let table_path = "test_table_8";
|
||||||
|
let number_of_columns = 5;
|
||||||
|
let primary_column = 0;
|
||||||
|
let mut store: Store<Data> = Store::new(table_path, number_of_columns, primary_column).await.unwrap();
|
||||||
|
|
||||||
|
let column: Column = 1;
|
||||||
|
|
||||||
|
assert!(store.indexes[column as usize].is_none());
|
||||||
|
store.attach_index(column).await.unwrap();
|
||||||
|
assert!(store.indexes[column as usize].is_some());
|
||||||
|
|
||||||
|
let value = 200;
|
||||||
|
|
||||||
|
let (_file_position0, _file_position1, _file_position2, _file_position3) = {
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
|
||||||
|
let entry0: Entry<Data> = Entry::new(vec![1, value, 3, 4, 5]);
|
||||||
|
let file_position0 = cursor.insert_entry(entry0).await.unwrap();
|
||||||
|
|
||||||
|
let entry1: Entry<Data> = Entry::new(vec![6, 7, 8, 9, 10]);
|
||||||
|
let file_position1 = cursor.insert_entry(entry1).await.unwrap();
|
||||||
|
|
||||||
|
let entry2: Entry<Data> = Entry::new(vec![11, 2, 10, 10, 10]);
|
||||||
|
let file_position2 = cursor.insert_entry(entry2).await.unwrap();
|
||||||
|
|
||||||
|
let entry3: Entry<Data> = Entry::new(vec![1, value, 100, 50, 40]);
|
||||||
|
let file_position3 = cursor.insert_entry(entry3).await.unwrap();
|
||||||
|
|
||||||
|
assert!(store.header.total_count == 4);
|
||||||
|
(file_position0, file_position1, file_position2, file_position3)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
assert!(store.header.deleted_count == 0);
|
||||||
|
let mut cursor = store.write_cursor().await.unwrap();
|
||||||
|
cursor.delete_entries_where_eq(column, &value, false).await.unwrap();
|
||||||
|
assert!(cursor.header().deleted_count == 2);
|
||||||
|
assert!(cursor.header().total_count == 4);
|
||||||
|
|
||||||
|
cursor.initiate_garbage_collection().await.unwrap();
|
||||||
|
assert!(cursor.header().deleted_count == 0);
|
||||||
|
assert!(cursor.header().total_count == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue