/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2026-2026 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ //! Simulate the creation of a [`DatabaseOverlay`] on top of an entire //! [`Database`] instance, generate a new tree that doesn't exist in //! the database, perform writes to verify overlay's cache //! functionality, and verify that scratching everything will not write //! the new tree. use kvdb_overlay::{Database, DatabaseOverlay, Result}; const TREE: &str = "_tree"; #[test] fn new_tree_remove() -> Result<()> { // Initialize database let (db, _folder) = Database::open_temp()?; // Initialize overlay let mut overlay = DatabaseOverlay::new(&db, vec![])?; // Open tree in the overlay overlay.open_tree_default(TREE, false)?; // We keep seperate tree for validation let tree = db.open_tree_default(TREE)?; // Insert some values to the overlay overlay.insert(TREE, b"key_a", b"val_a")?; overlay.insert(TREE, b"key_b", b"val_b")?; overlay.insert(TREE, b"key_c", b"val_c")?; // Verify they are in the overlay assert_eq!(overlay.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a"); assert_eq!(overlay.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b"); assert_eq!(overlay.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c"); // Verify they are not in the database assert!(tree.get(b"key_a")?.is_none()); assert!(tree.get(b"key_b")?.is_none()); assert!(tree.get(b"key_c")?.is_none()); // Now we asume something happened and want to scratch everything overlay.purge_new_trees()?; // Don't forget to flush db.flush_default_mode()?; // Verify the database doesn't contain the tree assert!(!db.tree_names()?.contains(&TREE.into())); Ok(()) } #[test] fn new_tree_remove_multiple_overlays() -> Result<()> { // Initialize database let (db, _folder) = Database::open_temp()?; // Initialize overlays let mut overlay0 = DatabaseOverlay::new(&db, vec![])?; let mut overlay1 = DatabaseOverlay::new(&db, vec![])?; // Open tree in the overlays overlay0.open_tree_default(TREE, false)?; overlay1.open_tree_default(TREE, false)?; // We keep seperate tree for validation let tree = db.open_tree_default(TREE)?; // Insert some values to the overlays overlay0.insert(TREE, b"key_a", b"val_a")?; overlay0.insert(TREE, b"key_b", b"val_b")?; overlay0.insert(TREE, b"key_c", b"val_c")?; overlay1.insert(TREE, b"key_a", b"val_a")?; overlay1.insert(TREE, b"key_b", b"val_b")?; overlay1.insert(TREE, b"key_c", b"val_c")?; // Verify they are in the overlays assert_eq!(overlay0.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a"); assert_eq!(overlay0.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b"); assert_eq!(overlay0.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c"); assert_eq!(overlay1.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a"); assert_eq!(overlay1.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b"); assert_eq!(overlay1.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c"); // Verify they are not in the database assert!(tree.get(b"key_a")?.is_none()); assert!(tree.get(b"key_b")?.is_none()); assert!(tree.get(b"key_c")?.is_none()); // Now we asume something happened and want to scratch everything // in overlay0 overlay0.purge_new_trees()?; // Now execute all tree batches in the overlay1 overlay1.apply()?; // Don't forget to flush db.flush_default_mode()?; // Verify the database contain the tree and the keys assert!(db.tree_names()?.contains(&TREE.into())); // We need to re-open the tree since we removed it when we // scratched overlay0 (overlay0.purge_new_trees()) let tree = db.open_tree_default(TREE)?; assert_eq!(tree.get(b"key_a")?.unwrap().as_ref(), b"val_a"); assert_eq!(tree.get(b"key_b")?.unwrap().as_ref(), b"val_b"); assert_eq!(tree.get(b"key_c")?.unwrap().as_ref(), b"val_c"); Ok(()) }