summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/vote_requester_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/repl/vote_requester_test.cpp')
-rw-r--r--src/mongo/db/repl/vote_requester_test.cpp623
1 files changed, 313 insertions, 310 deletions
diff --git a/src/mongo/db/repl/vote_requester_test.cpp b/src/mongo/db/repl/vote_requester_test.cpp
index d5b9d9ce3d5..fb5fb8d757f 100644
--- a/src/mongo/db/repl/vote_requester_test.cpp
+++ b/src/mongo/db/repl/vote_requester_test.cpp
@@ -44,345 +44,348 @@ namespace mongo {
namespace repl {
namespace {
- using executor::NetworkInterfaceMock;
- using unittest::assertGet;
-
- using RemoteCommandRequest = RemoteCommandRequest;
-
- bool stringContains(const std::string &haystack, const std::string& needle) {
- return haystack.find(needle) != std::string::npos;
- }
-
-
- class VoteRequesterTest : public mongo::unittest::Test {
- public:
- virtual void setUp() {
- ReplicaSetConfig config;
- ASSERT_OK(config.initialize(
- BSON("_id" << "rs0" <<
- "version" << 2 <<
- "members" << BSON_ARRAY(
- BSON("_id" << 0 << "host" << "host0") <<
- BSON("_id" << 1 << "host" << "host1") <<
- BSON("_id" << 2 << "host" << "host2") <<
- BSON("_id" << 3 << "host" << "host3" << "votes" << 0) <<
- BSON("_id" << 4 << "host" << "host4" << "votes" << 0)))));
- ASSERT_OK(config.validate());
- long long candidateId = 0;
- long long term = 2;
- OpTime lastOplogEntry = OpTime(Timestamp(999,0), 1);
-
- _requester.reset(new VoteRequester::Algorithm(config,
- candidateId,
- term,
- false, // not a dryRun
- lastOplogEntry));
- }
-
- virtual void tearDown() {
- _requester.reset(NULL);
- }
-
- protected:
- int64_t countLogLinesContaining(const std::string& needle) {
- return std::count_if(getCapturedLogMessages().begin(),
- getCapturedLogMessages().end(),
- stdx::bind(stringContains,
- stdx::placeholders::_1,
- needle));
- }
-
- bool hasReceivedSufficientResponses() {
- return _requester->hasReceivedSufficientResponses();
- }
-
- void processResponse(const RemoteCommandRequest& request, const ResponseStatus& response) {
- _requester->processResponse(request, response);
- }
-
- VoteRequester::VoteRequestResult getResult() {
- return _requester->getResult();
- }
-
- RemoteCommandRequest requestFrom(std::string hostname) {
- return RemoteCommandRequest(HostAndPort(hostname),
- "", // fields do not matter in VoteRequester
- BSONObj(),
- Milliseconds(0));
- }
-
- ResponseStatus badResponseStatus() {
- return ResponseStatus(ErrorCodes::NodeNotFound, "not on my watch");
- }
-
- ResponseStatus votedYes() {
- ReplSetRequestVotesResponse response;
- response.setOk(true);
- response.setVoteGranted(true);
- response.setTerm(1);
- return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(),
- Milliseconds(10)));
- }
-
- ResponseStatus votedNoBecauseConfigVersionDoesNotMatch() {
- ReplSetRequestVotesResponse response;
- response.setOk(true);
- response.setVoteGranted(false);
- response.setTerm(1);
- response.setReason("candidate's config version differs from mine");
- return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(),
- Milliseconds(10)));
- }
-
- ResponseStatus votedNoBecauseSetNameDiffers() {
- ReplSetRequestVotesResponse response;
- response.setOk(true);
- response.setVoteGranted(false);
- response.setTerm(1);
- response.setReason("candidate's set name differs from mine");
- return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(),
- Milliseconds(10)));
- }
-
- ResponseStatus votedNoBecauseLastOpTimeIsGreater() {
- ReplSetRequestVotesResponse response;
- response.setOk(true);
- response.setVoteGranted(false);
- response.setTerm(1);
- response.setReason("candidate's data is staler than mine");
- return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(),
- Milliseconds(10)));
- }
-
- ResponseStatus votedNoBecauseTermIsGreater() {
- ReplSetRequestVotesResponse response;
- response.setOk(true);
- response.setVoteGranted(false);
- response.setTerm(3);
- response.setReason("candidate's term is lower than mine");
- return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(),
- Milliseconds(10)));
- }
-
- ResponseStatus votedNoBecauseAlreadyVoted() {
- ReplSetRequestVotesResponse response;
- response.setOk(true);
- response.setVoteGranted(false);
- response.setTerm(2);
- response.setReason("already voted for another candidate this term");
- return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(),
- Milliseconds(10)));
- }
-
- std::unique_ptr<VoteRequester::Algorithm> _requester;
- };
-
- class VoteRequesterDryRunTest : public VoteRequesterTest {
- public:
- virtual void setUp() {
- ReplicaSetConfig config;
- ASSERT_OK(config.initialize(
- BSON("_id" << "rs0" <<
- "version" << 2 <<
- "members" << BSON_ARRAY(
- BSON("_id" << 0 << "host" << "host0") <<
- BSON("_id" << 1 << "host" << "host1") <<
- BSON("_id" << 2 << "host" << "host2") <<
- BSON("_id" << 3 << "host" << "host3" << "votes" << 0) <<
- BSON("_id" << 4 << "host" << "host4" << "votes" << 0)))));
- ASSERT_OK(config.validate());
- long long candidateId = 0;
- long long term = 2;
- OpTime lastOplogEntry = OpTime(Timestamp(999,0), 1);
-
- _requester.reset(new VoteRequester::Algorithm(config,
- candidateId,
- term,
- true, // dryRun
- lastOplogEntry));
- }
-
- };
-
- TEST_F(VoteRequesterTest, ImmediateGoodResponseWinElection) {
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- }
-
- TEST_F(VoteRequesterTest, BadConfigVersionWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseConfigVersionDoesNotMatch());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+using executor::NetworkInterfaceMock;
+using unittest::assertGet;
+
+using RemoteCommandRequest = RemoteCommandRequest;
+
+bool stringContains(const std::string& haystack, const std::string& needle) {
+ return haystack.find(needle) != std::string::npos;
+}
+
+
+class VoteRequesterTest : public mongo::unittest::Test {
+public:
+ virtual void setUp() {
+ ReplicaSetConfig config;
+ ASSERT_OK(config.initialize(BSON("_id"
+ << "rs0"
+ << "version" << 2 << "members"
+ << BSON_ARRAY(BSON("_id" << 0 << "host"
+ << "host0")
+ << BSON("_id" << 1 << "host"
+ << "host1")
+ << BSON("_id" << 2 << "host"
+ << "host2")
+ << BSON("_id" << 3 << "host"
+ << "host3"
+ << "votes" << 0)
+ << BSON("_id" << 4 << "host"
+ << "host4"
+ << "votes" << 0)))));
+ ASSERT_OK(config.validate());
+ long long candidateId = 0;
+ long long term = 2;
+ OpTime lastOplogEntry = OpTime(Timestamp(999, 0), 1);
+
+ _requester.reset(new VoteRequester::Algorithm(config,
+ candidateId,
+ term,
+ false, // not a dryRun
+ lastOplogEntry));
}
- TEST_F(VoteRequesterTest, SetNameDiffersWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ virtual void tearDown() {
+ _requester.reset(NULL);
}
- TEST_F(VoteRequesterTest, LastOpTimeIsGreaterWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseLastOpTimeIsGreater());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+protected:
+ int64_t countLogLinesContaining(const std::string& needle) {
+ return std::count_if(getCapturedLogMessages().begin(),
+ getCapturedLogMessages().end(),
+ stdx::bind(stringContains, stdx::placeholders::_1, needle));
}
- TEST_F(VoteRequesterTest, FailedToContactWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), badResponseStatus());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ bool hasReceivedSufficientResponses() {
+ return _requester->hasReceivedSufficientResponses();
}
- TEST_F(VoteRequesterTest, AlreadyVotedWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseAlreadyVoted());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ void processResponse(const RemoteCommandRequest& request, const ResponseStatus& response) {
+ _requester->processResponse(request, response);
}
- TEST_F(VoteRequesterTest, StaleTermLoseElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseTermIsGreater());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::StaleTerm, getResult());
- stopCapturingLogMessages();
+ VoteRequester::VoteRequestResult getResult() {
+ return _requester->getResult();
}
- TEST_F(VoteRequesterTest, NotEnoughVotesLoseElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), badResponseStatus());
- ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host2"));
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::InsufficientVotes, getResult());
- stopCapturingLogMessages();
+ RemoteCommandRequest requestFrom(std::string hostname) {
+ return RemoteCommandRequest(HostAndPort(hostname),
+ "", // fields do not matter in VoteRequester
+ BSONObj(),
+ Milliseconds(0));
}
- TEST_F(VoteRequesterDryRunTest, ImmediateGoodResponseWinElection) {
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ ResponseStatus badResponseStatus() {
+ return ResponseStatus(ErrorCodes::NodeNotFound, "not on my watch");
}
- TEST_F(VoteRequesterDryRunTest, BadConfigVersionWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseConfigVersionDoesNotMatch());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ ResponseStatus votedYes() {
+ ReplSetRequestVotesResponse response;
+ response.setOk(true);
+ response.setVoteGranted(true);
+ response.setTerm(1);
+ return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(), Milliseconds(10)));
}
- TEST_F(VoteRequesterDryRunTest, SetNameDiffersWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ ResponseStatus votedNoBecauseConfigVersionDoesNotMatch() {
+ ReplSetRequestVotesResponse response;
+ response.setOk(true);
+ response.setVoteGranted(false);
+ response.setTerm(1);
+ response.setReason("candidate's config version differs from mine");
+ return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(), Milliseconds(10)));
}
- TEST_F(VoteRequesterDryRunTest, LastOpTimeIsGreaterWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseLastOpTimeIsGreater());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ ResponseStatus votedNoBecauseSetNameDiffers() {
+ ReplSetRequestVotesResponse response;
+ response.setOk(true);
+ response.setVoteGranted(false);
+ response.setTerm(1);
+ response.setReason("candidate's set name differs from mine");
+ return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(), Milliseconds(10)));
}
- TEST_F(VoteRequesterDryRunTest, FailedToContactWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), badResponseStatus());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ ResponseStatus votedNoBecauseLastOpTimeIsGreater() {
+ ReplSetRequestVotesResponse response;
+ response.setOk(true);
+ response.setVoteGranted(false);
+ response.setTerm(1);
+ response.setReason("candidate's data is staler than mine");
+ return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(), Milliseconds(10)));
}
- TEST_F(VoteRequesterDryRunTest, AlreadyVotedWinElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseAlreadyVoted());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), votedYes());
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
- stopCapturingLogMessages();
+ ResponseStatus votedNoBecauseTermIsGreater() {
+ ReplSetRequestVotesResponse response;
+ response.setOk(true);
+ response.setVoteGranted(false);
+ response.setTerm(3);
+ response.setReason("candidate's term is lower than mine");
+ return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(), Milliseconds(10)));
}
- TEST_F(VoteRequesterDryRunTest, StaleTermLoseElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseTermIsGreater());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::StaleTerm, getResult());
- stopCapturingLogMessages();
+ ResponseStatus votedNoBecauseAlreadyVoted() {
+ ReplSetRequestVotesResponse response;
+ response.setOk(true);
+ response.setVoteGranted(false);
+ response.setTerm(2);
+ response.setReason("already voted for another candidate this term");
+ return ResponseStatus(NetworkInterfaceMock::Response(response.toBSON(), Milliseconds(10)));
}
- TEST_F(VoteRequesterDryRunTest, NotEnoughVotesLoseElection) {
- startCapturingLogMessages();
- ASSERT_FALSE(hasReceivedSufficientResponses());
- processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
- ASSERT_FALSE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
- processResponse(requestFrom("host2"), badResponseStatus());
- ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host2"));
- ASSERT_TRUE(hasReceivedSufficientResponses());
- ASSERT_EQUALS(VoteRequester::InsufficientVotes, getResult());
- stopCapturingLogMessages();
+ std::unique_ptr<VoteRequester::Algorithm> _requester;
+};
+
+class VoteRequesterDryRunTest : public VoteRequesterTest {
+public:
+ virtual void setUp() {
+ ReplicaSetConfig config;
+ ASSERT_OK(config.initialize(BSON("_id"
+ << "rs0"
+ << "version" << 2 << "members"
+ << BSON_ARRAY(BSON("_id" << 0 << "host"
+ << "host0")
+ << BSON("_id" << 1 << "host"
+ << "host1")
+ << BSON("_id" << 2 << "host"
+ << "host2")
+ << BSON("_id" << 3 << "host"
+ << "host3"
+ << "votes" << 0)
+ << BSON("_id" << 4 << "host"
+ << "host4"
+ << "votes" << 0)))));
+ ASSERT_OK(config.validate());
+ long long candidateId = 0;
+ long long term = 2;
+ OpTime lastOplogEntry = OpTime(Timestamp(999, 0), 1);
+
+ _requester.reset(new VoteRequester::Algorithm(config,
+ candidateId,
+ term,
+ true, // dryRun
+ lastOplogEntry));
}
+};
+
+TEST_F(VoteRequesterTest, ImmediateGoodResponseWinElection) {
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+}
+
+TEST_F(VoteRequesterTest, BadConfigVersionWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseConfigVersionDoesNotMatch());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterTest, SetNameDiffersWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterTest, LastOpTimeIsGreaterWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseLastOpTimeIsGreater());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterTest, FailedToContactWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), badResponseStatus());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterTest, AlreadyVotedWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseAlreadyVoted());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterTest, StaleTermLoseElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseTermIsGreater());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::StaleTerm, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterTest, NotEnoughVotesLoseElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), badResponseStatus());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host2"));
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::InsufficientVotes, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, ImmediateGoodResponseWinElection) {
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+}
+
+TEST_F(VoteRequesterDryRunTest, BadConfigVersionWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseConfigVersionDoesNotMatch());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, SetNameDiffersWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, LastOpTimeIsGreaterWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseLastOpTimeIsGreater());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, FailedToContactWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), badResponseStatus());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, AlreadyVotedWinElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseAlreadyVoted());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), votedYes());
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::SuccessfullyElected, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, StaleTermLoseElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseTermIsGreater());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::StaleTerm, getResult());
+ stopCapturingLogMessages();
+}
+
+TEST_F(VoteRequesterDryRunTest, NotEnoughVotesLoseElection) {
+ startCapturingLogMessages();
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ processResponse(requestFrom("host1"), votedNoBecauseSetNameDiffers());
+ ASSERT_FALSE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got no vote from host1"));
+ processResponse(requestFrom("host2"), badResponseStatus());
+ ASSERT_EQUALS(1, countLogLinesContaining("Got failed response from host2"));
+ ASSERT_TRUE(hasReceivedSufficientResponses());
+ ASSERT_EQUALS(VoteRequester::InsufficientVotes, getResult());
+ stopCapturingLogMessages();
+}
} // namespace
} // namespace repl