database_overlay_checkpoint.rs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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, and perform checkpoints and writes to verify
  20. //! overlay's cache checkpoint functionality.
  21. use kvdb_overlay::{Database, DatabaseOverlay, Result};
  22. const TREE: &str = "_tree";
  23. const NEW_TREE: &str = "_new_tree";
  24. #[test]
  25. fn database_overlay_checkpoint() -> Result<()> {
  26. // Initialize database
  27. let (db, _folder) = Database::open_temp()?;
  28. // Initialize overlay
  29. let mut overlay = DatabaseOverlay::new(&db, vec![])?;
  30. // Open tree in the overlay
  31. overlay.open_tree_default(TREE, false)?;
  32. // We keep seperate trees for validation
  33. let tree = db.open_tree_default(TREE)?;
  34. // Insert some values to the overlay
  35. overlay.insert(TREE, b"key_a", b"val_a")?;
  36. overlay.insert(TREE, b"key_b", b"val_b")?;
  37. overlay.insert(TREE, b"key_c", b"val_c")?;
  38. // Verify they are in the overlay
  39. assert_eq!(overlay.get(TREE, b"key_a")?, Some(b"val_a".into()));
  40. assert_eq!(overlay.get(TREE, b"key_b")?, Some(b"val_b".into()));
  41. assert_eq!(overlay.get(TREE, b"key_c")?, Some(b"val_c".into()));
  42. // Verify they are not in the database
  43. assert_eq!(tree.get(b"key_a")?, None);
  44. assert_eq!(tree.get(b"key_b")?, None);
  45. assert_eq!(tree.get(b"key_c")?, None);
  46. // Now we create an overlay checkpoint
  47. overlay.checkpoint();
  48. // We add some more values to the overlay
  49. overlay.insert(TREE, b"key_d", b"val_d")?;
  50. overlay.insert(TREE, b"key_e", b"val_e")?;
  51. overlay.insert(TREE, b"key_f", b"val_f")?;
  52. // Verify they are in the overlay
  53. assert_eq!(overlay.get(TREE, b"key_d")?, Some(b"val_d".into()));
  54. assert_eq!(overlay.get(TREE, b"key_e")?, Some(b"val_e".into()));
  55. assert_eq!(overlay.get(TREE, b"key_f")?, Some(b"val_f".into()));
  56. // Verify they are not in the database
  57. assert_eq!(tree.get(b"key_d")?, None);
  58. assert_eq!(tree.get(b"key_e")?, None);
  59. assert_eq!(tree.get(b"key_f")?, None);
  60. // We also create a new tree
  61. overlay.open_tree_default(NEW_TREE, false)?;
  62. // We assume something went wrong, so we revert to last checkpoint
  63. overlay.revert_to_checkpoint();
  64. // And drop the new tree we created
  65. db.drop_tree(NEW_TREE)?;
  66. // Now execute all tree batches in the overlay
  67. overlay.apply()?;
  68. // Don't forget to flush
  69. db.flush_default_mode()?;
  70. // Verify the database contains pre-checkpoint keys
  71. assert_eq!(tree.get(b"key_a")?, Some(b"val_a".into()));
  72. assert_eq!(tree.get(b"key_b")?, Some(b"val_b".into()));
  73. assert_eq!(tree.get(b"key_c")?, Some(b"val_c".into()));
  74. // Verify the database doesn't contains keys after checkpoint
  75. assert_eq!(tree.get(b"key_d")?, None);
  76. assert_eq!(tree.get(b"key_e")?, None);
  77. assert_eq!(tree.get(b"key_f")?, None);
  78. // Verify the database doesn't contain the new tree we created
  79. // after checkpoint
  80. assert!(!db.tree_names()?.contains(&NEW_TREE.into()));
  81. Ok(())
  82. }