From 81d35053799baf19576f8493e6ea1c316f8f85cb Mon Sep 17 00:00:00 2001 From: Alexey Ozeritskiy Date: Tue, 12 Dec 2023 00:30:53 +0100 Subject: [PATCH] Fix minvotes for even number of servers --- src/raft.cpp | 2 +- test/test_raft.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/raft.cpp b/src/raft.cpp index aa87ec2..6d75214 100644 --- a/src/raft.cpp +++ b/src/raft.cpp @@ -98,7 +98,7 @@ TVolatileState& TVolatileState::SetCommitIndex(int index) TRaft::TRaft(int node, const TNodeDict& nodes) : Id(node) , Nodes(nodes) - , MinVotes((nodes.size()+2)/2) + , MinVotes((nodes.size()+2+nodes.size()%2)/2) , Npeers(nodes.size()) , Nservers(nodes.size()+1) , State(std::make_unique()) diff --git a/test/test_raft.cpp b/test/test_raft.cpp index 92f952b..9f36c78 100644 --- a/test/test_raft.cpp +++ b/test/test_raft.cpp @@ -189,6 +189,33 @@ void test_initial(void**) { assert_true(raft->CurrentStateName() == EState::FOLLOWER); } +void test_numbers(void**) { + auto raft = MakeRaft({}, 3); + assert_int_equal(raft->GetMinVotes(), 2); + assert_int_equal(raft->GetNservers(), 3); + assert_int_equal(raft->GetNpeers(), 2); + + raft = MakeRaft({}, 2); + assert_int_equal(raft->GetMinVotes(), 2); + assert_int_equal(raft->GetNservers(), 2); + assert_int_equal(raft->GetNpeers(), 1); + + raft = MakeRaft({}, 1); + assert_int_equal(raft->GetMinVotes(), 1); + assert_int_equal(raft->GetNservers(), 1); + assert_int_equal(raft->GetNpeers(), 0); + + raft = MakeRaft({}, 5); + assert_int_equal(raft->GetMinVotes(), 3); + assert_int_equal(raft->GetNservers(), 5); + assert_int_equal(raft->GetNpeers(), 4); + + raft = MakeRaft({}, 10); + assert_int_equal(raft->GetMinVotes(), 6); + assert_int_equal(raft->GetNservers(), 10); + assert_int_equal(raft->GetNpeers(), 9); +} + void test_become(void**) { auto raft = MakeRaft(); assert_true(raft->CurrentStateName() == EState::FOLLOWER); @@ -597,6 +624,7 @@ int main() { cmocka_unit_test(test_message_cast), cmocka_unit_test(test_message_send_recv), cmocka_unit_test(test_initial), + cmocka_unit_test(test_numbers), cmocka_unit_test(test_become), cmocka_unit_test(test_become_same_func), cmocka_unit_test(test_follower_to_candidate_on_timeout),