Skip to content

Commit

Permalink
add insertion tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fominok committed Feb 13, 2025
1 parent f88534c commit c313e25
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 125 deletions.
126 changes: 2 additions & 124 deletions grovedb/src/operations/delete/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,12 +589,10 @@ mod tests {
use pretty_assertions::assert_eq;

use crate::{
bidirectional_references::BidirectionalReference,
operations::delete::{delete_up_tree::DeleteUpTreeOptions, ClearOptions, DeleteOptions},
reference_path::ReferencePathType,
tests::{
common::EMPTY_PATH, make_deep_tree, make_test_grovedb, TempGroveDb, ANOTHER_TEST_LEAF,
TEST_LEAF,
common::{make_tree_with_bidi_references, EMPTY_PATH},
make_test_grovedb, ANOTHER_TEST_LEAF, TEST_LEAF,
},
Element, Error,
};
Expand Down Expand Up @@ -1316,126 +1314,6 @@ mod tests {
assert_ne!(root_hash_before_clear, root_hash_after_clear);
}

fn make_tree_with_bidi_references(version: &GroveVersion) -> TempGroveDb {
let db = make_deep_tree(&version);

let transaction = db.start_transaction();

// Let's say we're deleting `deep_leaf` with an existing references chain
// that goes like
// test_leaf/innertree:ref -> another_test_leaf/innertree2:ref2 ->
// -> deep_leaf/deep_node_1/deeper_1:ref3 ->
// -> deep_leaf/deep_node_2/deeper_3:ref4 ->
// -> deep_leaf/deep_node_1/deeper_2:key5
//

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_1", b"deeper_2"],
b"key5",
Element::new_item_allowing_bidirectional_references(b"hello".to_vec()),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_2", b"deeper_3"],
b"ref4",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::UpstreamRootHeightReference(
1,
vec![
b"deep_node_1".to_vec(),
b"deeper_2".to_vec(),
b"key5".to_vec(),
],
),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_1", b"deeper_1"],
b"ref3",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::UpstreamRootHeightReference(
1,
vec![
b"deep_node_2".to_vec(),
b"deeper_3".to_vec(),
b"ref4".to_vec(),
],
),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[ANOTHER_TEST_LEAF, b"innertree2"],
b"ref2",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::AbsolutePathReference(vec![
b"deep_leaf".to_vec(),
b"deep_node_1".to_vec(),
b"deeper_1".to_vec(),
b"ref3".to_vec(),
]),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[TEST_LEAF, b"innertree"],
b"ref",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::AbsolutePathReference(vec![
ANOTHER_TEST_LEAF.to_vec(),
b"innertree2".to_vec(),
b"ref2".to_vec(),
]),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.commit_transaction(transaction).unwrap().unwrap();

db
}

#[test]
fn delete_item_with_backward_references() {
// Deletion of an item with backward references shall trigger cascade
Expand Down
88 changes: 87 additions & 1 deletion grovedb/src/operations/insert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,12 +466,16 @@ mod tests {
storage_cost::{removal::StorageRemovedBytes::NoStorageRemoval, StorageCost},
OperationCost,
};
use grovedb_path::SubtreePath;
use grovedb_version::version::GroveVersion;
use pretty_assertions::assert_eq;

use crate::{
operations::insert::InsertOptions,
tests::{common::EMPTY_PATH, make_empty_grovedb, make_test_grovedb, TEST_LEAF},
tests::{
common::{make_tree_with_bidi_references, EMPTY_PATH},
make_empty_grovedb, make_test_grovedb, TEST_LEAF,
},
Element, Error,
};

Expand Down Expand Up @@ -2187,4 +2191,86 @@ mod tests {
}
);
}

