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:
@ -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*);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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 //
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user