From b00b13182d013ebd5d3296b888e7929a927b42ad Mon Sep 17 00:00:00 2001 From: Evan Leis Date: Sat, 11 Apr 2026 19:28:51 +0800 Subject: [PATCH] Fix parallel tests. Running tests in parallel (default behavior) means that multiple tests will work with the /tmp/db file. This results in unpredicable test results. Using self-deleting tempdirs, we can work around this. Note that the WAL is automatically placed in the same directory as the db with a fixed name, so this temp directory actually creates a unique, safe place for the WAL file as well. --- Cargo.toml | 3 +++ src/btree.rs | 47 +++++++++++++++++++++-------------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 882d4da..612280d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,6 @@ path = "src/lib.rs" byteorder = "1.3.4" uuid = { version = "0.8", features = ["serde", "v4"] } memmap = "0.7.0" + +[dev-dependencies] +tempfile = { version = "3" } diff --git a/src/btree.rs b/src/btree.rs index f32f935..bfd6665 100644 --- a/src/btree.rs +++ b/src/btree.rs @@ -415,18 +415,16 @@ impl BTree { #[cfg(test)] mod tests { + use crate::btree::{BTree, BTreeBuilder}; use crate::error::Error; + use tempfile::TempDir; #[test] fn search_works() -> Result<(), Error> { - use crate::btree::BTreeBuilder; use crate::node_type::KeyValuePair; - use std::path::Path; - let mut btree = BTreeBuilder::new() - .path(Path::new("/tmp/db")) - .b_parameter(2) - .build()?; + let dir = tempfile::tempdir()?; // Deleted on drop. + let mut btree = create_temp_btree(dir)?; btree.insert(KeyValuePair::new("a".to_string(), "shalom".to_string()))?; btree.insert(KeyValuePair::new("b".to_string(), "hello".to_string()))?; btree.insert(KeyValuePair::new("c".to_string(), "marhaba".to_string()))?; @@ -444,14 +442,10 @@ mod tests { #[test] fn insert_works() -> Result<(), Error> { - use crate::btree::BTreeBuilder; use crate::node_type::KeyValuePair; - use std::path::Path; - let mut btree = BTreeBuilder::new() - .path(Path::new("/tmp/db")) - .b_parameter(2) - .build()?; + let dir = tempfile::tempdir()?; // Deleted on drop. + let mut btree = create_temp_btree(dir)?; btree.insert(KeyValuePair::new("a".to_string(), "shalom".to_string()))?; btree.insert(KeyValuePair::new("b".to_string(), "hello".to_string()))?; btree.insert(KeyValuePair::new("c".to_string(), "marhaba".to_string()))?; @@ -502,15 +496,11 @@ mod tests { #[test] fn delete_works() -> Result<(), Error> { - use crate::btree::BTreeBuilder; use crate::error::Error; use crate::node_type::{Key, KeyValuePair}; - use std::path::Path; - let mut btree = BTreeBuilder::new() - .path(Path::new("/tmp/db")) - .b_parameter(2) - .build()?; + let dir = tempfile::tempdir()?; // Deleted on drop. + let mut btree = create_temp_btree(dir)?; btree.insert(KeyValuePair::new("d".to_string(), "olah".to_string()))?; btree.insert(KeyValuePair::new("e".to_string(), "salam".to_string()))?; btree.insert(KeyValuePair::new("f".to_string(), "hallo".to_string()))?; @@ -547,14 +537,10 @@ mod tests { #[test] fn delete_with_empty_sub_tree() -> Result<(), Error> { - use crate::btree::BTreeBuilder; use crate::node_type::{Key, KeyValuePair}; - use std::path::Path; - let mut btree = BTreeBuilder::new() - .path(Path::new("/tmp/db")) - .b_parameter(2) - .build()?; + let dir = tempfile::tempdir()?; // Deleted on drop. + let mut btree = create_temp_btree(dir)?; btree.insert(KeyValuePair::new("a".to_string(), "shalom".to_string()))?; btree.insert(KeyValuePair::new("b".to_string(), "hello".to_string()))?; btree.insert(KeyValuePair::new("c".to_string(), "marhaba".to_string()))?; @@ -576,11 +562,11 @@ mod tests { btree.delete(Key("a".to_string()))?; res = btree.search("a".to_string()); assert!(matches!(res, Err(Error::KeyNotFound))); - + btree.delete(Key("b".to_string()))?; res = btree.search("b".to_string()); assert!(matches!(res, Err(Error::KeyNotFound))); - + btree.delete(Key("c".to_string()))?; res = btree.search("c".to_string()); assert!(matches!(res, Err(Error::KeyNotFound))); @@ -594,4 +580,13 @@ mod tests { assert!(matches!(res, Err(Error::KeyNotFound))); Ok(()) } + + fn create_temp_btree(dir: TempDir) -> Result { + let db_path = dir.path().join("db"); + let btree = BTreeBuilder::new() + .path(Box::leak(db_path.into_boxed_path())) + .b_parameter(2) + .build()?; + Ok(btree) + } }