1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-20 01:03:16 +03:00

Tests and fixes for replaying.

This commit is contained in:
Teemu Ollakka
2018-06-14 15:00:40 +03:00
parent ca6286d8b2
commit 0b6e49474f
11 changed files with 123 additions and 21 deletions

View File

@ -55,9 +55,11 @@ namespace wsrep
void remove_fragments(const wsrep::transaction_context& )
WSREP_OVERRIDE { }
void will_replay(wsrep::transaction_context&) WSREP_OVERRIDE { }
int replay(wsrep::transaction_context& tc) WSREP_OVERRIDE
enum wsrep::provider::status
replay(wsrep::transaction_context& tc) WSREP_OVERRIDE
{
int ret(provider().replay(tc.ws_handle(), this));
enum wsrep::provider::status ret(
provider().replay(tc.ws_handle(), this));
++replays_;
return ret;
}

View File

@ -26,6 +26,7 @@ namespace wsrep
, commit_order_enter_result_()
, commit_order_leave_result_()
, release_result_()
, replay_result_()
, group_id_("1")
, server_id_("1")
, group_seqno_(0)
@ -138,14 +139,43 @@ namespace wsrep
int release(wsrep::ws_handle&)
{ return release_result_; }
int replay(wsrep::ws_handle&, void* ctx)
enum wsrep::provider::status replay(wsrep::ws_handle&, void* ctx)
{
wsrep::mock_client_context& cc(
*static_cast<wsrep::mock_client_context*>(ctx));
wsrep::client_applier_mode applier_mode(cc);
const wsrep::transaction_context& tc(cc.transaction());
return server_context_.on_apply(cc, tc.ws_handle(), tc.ws_meta(),
wsrep::const_buffer());
wsrep::ws_meta ws_meta;
if (replay_result_ == wsrep::provider::success)
{
// If the ws_meta was not assigned yet, the certify
// returned early due to BF abort.
if (tc.ws_meta().seqno().nil())
{
++group_seqno_;
ws_meta = wsrep::ws_meta(
wsrep::gtid(group_id_, wsrep::seqno(group_seqno_)),
wsrep::stid(server_id_, tc.id(), cc.id()),
wsrep::seqno(group_seqno_ - 1),
wsrep::provider::flag::start_transaction |
wsrep::provider::flag::commit);
}
else
{
ws_meta = tc.ws_meta();
}
}
else
{
return replay_result_;
}
if (server_context_.on_apply(cc, tc.ws_handle(), ws_meta,
wsrep::const_buffer()))
{
return wsrep::provider::error_fatal;
}
return wsrep::provider::success;
}
int sst_sent(const wsrep::gtid&, int) { return 0; }
@ -183,6 +213,7 @@ namespace wsrep
enum wsrep::provider::status commit_order_enter_result_;
enum wsrep::provider::status commit_order_leave_result_;
enum wsrep::provider::status release_result_;
enum wsrep::provider::status replay_result_;
size_t start_fragments() const { return start_fragments_; }
size_t fragments() const { return fragments_; }

View File

@ -307,6 +307,45 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(
BOOST_REQUIRE(cc.current_error());
}
//
// Test a transaction which gets BF aborted inside provider before
// certification result is known. Replaying will be successful
//
BOOST_FIXTURE_TEST_CASE(
transaction_context_bf_before_cert_result_replay_success,
replicating_client_fixture_sync_rm)
{
BOOST_REQUIRE(cc.start_transaction(1) == 0);
sc.provider().certify_result_ = wsrep::provider::error_bf_abort;
sc.provider().replay_result_ = wsrep::provider::success;
BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay);
BOOST_REQUIRE(cc.after_statement() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committed);
BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
}
//
// Test a transaction which gets BF aborted inside provider before
// certification result is known. Replaying will fail because of
// certification failure.
//
BOOST_FIXTURE_TEST_CASE(
transaction_context_bf_before_cert_result_replay_cert_fail,
replicating_client_fixture_sync_rm)
{
BOOST_REQUIRE(cc.start_transaction(1) == 0);
sc.provider().certify_result_ = wsrep::provider::error_bf_abort;
sc.provider().replay_result_ = wsrep::provider::error_certification_failed;
BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_must_replay);
BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_error);
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_aborted);
BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
BOOST_REQUIRE(tc.active() == false);
}
//
// Test a 1PC transaction which gets BF aborted during before_commit via