| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /* 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 <https://www.gnu.org/licenses/>.
- */
- //! 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")?, Some(b"val_a".into()));
- assert_eq!(overlay.get(TREE, b"key_b")?, Some(b"val_b".into()));
- assert_eq!(overlay.get(TREE, b"key_c")?, Some(b"val_c".into()));
- // Verify they are not in the database
- assert_eq!(tree.get(b"key_a")?, None);
- assert_eq!(tree.get(b"key_b")?, None);
- assert_eq!(tree.get(b"key_c")?, 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")?, Some(b"val_a".into()));
- assert_eq!(overlay0.get(TREE, b"key_b")?, Some(b"val_b".into()));
- assert_eq!(overlay0.get(TREE, b"key_c")?, Some(b"val_c".into()));
- assert_eq!(overlay1.get(TREE, b"key_a")?, Some(b"val_a".into()));
- assert_eq!(overlay1.get(TREE, b"key_b")?, Some(b"val_b".into()));
- assert_eq!(overlay1.get(TREE, b"key_c")?, Some(b"val_c".into()));
- // Verify they are not in the database
- assert_eq!(tree.get(b"key_a")?, None);
- assert_eq!(tree.get(b"key_b")?, None);
- assert_eq!(tree.get(b"key_c")?, 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")?, Some(b"val_a".into()));
- assert_eq!(tree.get(b"key_b")?, Some(b"val_b".into()));
- assert_eq!(tree.get(b"key_c")?, Some(b"val_c".into()));
- Ok(())
- }
|