From 0b1286971570ae58023ec2f0cffe10e75bff76d1 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Wed, 7 Aug 2019 08:42:00 +0300 Subject: [PATCH] NBO begin error handling, unit test --- src/client_state.cpp | 6 ++++++ test/mock_provider.hpp | 2 +- test/nbo_test.cpp | 28 ++++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/client_state.cpp b/src/client_state.cpp index 5456e66..d55427d 100644 --- a/src/client_state.cpp +++ b/src/client_state.cpp @@ -483,7 +483,13 @@ int wsrep::client_state::begin_nbo_phase_one(const wsrep::key_array& keys, ret= 0; break; default: + override_error(e_deadlock_error); current_error_status_ = status; + if (!toi_meta_.seqno().is_undefined()) + { + provider().leave_toi(id_); + } + toi_meta_ = wsrep::ws_meta(); ret= 1; break; } diff --git a/test/mock_provider.hpp b/test/mock_provider.hpp index 6681d37..b5365e3 100644 --- a/test/mock_provider.hpp +++ b/test/mock_provider.hpp @@ -257,7 +257,7 @@ namespace wsrep ++toi_start_transaction_; if (flags & wsrep::provider::flag::commit) ++toi_commit_; - return wsrep::provider::success; + return certify_result_; } enum wsrep::provider::status leave_toi(wsrep::client_id, diff --git a/test/nbo_test.cpp b/test/nbo_test.cpp index 73eafc8..6d2917f 100644 --- a/test/nbo_test.cpp +++ b/test/nbo_test.cpp @@ -49,7 +49,7 @@ BOOST_FIXTURE_TEST_CASE(test_local_nbo, BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); // Second phase replicates the NBO end event and grabs TOI // again for finalizing the NBO. - BOOST_REQUIRE(cc.begin_nbo_phase_two(keys) == 0); + BOOST_REQUIRE(cc.begin_nbo_phase_two() == 0); BOOST_REQUIRE(cc.mode() == wsrep::client_state::m_nbo); BOOST_REQUIRE(cc.in_toi()); BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); @@ -67,6 +67,30 @@ BOOST_FIXTURE_TEST_CASE(test_local_nbo, BOOST_REQUIRE(sc.provider().toi_commit() == 1); } +BOOST_FIXTURE_TEST_CASE(test_local_nbo_cert_failure, + replicating_client_fixture_sync_rm) +{ + // NBO is executed in two consecutive TOI operations + BOOST_REQUIRE(cc.mode() == wsrep::client_state::m_local); + // First phase certifies the write set and enters TOI + wsrep::key key(wsrep::key::exclusive); + key.append_key_part("k1", 2); + key.append_key_part("k2", 2); + wsrep::key_array keys{key}; + std::string data("data"); + sc.provider().certify_result_ = wsrep::provider::error_certification_failed; + BOOST_REQUIRE(cc.begin_nbo_phase_one( + keys, + wsrep::const_buffer(data.data(), + data.size())) == 1); + BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error); + BOOST_REQUIRE(cc.current_error_status() == + wsrep::provider::error_certification_failed); + BOOST_REQUIRE(cc.mode() == wsrep::client_state::m_local); + BOOST_REQUIRE(cc.in_toi() == false); + BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); +} + // This test case operates through server_state object in order to // verify that the high priority service is called with appropriate // arguments. @@ -101,7 +125,7 @@ BOOST_FIXTURE_TEST_CASE(test_applying_nbo, key.append_key_part("k2", 2); wsrep::key_array keys{key}; // Starting phase two should put nbo_cs in toi mode. - BOOST_REQUIRE(nbo_cs->begin_nbo_phase_two(keys) == 0); + BOOST_REQUIRE(nbo_cs->begin_nbo_phase_two() == 0); BOOST_REQUIRE(nbo_cs->mode() == wsrep::client_state::m_nbo); BOOST_REQUIRE(nbo_cs->in_toi()); BOOST_REQUIRE(nbo_cs->toi_mode() == wsrep::client_state::m_local);