From e8f4b2d1836a34f590f6bddba21fde5f045187e3 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Wed, 18 Apr 2018 13:33:21 +0300 Subject: [PATCH] * Added tests for voluntary transaction rollback * Finished applier 2pc test --- src/client_context.hpp | 29 +++++++------- src/transaction_context.cpp | 4 +- src/transaction_context_test.cpp | 67 +++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/client_context.hpp b/src/client_context.hpp index 7848b1e..311aec8 100644 --- a/src/client_context.hpp +++ b/src/client_context.hpp @@ -53,19 +53,6 @@ namespace trrep s_quitting }; - // - // Client context constuctor - // - client_context(trrep::mutex& mutex, - trrep::server_context& server_context, - client_id id, - enum mode mode) - : mutex_(mutex) - , server_context_(server_context) - , id_(id) - , mode_(mode) - , state_(s_idle) - { } virtual ~client_context() { } // Accessors @@ -130,8 +117,22 @@ namespace trrep { abort(); } - private: + protected: + // + // Client context constuctor + // + client_context(trrep::mutex& mutex, + trrep::server_context& server_context, + client_id id, + enum mode mode) + : mutex_(mutex) + , server_context_(server_context) + , id_(id) + , mode_(mode) + , state_(s_idle) + { } + private: void state(enum state state); trrep::mutex& mutex_; diff --git a/src/transaction_context.cpp b/src/transaction_context.cpp index 2eef5b5..12f87f9 100644 --- a/src/transaction_context.cpp +++ b/src/transaction_context.cpp @@ -248,8 +248,8 @@ int trrep::transaction_context::before_commit() { // 1pc state(lock, s_certifying); + state(lock, s_committing); } - state(lock, s_committing); } break; } @@ -437,7 +437,7 @@ void trrep::transaction_context::state( assert(lock.owns_lock()); static const char allowed[n_states][n_states] = { /* ex pr ce co oc ct cf ma ab ad mr re from/to */ - { 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, /* ex */ + { 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0}, /* ex */ { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, /* pr */ { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0}, /* ce */ { 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0}, /* co */ diff --git a/src/transaction_context_test.cpp b/src/transaction_context_test.cpp index d44040a..ab473a3 100644 --- a/src/transaction_context_test.cpp +++ b/src/transaction_context_test.cpp @@ -139,6 +139,43 @@ BOOST_AUTO_TEST_CASE(transaction_context_2pc) BOOST_REQUIRE(tc.certified() == false); } +// +// Test a voluntary rollback +// +BOOST_AUTO_TEST_CASE(transaction_context_rollback) +{ + trrep::mock_server_context sc("s1", "s1", + trrep::server_context::rm_sync); + trrep::mock_client_context cc(sc,trrep::client_id(1), + trrep::client_context::m_replicating); + trrep::transaction_context tc(cc); + + // Verify initial state + BOOST_REQUIRE(tc.active() == false); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing); + + // Start a new transaction with ID 1 + tc.start_transaction(1); + BOOST_REQUIRE(tc.active()); + BOOST_REQUIRE(tc.id() == trrep::transaction_id(1)); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing); + + // Run before commit + BOOST_REQUIRE(tc.before_rollback() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting); + + // Run after commit + BOOST_REQUIRE(tc.after_rollback() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted); + + // Cleanup after statement + BOOST_REQUIRE(tc.after_statement() == 0); + BOOST_REQUIRE(tc.active() == false); + BOOST_REQUIRE(tc.ordered() == false); + BOOST_REQUIRE(tc.certified() == false); + +} + // // Test a 1PC transaction which gets BF aborted before before_commit // @@ -397,5 +434,33 @@ BOOST_AUTO_TEST_CASE(transaction_context_2pc_applying) BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing); BOOST_REQUIRE(tc.after_prepare() == 0); BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing); - + BOOST_REQUIRE(tc.before_commit() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing); + BOOST_REQUIRE(tc.ordered_commit() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit); + BOOST_REQUIRE(tc.after_commit() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed); +} + +BOOST_AUTO_TEST_CASE(transaction_context_applying_rollback) +{ + trrep::mock_server_context sc("s1", "s1", + trrep::server_context::rm_sync); + trrep::mock_client_context cc(sc, + trrep::client_id(1), + trrep::client_context::m_applier); + trrep::transaction_context tc(applying_transaction( + cc, 1, 1, + WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END)); + + BOOST_REQUIRE(tc.active() == false); + BOOST_REQUIRE(tc.start_transaction() == 0); + BOOST_REQUIRE(tc.active() == true); + BOOST_REQUIRE(tc.certified() == true); + BOOST_REQUIRE(tc.ordered() == true); + + BOOST_REQUIRE(tc.before_rollback() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting); + BOOST_REQUIRE(tc.after_rollback() == 0); + BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted); }