From a5c7306b90f3055861c0728c385d3292a4268d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Moravec?= Date: Sun, 4 Feb 2024 20:48:10 +0100 Subject: [PATCH] tests: index testing --- storage_engine/src/index.rs | 172 ++++++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 18 deletions(-) diff --git a/storage_engine/src/index.rs b/storage_engine/src/index.rs index 3cb84d2..5d2187a 100644 --- a/storage_engine/src/index.rs +++ b/storage_engine/src/index.rs @@ -75,25 +75,10 @@ where self.data.entry(k).and_modify(|values| { values.remove(&v); }); - self.dump_to_file().await + self.sync_to_disk().await } pub async fn sync_to_disk(&mut self) -> Result<()> { - self.dump_to_file().await - } - - async fn append_to_file(&mut self, key: &K, value: &V) -> Result<()> { - let mut encoded = Vec::new(); - encoded.extend(encode(key)?); - encoded.extend(encode(value)?); - - self.file.seek(std::io::SeekFrom::End(0)).await?; - self.file.write(&encoded).await?; - - Ok(()) - } - - async fn dump_to_file(&mut self) -> Result<()> { let mut writer = BufWriter::new(&mut self.file); writer.seek(std::io::SeekFrom::Start(0)).await?; @@ -114,6 +99,17 @@ where Ok(()) } + async fn append_to_file(&mut self, key: &K, value: &V) -> Result<()> { + let mut encoded = Vec::new(); + encoded.extend(encode(key)?); + encoded.extend(encode(value)?); + + self.file.seek(std::io::SeekFrom::End(0)).await?; + self.file.write(&encoded).await?; + + Ok(()) + } + async fn load_from_file(&mut self) -> Result<()> { let mut bytes = vec![]; @@ -141,7 +137,147 @@ mod tests { use super::*; #[tokio::test] - async fn encode_decode() { - todo!(); + async fn connect_to_new() { + let file_name = PathBuf::from("connect_to_new"); + if file_name.exists() { + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + { + let index = Index::::new(file_name.clone()).await.unwrap(); + assert_eq!(index.data.len(), 0); + } + + { + let index = Index::::connect(file_name.clone()).await.unwrap(); + assert_eq!(index.data.len(), 0); + } + + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + #[tokio::test] + async fn inserting() { + let file_name = PathBuf::from("inserting"); + if file_name.exists() { + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + { + let mut index = Index::::new(file_name.clone()).await.unwrap(); + index.insert(1, 2).await.unwrap(); + index.insert(1, 3).await.unwrap(); + index.insert(1, 4).await.unwrap(); + index.insert(2, 3).await.unwrap(); + index.insert(2, 4).await.unwrap(); + index.insert(2, 5).await.unwrap(); + + assert_eq!(index.data.len(), 2); + assert_eq!(index.data.get(&1).unwrap().len(), 3); + assert_eq!(index.data.get(&2).unwrap().len(), 3); + } + + { + let index = Index::::connect(file_name.clone()).await.unwrap(); + assert_eq!(index.data.len(), 2); + assert_eq!(index.data.get(&1).unwrap().len(), 3); + assert_eq!(index.data.get(&2).unwrap().len(), 3); + } + + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + #[tokio::test] + async fn lookuping() { + let file_name = PathBuf::from("lookuping"); + if file_name.exists() { + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + { + let mut index = Index::::new(file_name.clone()).await.unwrap(); + index.insert(1, 2).await.unwrap(); + index.insert(1, 3).await.unwrap(); + index.insert(1, 4).await.unwrap(); + index.insert(2, 3).await.unwrap(); + index.insert(2, 4).await.unwrap(); + index.insert(2, 5).await.unwrap(); + + assert_eq!(index.lookup(&1).await.unwrap().unwrap().len(), 3); + assert_eq!(index.lookup(&2).await.unwrap().unwrap().len(), 3); + assert_eq!(index.lookup(&3).await.unwrap(), None); + + let first = index.lookup(&1).await.unwrap().unwrap(); + assert!(first.contains(&2)); + assert!(first.contains(&3)); + assert!(first.contains(&4)); + + let second = index.lookup(&2).await.unwrap().unwrap(); + assert!(second.contains(&3)); + assert!(second.contains(&4)); + assert!(second.contains(&5)); + } + + { + let index = Index::::connect(file_name.clone()).await.unwrap(); + assert_eq!(index.lookup(&1).await.unwrap().unwrap().len(), 3); + assert_eq!(index.lookup(&2).await.unwrap().unwrap().len(), 3); + assert_eq!(index.lookup(&3).await.unwrap(), None); + + let first = index.lookup(&1).await.unwrap().unwrap(); + assert!(first.contains(&2)); + assert!(first.contains(&3)); + assert!(first.contains(&4)); + + let second = index.lookup(&2).await.unwrap().unwrap(); + assert!(second.contains(&3)); + assert!(second.contains(&4)); + assert!(second.contains(&5)); + } + + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + #[tokio::test] + async fn deleting() { + let file_name = PathBuf::from("deleting"); + if file_name.exists() { + tokio::fs::remove_file(&file_name).await.unwrap(); + } + + { + let mut index = Index::::new(file_name.clone()).await.unwrap(); + index.insert(1, 2).await.unwrap(); + index.insert(1, 3).await.unwrap(); + index.insert(1, 4).await.unwrap(); + index.insert(2, 3).await.unwrap(); + index.insert(2, 4).await.unwrap(); + index.insert(2, 5).await.unwrap(); + + assert!(index.lookup(&1).await.unwrap().unwrap().contains(&2)); + index.delete(1, 2).await.unwrap(); + assert!(!index.lookup(&1).await.unwrap().unwrap().contains(&2)); + + assert!(index.lookup(&2).await.unwrap().unwrap().contains(&3)); + index.delete(2, 3).await.unwrap(); + assert!(!index.lookup(&2).await.unwrap().unwrap().contains(&3)); + } + + { + let mut index = Index::::connect(file_name.clone()).await.unwrap(); + + assert!(!index.lookup(&1).await.unwrap().unwrap().contains(&2)); + assert!(!index.lookup(&2).await.unwrap().unwrap().contains(&3)); + + assert!(index.lookup(&1).await.unwrap().unwrap().contains(&3)); + index.delete(1, 3).await.unwrap(); + assert!(!index.lookup(&1).await.unwrap().unwrap().contains(&3)); + + assert!(index.lookup(&1).await.unwrap().unwrap().contains(&4)); + assert!(index.lookup(&2).await.unwrap().unwrap().contains(&4)); + assert!(index.lookup(&2).await.unwrap().unwrap().contains(&5)); + } + + tokio::fs::remove_file(&file_name).await.unwrap(); } }