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

codership/wsrep-lib#34 Unit test for sync-disconnect-sync

Added unit test for sync-disconnect-sync transition without SST.
This commit is contained in:
Teemu Ollakka
2018-12-14 13:03:37 +02:00
parent bf83907f38
commit 76424ad515
3 changed files with 85 additions and 5 deletions

View File

@ -286,6 +286,16 @@ namespace wsrep
return *provider_; return *provider_;
} }
/**
* Initialize connection to cluster.
*
* @param cluster_name A string containing the name of the cluster
* @param cluster_address Cluster address string
* @param state_donor String containing a list of desired donors
* @param bootstrap Bootstrap option
*
* @return Zero in case of success, non-zero on error.
*/
int connect(const std::string& cluster_name, int connect(const std::string& cluster_name,
const std::string& cluster_address, const std::string& cluster_address,
const std::string& state_donor, const std::string& state_donor,
@ -598,6 +608,7 @@ namespace wsrep
// Close transactions when handling disconnect from the group. // Close transactions when handling disconnect from the group.
void close_transactions_at_disconnect(wsrep::high_priority_service&); void close_transactions_at_disconnect(wsrep::high_priority_service&);
// Common actions on final view // Common actions on final view
void go_final(wsrep::unique_lock<wsrep::mutex>&, void go_final(wsrep::unique_lock<wsrep::mutex>&,
const wsrep::view&, wsrep::high_priority_service*); const wsrep::view&, wsrep::high_priority_service*);

View File

@ -686,6 +686,7 @@ void wsrep::server_state::on_view(const wsrep::view& view,
wsrep::log_info() wsrep::log_info()
<< "================================================\nView:\n" << "================================================\nView:\n"
<< " id: " << view.state_id() << "\n" << " id: " << view.state_id() << "\n"
<< " seqno: " << view.view_seqno() << "\n"
<< " status: " << view.status() << "\n" << " status: " << view.status() << "\n"
<< " prococol_version: " << view.protocol_version() << "\n" << " prococol_version: " << view.protocol_version() << "\n"
<< " own_index: " << view.own_index() << "\n" << " own_index: " << view.own_index() << "\n"
@ -722,6 +723,13 @@ void wsrep::server_state::on_view(const wsrep::view& view,
{ {
state(lock, s_joiner); state(lock, s_joiner);
state(lock, s_initializing); state(lock, s_initializing);
if (init_initialized_)
{
// If storage engines have already been initialized,
// skip directly to s_joined.
state(lock, s_initialized);
state(lock, s_joined);
}
} }
else if (state_ == s_joiner) else if (state_ == s_joiner)
{ {

View File

@ -65,6 +65,20 @@ namespace
wsrep::ws_meta ws_meta; wsrep::ws_meta ws_meta;
wsrep::id cluster_id; wsrep::id cluster_id;
wsrep::view bootstrap_view; wsrep::view bootstrap_view;
void final_view()
{
BOOST_REQUIRE(ss.state() != wsrep::server_state::s_disconnected);
wsrep::view view(wsrep::gtid(), // state_id
wsrep::seqno::undefined(), // view seqno
wsrep::view::disconnected, // status
0, // capabilities
-1, // own_index
0, // protocol ver
std::vector<wsrep::view::member>() // members
);
ss.on_view(view, &hps);
}
}; };
struct applying_server_fixture : server_fixture_base struct applying_server_fixture : server_fixture_base
@ -83,6 +97,22 @@ namespace
{ {
server_service.sst_before_init_ = true; server_service.sst_before_init_ = true;
} }
// Helper method to bootstrap the server with bootstrap view
void bootstrap()
{
BOOST_REQUIRE(ss.connect("cluster", "local", "0", false) == 0);
ss.on_connect(bootstrap_view);
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected);
server_service.sync_point_enabled_ = "on_view_wait_initialized";
server_service.sync_point_action_ = server_service.spa_initialize;
ss.on_view(bootstrap_view, &hps);
server_service.sync_point_enabled_ = "";
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
ss.on_sync();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
}
}; };
struct init_first_server_fixture : server_fixture_base struct init_first_server_fixture : server_fixture_base
@ -210,18 +240,49 @@ BOOST_AUTO_TEST_CASE(server_state_state_strings)
BOOST_FIXTURE_TEST_CASE(server_state_sst_first_boostrap, BOOST_FIXTURE_TEST_CASE(server_state_sst_first_boostrap,
sst_first_server_fixture) sst_first_server_fixture)
{ {
bootstrap();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
}
// Cycle from synced state to disconnected and back to synced. Server
// storage engines remain initialized.
BOOST_FIXTURE_TEST_CASE(
server_state_sst_first_synced_disconnected_synced_no_sst,
sst_first_server_fixture)
{
bootstrap();
ss.disconnect();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_disconnecting);
final_view();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_disconnected);
// Connect back as a sole member in the cluster
BOOST_REQUIRE(ss.connect("cluster", "local", "0", false) == 0); BOOST_REQUIRE(ss.connect("cluster", "local", "0", false) == 0);
ss.on_connect(bootstrap_view); // @todo: s_connecting state would be good to have
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_disconnected);
// Server state must keep the initialized state
BOOST_REQUIRE(ss.is_initialized() == true);
std::vector<wsrep::view::member> members;
members.push_back(wsrep::view::member(wsrep::id("s1"), "name", ""));
wsrep::view view(wsrep::gtid(cluster_id, wsrep::seqno(1)),
wsrep::seqno(2),
wsrep::view::primary,
0, // capabilities
0, // own index
1, // protocol version
members);
ss.on_connect(view);
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected);
server_service.sync_point_enabled_ = "on_view_wait_initialized"; // As storage engines have been initialized, there should not be
server_service.sync_point_action_ = server_service.spa_initialize; // any reason to wait for initialization. State should jump directly
ss.on_view(bootstrap_view, &hps); // to s_joined after handling the view.
server_service.sync_point_enabled_ = ""; ss.on_view(view, &hps);
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
ss.on_sync(); ss.on_sync();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Test cases for init first // // Test cases for init first //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////