#[test]
fn update_item_with_backward_references() {
let version = GroveVersion::latest();

let db = make_tree_with_bidi_references(version);

let transaction = db.start_transaction();

let get_hash = || {
Element::get_value_hash(
&db.open_transactional_merk_at_path(
SubtreePath::from(&[TEST_LEAF, b"innertree"]),
&transaction,
None,
version,
)
.unwrap()
.unwrap(),
b"ref",
true,
version,
)
.unwrap()
.unwrap()
.unwrap()
};

let hash_before = get_hash();

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_1", b"deeper_2"],
b"key5",
Element::new_item_allowing_bidirectional_references(b"certainly new value".to_vec()),
Some(InsertOptions {
propagate_backward_references: true,
..Default::default()
}),
None,
version,
)
.unwrap()
.unwrap();

let hash_after = get_hash();

assert_ne!(hash_before, hash_after);
}

#[test]
fn update_item_with_backward_references_with_no_support() {
let version = GroveVersion::latest();

let db = make_tree_with_bidi_references(version);

let transaction = db.start_transaction();

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_1", b"deeper_2"],
b"key5",
Element::new_item(b"hello".to_vec()),
Some(InsertOptions {
propagate_backward_references: true,
..Default::default()
}),
None,
version,
)
.unwrap()
.unwrap();

assert!(matches!(
db.get(
&[TEST_LEAF, b"innertree"],
b"ref",
Some(&transaction),
version
)
.unwrap(),
Err(Error::PathKeyNotFound(_))
));
}
}
124 changes: 124 additions & 0 deletions grovedb/src/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
use grovedb_path::SubtreePath;
use grovedb_version::version::GroveVersion;

use super::{
make_deep_tree, reference_path::ReferencePathType, BidirectionalReference, TempGroveDb,
ANOTHER_TEST_LEAF, TEST_LEAF,
};
use crate::{operations::proof::util::ProvedPathKeyValues, Element, Error};

/// Compare result tuples
Expand Down Expand Up @@ -35,4 +39,124 @@ pub fn compare_result_sets(elements: &Vec<Vec<u8>>, result_set: &ProvedPathKeyVa
}
}

pub(crate) fn make_tree_with_bidi_references(version: &GroveVersion) -> TempGroveDb {
let db = make_deep_tree(&version);

let transaction = db.start_transaction();

// Let's say we're deleting `deep_leaf` with an existing references chain
// that goes like
// test_leaf/innertree:ref -> another_test_leaf/innertree2:ref2 ->
// -> deep_leaf/deep_node_1/deeper_1:ref3 ->
// -> deep_leaf/deep_node_2/deeper_3:ref4 ->
// -> deep_leaf/deep_node_1/deeper_2:key5
//

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_1", b"deeper_2"],
b"key5",
Element::new_item_allowing_bidirectional_references(b"hello".to_vec()),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_2", b"deeper_3"],
b"ref4",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::UpstreamRootHeightReference(
1,
vec![
b"deep_node_1".to_vec(),
b"deeper_2".to_vec(),
b"key5".to_vec(),
],
),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[b"deep_leaf".as_ref(), b"deep_node_1", b"deeper_1"],
b"ref3",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::UpstreamRootHeightReference(
1,
vec![
b"deep_node_2".to_vec(),
b"deeper_3".to_vec(),
b"ref4".to_vec(),
],
),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[ANOTHER_TEST_LEAF, b"innertree2"],
b"ref2",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::AbsolutePathReference(vec![
b"deep_leaf".to_vec(),
b"deep_node_1".to_vec(),
b"deeper_1".to_vec(),
b"ref3".to_vec(),
]),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.insert(
&[TEST_LEAF, b"innertree"],
b"ref",
Element::BidirectionalReference(BidirectionalReference {
forward_reference_path: ReferencePathType::AbsolutePathReference(vec![
ANOTHER_TEST_LEAF.to_vec(),
b"innertree2".to_vec(),
b"ref2".to_vec(),
]),
backward_reference_slot: 0,
cascade_on_update: true,
max_hop: None,
flags: None,
}),
None,
Some(&transaction),
version,
)
.unwrap()
.unwrap();

db.commit_transaction(transaction).unwrap().unwrap();

db
}

pub(crate) const EMPTY_PATH: SubtreePath<'static, [u8; 0]> = SubtreePath::empty();

0 comments on commit c313e25

Please sign in to comment.