new_tree_remove.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2026-2026 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. //! Simulate the creation of a [`DatabaseOverlay`] on top of an entire
  19. //! [`Database`] instance, generate a new tree that doesn't exist in
  20. //! the database, perform writes to verify overlay's cache
  21. //! functionality, and verify that scratching everything will not write
  22. //! the new tree.
  23. use kvdb_overlay::{Database, DatabaseOverlay, Result};
  24. const TREE: &str = "_tree";
  25. #[test]
  26. fn new_tree_remove() -> Result<()> {
  27. // Initialize database
  28. let (db, _folder) = Database::open_temp()?;
  29. // Initialize overlay
  30. let mut overlay = DatabaseOverlay::new(&db, vec![])?;
  31. // Open tree in the overlay
  32. overlay.open_tree_default(TREE, false)?;
  33. // We keep seperate tree for validation
  34. let tree = db.open_tree_default(TREE)?;
  35. // Insert some values to the overlay
  36. overlay.insert(TREE, b"key_a", b"val_a")?;
  37. overlay.insert(TREE, b"key_b", b"val_b")?;
  38. overlay.insert(TREE, b"key_c", b"val_c")?;
  39. // Verify they are in the overlay
  40. assert_eq!(overlay.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a");
  41. assert_eq!(overlay.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b");
  42. assert_eq!(overlay.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c");
  43. // Verify they are not in the database
  44. assert!(tree.get(b"key_a")?.is_none());
  45. assert!(tree.get(b"key_b")?.is_none());
  46. assert!(tree.get(b"key_c")?.is_none());
  47. // Now we asume something happened and want to scratch everything
  48. overlay.purge_new_trees()?;
  49. // Don't forget to flush
  50. db.flush_default_mode()?;
  51. // Verify the database doesn't contain the tree
  52. assert!(!db.tree_names()?.contains(&TREE.into()));
  53. Ok(())
  54. }
  55. #[test]
  56. fn new_tree_remove_multiple_overlays() -> Result<()> {
  57. // Initialize database
  58. let (db, _folder) = Database::open_temp()?;
  59. // Initialize overlays
  60. let mut overlay0 = DatabaseOverlay::new(&db, vec![])?;
  61. let mut overlay1 = DatabaseOverlay::new(&db, vec![])?;
  62. // Open tree in the overlays
  63. overlay0.open_tree_default(TREE, false)?;
  64. overlay1.open_tree_default(TREE, false)?;
  65. // We keep seperate tree for validation
  66. let tree = db.open_tree_default(TREE)?;
  67. // Insert some values to the overlays
  68. overlay0.insert(TREE, b"key_a", b"val_a")?;
  69. overlay0.insert(TREE, b"key_b", b"val_b")?;
  70. overlay0.insert(TREE, b"key_c", b"val_c")?;
  71. overlay1.insert(TREE, b"key_a", b"val_a")?;
  72. overlay1.insert(TREE, b"key_b", b"val_b")?;
  73. overlay1.insert(TREE, b"key_c", b"val_c")?;
  74. // Verify they are in the overlays
  75. assert_eq!(overlay0.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a");
  76. assert_eq!(overlay0.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b");
  77. assert_eq!(overlay0.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c");
  78. assert_eq!(overlay1.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a");
  79. assert_eq!(overlay1.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b");
  80. assert_eq!(overlay1.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c");
  81. // Verify they are not in the database
  82. assert!(tree.get(b"key_a")?.is_none());
  83. assert!(tree.get(b"key_b")?.is_none());
  84. assert!(tree.get(b"key_c")?.is_none());
  85. // Now we asume something happened and want to scratch everything
  86. // in overlay0
  87. overlay0.purge_new_trees()?;
  88. // Now execute all tree batches in the overlay1
  89. overlay1.apply()?;
  90. // Don't forget to flush
  91. db.flush_default_mode()?;
  92. // Verify the database contain the tree and the keys
  93. assert!(db.tree_names()?.contains(&TREE.into()));
  94. // We need to re-open the tree since we removed it when we
  95. // scratched overlay0 (overlay0.purge_new_trees())
  96. let tree = db.open_tree_default(TREE)?;
  97. assert_eq!(tree.get(b"key_a")?.unwrap().as_ref(), b"val_a");
  98. assert_eq!(tree.get(b"key_b")?.unwrap().as_ref(), b"val_b");
  99. assert_eq!(tree.get(b"key_c")?.unwrap().as_ref(), b"val_c");
  100. Ok(())
  101. }