From 53d71b29ea8e9163737071211c2042a83af58bfb Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Thu, 7 Mar 2019 12:06:16 +0200 Subject: [PATCH] Save --- include/wsrep/client_state.hpp | 16 ++++++++-- test/CMakeLists.txt | 1 + test/nbo_test.cpp | 58 ++++++++++++++++++++++++++++++++++ test/toi_test.cpp | 4 +++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 test/nbo_test.cpp diff --git a/include/wsrep/client_state.hpp b/include/wsrep/client_state.hpp index 7b0409a..da5280c 100644 --- a/include/wsrep/client_state.hpp +++ b/include/wsrep/client_state.hpp @@ -99,7 +99,9 @@ namespace wsrep /** Client is in total order isolation mode */ m_toi, /** Client is executing rolling schema upgrade */ - m_rsu + m_rsu, + /** Client is executing NBO */ + m_nbo }; static const int n_modes_ = m_rsu + 1; @@ -573,6 +575,9 @@ namespace wsrep * @param buffer Buffer containing the action to execute inside * total order isolation section * @param flags Provider flags for TOI operation + * @todo Flags argument is not necessary for TOI operation, + * they should always have start_transaction | commit + * when passed to provider. * * @return Zero on success, non-zero otherwise. */ @@ -634,12 +639,16 @@ namespace wsrep /** * Begin non-blocking operation. */ - int begin_nbo(const wsrep::key_array&); + int begin_nbo_phase_one(const wsrep::key_array&); /** * End non-blocking operation */ - int end_nbo(); + int end_nbo_phase_one(); + + int begin_nbo_phase_two(); + + int end_nbo_phase_two(); /** * Get reference to the client mutex. @@ -915,6 +924,7 @@ namespace wsrep case wsrep::client_state::m_high_priority: return "high priority"; case wsrep::client_state::m_toi: return "toi"; case wsrep::client_state::m_rsu: return "rsu"; + case wsrep::client_state::m_nbo: return "nbo"; } return "unknown"; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b867b29..9086df0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(wsrep-lib_test mock_storage_service.cpp test_utils.cpp id_test.cpp + nbo_test.cpp server_context_test.cpp toi_test.cpp transaction_test.cpp diff --git a/test/nbo_test.cpp b/test/nbo_test.cpp new file mode 100644 index 0000000..fc3c330 --- /dev/null +++ b/test/nbo_test.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 Codership Oy + * + * This file is part of wsrep-lib. + * + * Wsrep-lib is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Wsrep-lib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wsrep-lib. If not, see . + */ + +#include "wsrep/client_state.hpp" + +#include "client_state_fixture.hpp" + +#include + +BOOST_FIXTURE_TEST_CASE(test_local_nbo, + 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}; + BOOST_REQUIRE(cc.begin_nbo_phase_one(keys) == 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); + // After required resoureces have been grabbed, NBO leave should + // end TOI but leave the client state in m_nbo. + BOOST_REQUIRE(cc.end_nbo_phase_one() == 0); + BOOST_REQUIRE(cc.mode() == wsrep::client_state::m_nbo); + BOOST_REQUIRE(cc.in_toi() == false); + 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() == 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); + // End of NBO phase will leave TOI and put the client state back to + // m_local + BOOST_REQUIRE(cc.end_nbo_phase_two() == 0); + 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); +} diff --git a/test/toi_test.cpp b/test/toi_test.cpp index 7d6d653..2268fcb 100644 --- a/test/toi_test.cpp +++ b/test/toi_test.cpp @@ -27,6 +27,7 @@ BOOST_FIXTURE_TEST_CASE(test_toi_mode, replicating_client_fixture_sync_rm) { BOOST_REQUIRE(cc.mode() == wsrep::client_state::m_local); + BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); wsrep::key key(wsrep::key::exclusive); key.append_key_part("k1", 2); key.append_key_part("k2", 2); @@ -40,6 +41,7 @@ BOOST_FIXTURE_TEST_CASE(test_toi_mode, BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); BOOST_REQUIRE(cc.leave_toi() == 0); BOOST_REQUIRE(cc.mode() == wsrep::client_state::m_local); + BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); } BOOST_FIXTURE_TEST_CASE(test_toi_applying, @@ -50,6 +52,7 @@ BOOST_FIXTURE_TEST_CASE(test_toi_applying, cc.after_commit()) == 0); cc.after_applying(); + BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); wsrep::ws_meta ws_meta(wsrep::gtid(wsrep::id("1"), wsrep::seqno(2)), wsrep::stid(sc.id(), wsrep::transaction_id::undefined(), @@ -61,5 +64,6 @@ BOOST_FIXTURE_TEST_CASE(test_toi_applying, BOOST_REQUIRE(cc.in_toi()); BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_high_priority); BOOST_REQUIRE(cc.leave_toi() == 0); + BOOST_REQUIRE(cc.toi_mode() == wsrep::client_state::m_local); cc.after_applying(); }