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:
@ -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;
|
||||
}
|
||||
|
@ -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_; }
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user