Commit 647ac661 authored by Georgios Bitzes's avatar Georgios Bitzes
Browse files

test: run pre-vote together with vote, ensure results match

parent a7e79628
Pipeline #1508292 failed with stages
in 81 minutes and 52 seconds
......@@ -404,11 +404,11 @@ TEST_F(Raft_Voting, no_double_voting_on_same_term) {
req.lastTerm = 0;
req.lastIndex = 2;
RaftVoteResponse resp = dispatcher()->requestVote(req);
RaftVoteResponse resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::GRANTED);
req.candidate = myself(2);
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::REFUSED);
}
......@@ -419,11 +419,11 @@ TEST_F(Raft_Voting, no_votes_for_previous_terms) {
req.lastTerm = 0;
req.lastIndex = 2;
RaftVoteResponse resp = dispatcher()->requestVote(req);
RaftVoteResponse resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::GRANTED);
req.term = 0;
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::REFUSED);
}
......@@ -434,7 +434,7 @@ TEST_F(Raft_Voting, no_votes_to_outdated_logs) {
req.lastTerm = 0;
req.lastIndex = 1;
RaftVoteResponse resp = dispatcher()->requestVote(req);
RaftVoteResponse resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::GRANTED);
// add a few requests to the log
......@@ -447,17 +447,17 @@ TEST_F(Raft_Voting, no_votes_to_outdated_logs) {
req.lastTerm = 4;
req.lastIndex = 30;
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::REFUSED);
req.lastTerm = 5;
req.lastIndex = 2;
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::REFUSED);
req.lastIndex = 4;
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::GRANTED);
}
......@@ -468,7 +468,7 @@ TEST_F(Raft_Voting, veto_if_new_leader_would_overwrite_committed_entries) {
req.lastTerm = 0;
req.lastIndex = 1;
RaftVoteResponse resp = dispatcher()->requestVote(req);
RaftVoteResponse resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::GRANTED);
// add a few requests to the log
......@@ -485,18 +485,18 @@ TEST_F(Raft_Voting, veto_if_new_leader_would_overwrite_committed_entries) {
req.lastIndex = 1;
// would overwrite committed entry #1
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::VETO);
req.lastTerm = 3;
// contacting node is too far behind, and the addition of the leadership marker
// would overwrite entry #2
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::VETO);
// contacting node's lastIndex has a higher term than local, committed lastIndex.
req.lastTerm = 4;
ASSERT_EQ(dispatcher()->requestVote(req).vote, RaftVote::VETO);
ASSERT_EQ(issueManualVote(req).vote, RaftVote::VETO);
// Case where lastIndex has been trimmed already
RETRY_ASSERT_TRUE(stateMachine()->getLastApplied() >= 2);
......@@ -504,7 +504,7 @@ TEST_F(Raft_Voting, veto_if_new_leader_would_overwrite_committed_entries) {
req.lastIndex = 1;
req.lastTerm = 3;
resp = dispatcher()->requestVote(req);
resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::VETO);
}
......@@ -522,7 +522,7 @@ TEST_F(Raft_Voting, smaller_log_but_last_index_higher_term) {
req.lastTerm = 5;
req.lastIndex = 2;
RaftVoteResponse resp = dispatcher()->requestVote(req);
RaftVoteResponse resp = issueManualVote(req);
ASSERT_EQ(resp.vote, RaftVote::GRANTED);
}
......
......@@ -32,6 +32,8 @@
#include "raft/RaftJournal.hh"
#include "QuarkDBNode.hh"
#include "qclient/GlobalInterceptor.hh"
#include "raft/RaftDispatcher.hh"
#include <gtest/gtest.h>
namespace quarkdb {
......@@ -288,6 +290,22 @@ RaftTimeouts TestCluster::timeouts() {
return clusterTimeouts;
}
RaftVoteResponse TestCluster::issueManualVote(const RaftVoteRequest &votereq, int id) {
RaftStateSnapshotPtr snapshot = state(id)->getSnapshot();
// pre-vote
RaftVoteResponse preVoteOutcome = dispatcher(id)->requestVote(votereq, true);
// ensure nothing changed
EXPECT_EQ(snapshot, state(id)->getSnapshot());
EXPECT_EQ(snapshot->term, state(id)->getSnapshot()->term);
// real-vote
RaftVoteResponse realVoteOutcome = dispatcher(id)->requestVote(votereq, false);
EXPECT_EQ(preVoteOutcome.vote, realVoteOutcome.vote);
return realVoteOutcome;
}
TestNode::TestNode(RaftServer me, RaftClusterID clust, RaftTimeouts timeouts, const std::vector<RaftServer> &nd)
: myselfSrv(me), clusterID(clust), initialNodes(nd) {
......
......@@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#ifndef __QUARKDB_TEST_UTILS_H__
#define __QUARKDB_TEST_UTILS_H__
#ifndef QUARKDB_TEST_UTILS_HH
#define QUARKDB_TEST_UTILS_HH
#include <sys/socket.h>
#include <sys/un.h>
......@@ -226,6 +226,11 @@ public:
Publisher* publisher(int id = 0);
RaftTimeouts timeouts();
// issue manual vote, with a pre-vote test before that.
// ensure pre-vote and vote match, and that pre-vote does not advance
// raft state.
RaftVoteResponse issueManualVote(const RaftVoteRequest &votereq, int id = 0);
qclient::Options makeNoRedirectOptions(int id = 0);
std::unique_ptr<qclient::Handshake> makeQClientHandshake(int id = 0);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment