Skip to content

Commit 0bff606

Browse files
yawzhangxiaoxichen
authored andcommitted
add yield leader api for test
1 parent 49c4745 commit 0bff606

File tree

7 files changed

+33
-25
lines changed

7 files changed

+33
-25
lines changed

conanfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class HomestoreConan(ConanFile):
1111
name = "homestore"
12-
version = "6.20.22"
12+
version = "6.20.23"
1313

1414
homepage = "https://github.com/eBay/Homestore"
1515
description = "HomeStore Storage Engine"

src/include/homestore/replication/repl_dev.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ class ReplDev {
531531
/// @brief request leadership if it should be the leader but not, yield leadership if it is leader but should not be
532532
virtual void reconcile_leader() = 0;
533533

534+
/// @brief Yield current leadership and becomes a follower.
535+
/// this API call nuraft yield_leadership directly
536+
virtual void yield_leadership(bool immediate_yield, replica_id_t candidate) = 0;
537+
534538
/// @brief Sets a custom name for the repldev. Users can assign a meaningful name to the repldev for easy debugging.
535539
virtual void set_custom_rdev_name(std::string const& name) = 0;
536540

src/lib/replication/repl_dev/raft_repl_dev.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,10 @@ void RaftReplDev::reconcile_leader() {
17381738
RD_LOGI(NO_TRACE_ID, "Yielded leadership");
17391739
}
17401740

1741+
void RaftReplDev::yield_leadership(bool immediate_yield, replica_id_t candidate) {
1742+
raft_server()->yield_leadership(immediate_yield, nuraft_mesg::to_server_id(candidate));
1743+
}
1744+
17411745
std::set< replica_id_t > RaftReplDev::get_active_peers() const {
17421746
auto repl_status = get_replication_status();
17431747
std::set< replica_id_t > res;

src/lib/replication/repl_dev/raft_repl_dev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ class RaftReplDev : public ReplDev,
298298
std::set< replica_id_t > get_active_peers() const;
299299
group_id_t group_id() const override { return m_group_id; }
300300
void reconcile_leader() override;
301+
void yield_leadership(bool immediate_yield, replica_id_t candidate) override;
301302
void set_custom_rdev_name(std::string const& name) override {
302303
RD_LOGI(NO_TRACE_ID, "Resetting repl dev name from {} to {}", m_rdev_name, name);
303304
m_rdev_name = name;

src/lib/replication/repl_dev/solo_repl_dev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class SoloReplDev : public ReplDev {
7979
peer_info{.id_ = m_group_id, .replication_idx_ = 0, .last_succ_resp_us_ = 0, .priority_ = 1}};
8080
}
8181
void reconcile_leader() override {}
82+
void yield_leadership(bool immediate_yield, replica_id_t candidate) override {}
8283
bool is_ready_for_traffic() const override { return true; }
8384
void set_stage(repl_dev_stage_t stage) override {}
8485
repl_dev_stage_t get_stage() const override { return repl_dev_stage_t::ACTIVE; }

src/tests/test_common/raft_repl_test_base.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,10 @@ class RaftReplDevTestBase : public testing::Test {
789789

790790
void reconcile_leader(std::shared_ptr< TestReplicatedDB > db) { db->repl_dev()->reconcile_leader(); }
791791

792+
void yield_leadership(std::shared_ptr< TestReplicatedDB > db, bool immediate_yield, replica_id_t candidate) {
793+
db->repl_dev()->yield_leadership(immediate_yield, candidate);
794+
}
795+
792796
protected:
793797
std::vector< std::shared_ptr< TestReplicatedDB > > dbs_;
794798
uint32_t written_entries_{0};

src/tests/test_raft_repl_dev.cpp

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -750,20 +750,24 @@ TEST_F(RaftReplDevTest, ReconcileLeader) {
750750
this->validate_data();
751751
g_helper->sync_for_cleanup_start();
752752

753-
LOGINFO("Restart leader");
754-
if (g_helper->replica_num() == 0) { g_helper->restart_homestore(); }
753+
LOGINFO("Yield leader");
754+
auto expected_leader_num = 1;
755+
auto expected_leader = g_helper->replica_id(expected_leader_num);
756+
if (g_helper->replica_num() == 0) { this->yield_leadership(dbs_[0], false, expected_leader); }
755757
g_helper->sync_for_verify_start();
756758
LOGINFO("Validate leader switched");
757759
std::this_thread::sleep_for(std::chrono::milliseconds{500});
758760
auto leader = this->wait_and_get_leader_id();
759-
auto leader_replica_num = 0;
760-
if (g_helper->replica_num() == 0) {
761-
ASSERT_NE(leader, g_helper->my_replica_id());
762-
LOGINFO("Leader has changed");
763-
} else if (g_helper->my_replica_id() == leader) {
764-
leader_replica_num = g_helper->replica_num();
765-
LOGINFO("New leader is replica={}, replica_num={}", leader, leader_replica_num);
766-
}
761+
ASSERT_EQ(leader, expected_leader);
762+
763+
g_helper->sync_for_test_start();
764+
LOGINFO("Trigger reconcile leader on follower, expected no change")
765+
if (g_helper->replica_num() == 2) { this->reconcile_leader(dbs_[0]); }
766+
g_helper->sync_for_verify_start();
767+
LOGINFO("Validate leader unchanged");
768+
std::this_thread::sleep_for(std::chrono::milliseconds{500});
769+
leader = this->wait_and_get_leader_id();
770+
ASSERT_EQ(leader, expected_leader);
767771

768772
g_helper->sync_for_test_start();
769773
if (g_helper->replica_num() == 0) {
@@ -777,19 +781,13 @@ TEST_F(RaftReplDevTest, ReconcileLeader) {
777781
if (g_helper->replica_num() == 0) { ASSERT_EQ(leader, g_helper->my_replica_id()); }
778782
g_helper->sync_for_cleanup_start();
779783

780-
LOGINFO("Restart leader again");
781-
if (g_helper->replica_num() == 0) { g_helper->restart_homestore(); }
784+
LOGINFO("Yield leader again");
785+
if (g_helper->replica_num() == 0) { this->yield_leadership(dbs_[0], false, expected_leader); }
782786
g_helper->sync_for_verify_start();
783787
LOGINFO("Validate leader switched");
784788
std::this_thread::sleep_for(std::chrono::milliseconds{500});
785789
leader = this->wait_and_get_leader_id();
786-
if (g_helper->replica_num() == 0) {
787-
ASSERT_NE(leader, g_helper->my_replica_id());
788-
LOGINFO("Leader has changed again");
789-
} else if (g_helper->my_replica_id() == leader) {
790-
leader_replica_num = g_helper->replica_num();
791-
LOGINFO("New leader is replica={}, replica_num={}", leader, leader_replica_num);
792-
}
790+
ASSERT_EQ(leader, expected_leader);
793791
g_helper->sync_for_test_start();
794792

795793
if (g_helper->my_replica_id() == leader) {
@@ -800,11 +798,7 @@ TEST_F(RaftReplDevTest, ReconcileLeader) {
800798
std::this_thread::sleep_for(std::chrono::milliseconds{1000});
801799
leader = this->wait_and_get_leader_id();
802800
LOGINFO("Validate leader switched back to initial replica, leader={}", leader);
803-
if (g_helper->replica_num() == 0 && leader != g_helper->my_replica_id()) {
804-
// yield leadership cannot garantee replica 0 will be leader again
805-
// so we just log a warning here if it is not
806-
LOGWARN("Leader is not replica 0 after yielding, leader={}", leader);
807-
}
801+
if (g_helper->replica_num() == 0) { ASSERT_EQ(leader, g_helper->my_replica_id()); }
808802
g_helper->sync_for_cleanup_start();
809803
}
810804

0 commit comments

Comments
 (0)