From a7adcb01ba9923ceada833e160107ba9ba3737e6 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Wed, 13 Jun 2018 12:35:42 +0300 Subject: [PATCH] Unit test for 2PC where rollback is done immediately after after_prepare() --- test/transaction_context_test_2pc.cpp | 91 +++++++++++---------------- 1 file changed, 35 insertions(+), 56 deletions(-) diff --git a/test/transaction_context_test_2pc.cpp b/test/transaction_context_test_2pc.cpp index 50d1698..ce81f78 100644 --- a/test/transaction_context_test_2pc.cpp +++ b/test/transaction_context_test_2pc.cpp @@ -4,42 +4,27 @@ #include "client_context_fixture.hpp" - - // // Test a succesful 2PC transaction lifecycle // BOOST_FIXTURE_TEST_CASE(transaction_context_2pc, replicating_client_fixture_sync_rm) { - // Start a new transaction with ID 1 cc.start_transaction(1); BOOST_REQUIRE(tc.active()); BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); - - // Run before prepare BOOST_REQUIRE(cc.before_prepare() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_preparing); - - // Run after prepare BOOST_REQUIRE(cc.after_prepare() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committing); - - // Run before commit BOOST_REQUIRE(cc.before_commit() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committing); - - // Run ordered commit BOOST_REQUIRE(cc.ordered_commit() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_ordered_commit); - - // Run after commit BOOST_REQUIRE(cc.after_commit() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committed); - - // Cleanup after statement - cc.after_statement(); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_success); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(tc.ordered() == false); BOOST_REQUIRE(tc.certified() == false); @@ -53,28 +38,20 @@ BOOST_FIXTURE_TEST_CASE( transaction_context_2pc_bf_before_before_prepare, replicating_client_fixture_sync_rm) { - // Start a new transaction with ID 1 cc.start_transaction(1); BOOST_REQUIRE(tc.active()); BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); - wsrep_test::bf_abort_unordered(cc); - - // Run before commit BOOST_REQUIRE(cc.before_prepare()); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_abort); BOOST_REQUIRE(tc.certified() == false); BOOST_REQUIRE(tc.ordered() == false); - - // Rollback sequence BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_aborting); BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_aborted); - - // Cleanup after statement - cc.after_statement(); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_error); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(tc.ordered() == false); BOOST_REQUIRE(tc.certified() == false); @@ -88,38 +65,56 @@ BOOST_FIXTURE_TEST_CASE( transaction_context_2pc_bf_before_after_prepare, replicating_client_fixture_sync_rm) { - // Start a new transaction with ID 1 cc.start_transaction(1); BOOST_REQUIRE(tc.active()); BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); - - // Run before prepare BOOST_REQUIRE(cc.before_prepare() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_preparing); - wsrep_test::bf_abort_unordered(cc); - - // Run before commit BOOST_REQUIRE(cc.after_prepare()); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_abort); BOOST_REQUIRE(tc.certified() == false); BOOST_REQUIRE(tc.ordered() == false); - - // Rollback sequence BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_aborting); BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_aborted); - - // Cleanup after statement - cc.after_statement(); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_error); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(tc.ordered() == false); BOOST_REQUIRE(tc.certified() == false); BOOST_REQUIRE(cc.current_error()); } +// +// Test a 2PC transaction which gets BF aborted after_prepare() and +// the rollback takes place before entering before_commit(). +// +BOOST_FIXTURE_TEST_CASE( + transaction_context_2pc_bf_after_after_prepare, + replicating_client_fixture_sync_rm) +{ + cc.start_transaction(1); + BOOST_REQUIRE(tc.active()); + BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); + BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); + BOOST_REQUIRE(cc.before_prepare() == 0); + BOOST_REQUIRE(cc.after_prepare() == 0); + BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committing); + wsrep_test::bf_abort_ordered(cc); + BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_abort); + BOOST_REQUIRE(cc.before_rollback() == 0); + BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); + BOOST_REQUIRE(cc.after_rollback() == 0); + BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_success); + BOOST_REQUIRE(tc.active() == false); + BOOST_REQUIRE(tc.ordered() == false); + BOOST_REQUIRE(tc.certified() == false); + BOOST_REQUIRE(cc.current_error() == wsrep::e_success); +} + // // Test a 2PC transaction which gets BF aborted between after_prepare() // and before_commit() @@ -128,37 +123,31 @@ BOOST_FIXTURE_TEST_CASE( transaction_context_2pc_bf_before_before_commit, replicating_client_fixture_sync_rm) { - // Start a new transaction with ID 1 cc.start_transaction(1); BOOST_REQUIRE(tc.active()); BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); - BOOST_REQUIRE(cc.before_prepare() == 0); BOOST_REQUIRE(cc.after_prepare() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committing); wsrep_test::bf_abort_ordered(cc); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_abort); - // Run before commit BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); BOOST_REQUIRE(tc.certified() == true); BOOST_REQUIRE(tc.ordered() == true); - - // Rollback sequence BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); - - // Cleanup after statement - cc.after_statement(); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_success); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(tc.ordered() == false); BOOST_REQUIRE(tc.certified() == false); BOOST_REQUIRE(cc.current_error() == wsrep::e_success); } + // // Test a 2PC transaction which gets BF aborted when trying to grab // commit order. @@ -167,32 +156,23 @@ BOOST_FIXTURE_TEST_CASE( transaction_context_2pc_bf_during_commit_order_enter, replicating_client_fixture_sync_rm) { - // Start a new transaction with ID 1 cc.start_transaction(1); BOOST_REQUIRE(tc.active()); BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); - BOOST_REQUIRE(cc.before_prepare() == 0); BOOST_REQUIRE(cc.after_prepare() == 0); - sc.provider().commit_order_enter_status_ = wsrep::provider::error_bf_abort; - - // Run before commit BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); BOOST_REQUIRE(tc.certified() == true); BOOST_REQUIRE(tc.ordered() == true); - sc.provider().commit_order_enter_status_ = wsrep::provider::success; - // Rollback sequence BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay); - - // Cleanup after statement - cc.after_statement(); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_success); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(tc.ordered() == false); BOOST_REQUIRE(tc.certified() == false); @@ -219,7 +199,6 @@ BOOST_FIXTURE_TEST_CASE(transaction_context_streaming_2pc_commit, BOOST_REQUIRE(sc.provider().fragments() == 2); BOOST_REQUIRE(sc.provider().start_fragments() == 1); BOOST_REQUIRE(sc.provider().commit_fragments() == 1); - } BOOST_FIXTURE_TEST_CASE(transaction_context_streaming_2pc_commit_two_statements, @@ -260,7 +239,7 @@ BOOST_FIXTURE_TEST_CASE(transaction_context_2pc_applying, BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_ordered_commit); BOOST_REQUIRE(cc.after_commit() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committed); - cc.after_statement(); + BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_success); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committed); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(cc.current_error() == wsrep::e_success);