database_overlay_clone.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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 clone it to verify writes on the cloned
  20. //! overlay's cache do not affect the original one.
  21. use kvdb_overlay::{Database, DatabaseOverlay, Result};
  22. const TREE: &str = "_tree";
  23. #[test]
  24. fn database_overlay_clone() -> Result<()> {
  25. // Initialize database
  26. let (db, _folder) = Database::open_temp()?;
  27. // Initialize overlay
  28. let mut overlay = DatabaseOverlay::new(&db, vec![])?;
  29. // Open tree in the overlay
  30. overlay.open_tree_default(TREE, false)?;
  31. // Check overlay tree is empty
  32. assert!(overlay.is_empty(TREE)?);
  33. // Check last value is `None`
  34. assert_eq!(overlay.last(TREE)?, None);
  35. // We keep seperate tree for validation
  36. let tree = db.open_tree_default(TREE)?;
  37. // Insert some values to the overlay
  38. overlay.insert(TREE, b"key_a", b"val_a")?;
  39. overlay.insert(TREE, b"key_b", b"val_b")?;
  40. overlay.insert(TREE, b"key_c", b"val_c")?;
  41. // Verify they are in the overlay
  42. assert_eq!(overlay.get(TREE, b"key_a")?.unwrap().as_ref(), b"val_a");
  43. assert_eq!(overlay.get(TREE, b"key_b")?.unwrap().as_ref(), b"val_b");
  44. assert_eq!(overlay.get(TREE, b"key_c")?.unwrap().as_ref(), b"val_c");
  45. // Check overlay tree is not empty
  46. assert!(!overlay.is_empty(TREE)?);
  47. // Check its last value
  48. assert_eq!(
  49. overlay.last(TREE)?,
  50. Some((b"key_c".into(), b"val_c".into()))
  51. );
  52. // Verify they are not in the database
  53. assert!(tree.get(b"key_a")?.is_none());
  54. assert!(tree.get(b"key_b")?.is_none());
  55. assert!(tree.get(b"key_c")?.is_none());
  56. // Clone the overlay
  57. let mut overlay_clone = overlay.clone();
  58. // Check cloned overlay tree is not empty
  59. assert!(!overlay_clone.is_empty(TREE)?);
  60. // Check its last value
  61. assert_eq!(
  62. overlay_clone.last(TREE)?,
  63. Some((b"key_c".into(), b"val_c".into()))
  64. );
  65. // Insert some values to the cloned overlay
  66. overlay_clone.insert(TREE, b"key_d", b"val_d")?;
  67. overlay_clone.insert(TREE, b"key_e", b"val_e")?;
  68. overlay_clone.insert(TREE, b"key_f", b"val_f")?;
  69. // Verify all records are in the cloned overlay
  70. assert_eq!(
  71. overlay_clone.get(TREE, b"key_a")?.unwrap().as_ref(),
  72. b"val_a"
  73. );
  74. assert_eq!(
  75. overlay_clone.get(TREE, b"key_b")?.unwrap().as_ref(),
  76. b"val_b"
  77. );
  78. assert_eq!(
  79. overlay_clone.get(TREE, b"key_c")?.unwrap().as_ref(),
  80. b"val_c"
  81. );
  82. assert_eq!(
  83. overlay_clone.get(TREE, b"key_d")?.unwrap().as_ref(),
  84. b"val_d"
  85. );
  86. assert_eq!(
  87. overlay_clone.get(TREE, b"key_e")?.unwrap().as_ref(),
  88. b"val_e"
  89. );
  90. assert_eq!(
  91. overlay_clone.get(TREE, b"key_f")?.unwrap().as_ref(),
  92. b"val_f"
  93. );
  94. // Check its last values
  95. assert_eq!(
  96. overlay_clone.last(TREE)?,
  97. Some((b"key_f".into(), b"val_f".into()))
  98. );
  99. // Verify they are not in original overlay or the database
  100. assert!(tree.get(b"key_d")?.is_none());
  101. assert!(tree.get(b"key_e")?.is_none());
  102. assert!(tree.get(b"key_f")?.is_none());
  103. assert!(overlay.get(TREE, b"key_d")?.is_none());
  104. assert!(overlay.get(TREE, b"key_e")?.is_none());
  105. assert!(overlay.get(TREE, b"key_f")?.is_none());
  106. // We finished processing the cloned overlay, so we can
  107. // discard it and apply all tree baches of the original
  108. // overlay.
  109. overlay.apply()?;
  110. // Don't forget to flush
  111. db.flush_default_mode()?;
  112. // Verify the database contains keys
  113. assert_eq!(tree.get(b"key_a")?.unwrap().as_ref(), b"val_a");
  114. assert_eq!(tree.get(b"key_b")?.unwrap().as_ref(), b"val_b");
  115. assert_eq!(tree.get(b"key_c")?.unwrap().as_ref(), b"val_c");
  116. Ok(())
  117. }