From 594f33d4a5d69af47d99b3c6df75d1d9f3675f5d Mon Sep 17 00:00:00 2001 From: Egor Ivkov <e.o.ivkov@gmail.com> Date: Thu, 4 May 2023 19:31:25 +0300 Subject: [PATCH] extensive dml tests --- src/traft/rpc/cas.rs | 113 +++++++++++++++++++++++++++++++++---------- test/int/test_cas.py | 29 +++++------ 2 files changed, 103 insertions(+), 39 deletions(-) diff --git a/src/traft/rpc/cas.rs b/src/traft/rpc/cas.rs index d969e3f338..b32e538b1f 100644 --- a/src/traft/rpc/cas.rs +++ b/src/traft/rpc/cas.rs @@ -1,5 +1,5 @@ +use crate::storage::TClusterwideSpace as _; use crate::storage::{ClusterwideSpace, Indexes, Properties, Spaces}; -use crate::storage::{PropertyName, TClusterwideSpace as _}; use crate::tlog; use crate::traft::error::Error as TraftError; use crate::traft::node; @@ -346,7 +346,7 @@ fn modifies_operable(op: &Op, space: &str, properties: &Properties) -> bool { Op::DdlPrepare { ddl, .. } => ddl_modifies(ddl), Op::DdlCommit | Op::DdlAbort => { if let Some(change) = properties - .get::<Ddl>(PropertyName::PendingSchemaChange) + .pending_schema_change() .expect("conversion should not fail") { ddl_modifies(&change) @@ -359,6 +359,7 @@ fn modifies_operable(op: &Op, space: &str, properties: &Properties) -> bool { } mod tests { + use serde::Serialize; use tarantool::tuple::ToTupleBuffer; use crate::storage::TClusterwideSpace as _; @@ -367,7 +368,7 @@ mod tests { use super::*; #[::tarantool::test] - fn check_ddl_predicate() { + fn ddl() { let clusterwide = Clusterwide::new().unwrap(); let predicate = Predicate { @@ -405,27 +406,46 @@ mod tests { } #[::tarantool::test] - fn check_bounds() { + fn dml() { + #[derive(Debug)] + enum TestOp { + Insert, + Replace, + Update, + Delete, + } + #[track_caller] - fn test(range: Range, test_cases: &[&str], storage: &Clusterwide) -> Vec<bool> { + fn test<T: Serialize>( + op: &TestOp, + range: &Range, + test_cases: &[T], + storage: &Clusterwide, + ) -> Vec<bool> { let predicate = Predicate { index: 1, term: 1, - ranges: vec![range], + ranges: vec![range.clone()], }; test_cases .iter() - .map(|&case| (String::from(case),).to_tuple_buffer().unwrap()) + .map(|case| (case,).to_tuple_buffer().unwrap()) .map(|key| { + let space = ClusterwideSpace::Property; + match op { + TestOp::Insert => Dml::Insert { space, tuple: key }, + TestOp::Replace => Dml::Replace { space, tuple: key }, + TestOp::Update => Dml::Update { + space, + key, + ops: vec![], + }, + TestOp::Delete => Dml::Delete { space, key }, + } + }) + .map(|op| { predicate - .check_entry( - 2, - &Op::Dml(Dml::Delete { - space: ClusterwideSpace::Property, - key, - }), - &storage.properties, - ) + .check_entry(2, &Op::Dml(op), &storage.properties) .is_err() }) .collect() @@ -434,6 +454,12 @@ mod tests { let storage = Clusterwide::new().unwrap(); let test_cases = ["a", "b", "c", "d", "e"]; + let ops = &[ + TestOp::Insert, + TestOp::Replace, + TestOp::Update, + TestOp::Delete, + ]; // For range ["b", "d"] // Test cases a,b,c,d,e @@ -443,8 +469,10 @@ mod tests { key_min: Bound::Included(("b",).to_tuple_buffer().unwrap()), key_max: Bound::Included(("d",).to_tuple_buffer().unwrap()), }; - let errors = test(range, &test_cases, &storage); - assert_eq!(errors, vec![false, true, true, true, false]); + for op in ops { + let errors = test(&op, &range, &test_cases, &storage); + assert_eq!(errors, vec![false, true, true, true, false], "{op:?}"); + } // For range ("b", "d"] // Test cases a,b,c,d,e @@ -454,8 +482,10 @@ mod tests { key_min: Bound::Excluded(("b",).to_tuple_buffer().unwrap()), key_max: Bound::Included(("d",).to_tuple_buffer().unwrap()), }; - let errors = test(range, &test_cases, &storage); - assert_eq!(errors, vec![false, false, true, true, false]); + for op in ops { + let errors = test(&op, &range, &test_cases, &storage); + assert_eq!(errors, vec![false, false, true, true, false], "{op:?}"); + } // For range ["b", "d") // Test cases a,b,c,d,e @@ -465,8 +495,10 @@ mod tests { key_min: Bound::Included(("b",).to_tuple_buffer().unwrap()), key_max: Bound::Excluded(("d",).to_tuple_buffer().unwrap()), }; - let errors = test(range, &test_cases, &storage); - assert_eq!(errors, vec![false, true, true, false, false]); + for op in ops { + let errors = test(&op, &range, &test_cases, &storage); + assert_eq!(errors, vec![false, true, true, false, false], "{op:?}"); + } // For range _, "d"] // Test cases a,b,c,d,e @@ -476,8 +508,10 @@ mod tests { key_min: Bound::Unbounded, key_max: Bound::Included(("d",).to_tuple_buffer().unwrap()), }; - let errors = test(range, &test_cases, &storage); - assert_eq!(errors, vec![true, true, true, true, false]); + for op in ops { + let errors = test(&op, &range, &test_cases, &storage); + assert_eq!(errors, vec![true, true, true, true, false], "{op:?}"); + } // For range ["b", _ // Test cases a,b,c,d,e @@ -487,7 +521,36 @@ mod tests { key_min: Bound::Included(("b",).to_tuple_buffer().unwrap()), key_max: Bound::Unbounded, }; - let errors = test(range, &test_cases, &storage); - assert_eq!(errors, vec![false, true, true, true, true]); + for op in ops { + let errors = test(&op, &range, &test_cases, &storage); + assert_eq!(errors, vec![false, true, true, true, true], "{op:?}"); + } + + // For range _, _ + // Test cases a,b,c,d,e + // Error 1,1,1,1,1 + let range = Range { + space: Properties::SPACE_NAME.into(), + key_min: Bound::Unbounded, + key_max: Bound::Unbounded, + }; + for op in ops { + let errors = test(&op, &range, &test_cases, &storage); + assert_eq!(errors, vec![true, true, true, true, true], "{op:?}"); + } + + // Different space + // For range _, _ + // Test cases a + // Error 0 + let range = Range { + space: Spaces::SPACE_NAME.into(), + key_min: Bound::Unbounded, + key_max: Bound::Unbounded, + }; + for op in ops { + let errors = test(&op, &range, &[1], &storage); + assert_eq!(errors, vec![false], "{op:?}"); + } } } diff --git a/test/int/test_cas.py b/test/int/test_cas.py index d73704bc09..4035042b22 100644 --- a/test/int/test_cas.py +++ b/test/int/test_cas.py @@ -82,21 +82,22 @@ def test_cas_errors(instance: Instance): ) # Prohibited spaces - with pytest.raises(TarantoolError) as e5: - instance.cas( - "insert", - "_picodata_space", - [0], - range=( - dict(kind="included", value=0), - dict(kind="included", value=0), - ), + for space in ["_picodata_space", "_picodata_index"]: + with pytest.raises(TarantoolError) as e5: + instance.cas( + "insert", + space, + [0], + range=( + dict(kind="included", value=0), + dict(kind="included", value=0), + ), + ) + assert e5.value.args == ( + "ER_PROC_C", + f"compare-and-swap request failed: space {space} is prohibited for use " + + "in a predicate", ) - assert e5.value.args == ( - "ER_PROC_C", - "compare-and-swap request failed: space _picodata_space is prohibited for use " - + "in a predicate", - ) def test_cas_predicate(instance: Instance): -- GitLab