summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authorJudah Schvimer <judah@mongodb.com>2018-04-30 16:12:53 -0400
committerJudah Schvimer <judah@mongodb.com>2018-05-01 13:27:28 -0400
commit0ab171caf6aaebf044e52d3f491f7f13e6858e9a (patch)
tree958f255b2503313b33f460ef0ff04f4043f75b8b /src/mongo/db/repl
parent431cc09caaa8150ea8d7725bfaa14cc612d0d62d (diff)
downloadmongo-0ab171caf6aaebf044e52d3f491f7f13e6858e9a.tar.gz
SERVER-34716 improve ReplSetGetStatus unittests
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/topology_coordinator.cpp5
-rw-r--r--src/mongo/db/repl/topology_coordinator.h3
-rw-r--r--src/mongo/db/repl/topology_coordinator_v1_test.cpp49
3 files changed, 45 insertions, 12 deletions
diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp
index 5ca660a2012..f5898afeea8 100644
--- a/src/mongo/db/repl/topology_coordinator.cpp
+++ b/src/mongo/db/repl/topology_coordinator.cpp
@@ -1947,7 +1947,8 @@ void TopologyCoordinator::changeMemberState_forTest(const MemberState& newMember
log() << newMemberState;
}
-void TopologyCoordinator::_setCurrentPrimaryForTest(int primaryIndex) {
+void TopologyCoordinator::setCurrentPrimary_forTest(int primaryIndex,
+ const Timestamp& electionTime) {
if (primaryIndex == _selfIndex) {
changeMemberState_forTest(MemberState::RS_PRIMARY);
} else {
@@ -1957,7 +1958,7 @@ void TopologyCoordinator::_setCurrentPrimaryForTest(int primaryIndex) {
if (primaryIndex != -1) {
ReplSetHeartbeatResponse hbResponse;
hbResponse.setState(MemberState::RS_PRIMARY);
- hbResponse.setElectionTime(Timestamp());
+ hbResponse.setElectionTime(electionTime);
hbResponse.setAppliedOpTime(_memberData.at(primaryIndex).getHeartbeatAppliedOpTime());
hbResponse.setSyncingTo(HostAndPort());
hbResponse.setHbMsg("");
diff --git a/src/mongo/db/repl/topology_coordinator.h b/src/mongo/db/repl/topology_coordinator.h
index d505dd3a90e..fd630827579 100644
--- a/src/mongo/db/repl/topology_coordinator.h
+++ b/src/mongo/db/repl/topology_coordinator.h
@@ -751,7 +751,8 @@ public:
// Sets _currentPrimaryIndex to the given index. Should only be used in unit tests!
// TODO(spencer): Remove this once we can easily call for an election in unit tests to
// set the current primary.
- void _setCurrentPrimaryForTest(int primaryIndex);
+ void setCurrentPrimary_forTest(int primaryIndex,
+ const Timestamp& electionTime = Timestamp(0, 0));
// Returns _electionTime. Only used in unittests.
Timestamp getElectionTime() const;
diff --git a/src/mongo/db/repl/topology_coordinator_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_v1_test.cpp
index 14d0bfef328..43ee132afa9 100644
--- a/src/mongo/db/repl/topology_coordinator_v1_test.cpp
+++ b/src/mongo/db/repl/topology_coordinator_v1_test.cpp
@@ -110,7 +110,7 @@ protected:
void makeSelfPrimary(const Timestamp& electionTimestamp = Timestamp(0, 0)) {
getTopoCoord().changeMemberState_forTest(MemberState::RS_PRIMARY, electionTimestamp);
- getTopoCoord()._setCurrentPrimaryForTest(_selfIndex);
+ getTopoCoord().setCurrentPrimary_forTest(_selfIndex, electionTimestamp);
OpTime dummyOpTime(Timestamp(1, 1), getTopoCoord().getTerm());
ASSERT_OK(getTopoCoord().completeTransitionToPrimary(dummyOpTime));
}
@@ -1091,7 +1091,7 @@ TEST_F(TopoCoordTest, NodeReturnsNotSecondaryWhenSyncFromIsRunAgainstPrimary) {
ASSERT_EQUALS(-1, getCurrentPrimaryIndex());
makeSelfPrimary();
ASSERT_EQUALS(0, getCurrentPrimaryIndex());
- getTopoCoord()._setCurrentPrimaryForTest(0);
+ getTopoCoord().setCurrentPrimary_forTest(0);
getTopoCoord().prepareSyncFromResponse(HostAndPort("h3"), &response, &result);
ASSERT_EQUALS(ErrorCodes::NotSecondary, result);
ASSERT_EQUALS("primaries don't sync", result.reason());
@@ -1566,7 +1566,6 @@ TEST_F(TopoCoordTest,
ASSERT_EQUALS(HostAndPort("h5").toString(), response2Obj["prevSyncTarget"].String());
}
-// TODO(dannenberg) figure out a concise name for this
TEST_F(TopoCoordTest, ReplSetGetStatus) {
// This test starts by configuring a TopologyCoordinator as a member of a 4 node replica
// set, with each node in a different state.
@@ -1586,6 +1585,7 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
OpTime oplogDurable(Timestamp(3, 4), 1);
OpTime lastCommittedOpTime(Timestamp(2, 3), 6);
OpTime readConcernMajorityOpTime(Timestamp(4, 5), 7);
+ Timestamp lastStableCheckpointTimestamp(9, 9);
BSONObj initialSyncStatus = BSON("failedInitialSyncAttempts" << 1);
std::string setName = "mySet";
@@ -1629,7 +1629,7 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
getTopoCoord().prepareHeartbeatRequestV1(startupTime + Milliseconds(2), setName, member);
getTopoCoord().processHeartbeatResponse(
heartbeatTime, Milliseconds(4000), member, hbResponseGood);
- makeSelfPrimary();
+ makeSelfPrimary(electionTime);
getTopoCoord().setMyLastAppliedOpTime(oplogProgress, startupTime, false);
getTopoCoord().setMyLastDurableOpTime(oplogDurable, startupTime, false);
getTopoCoord().advanceLastCommittedOpTime(lastCommittedOpTime);
@@ -1642,23 +1642,28 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
curTime,
static_cast<unsigned>(durationCount<Seconds>(uptimeSecs)),
readConcernMajorityOpTime,
- initialSyncStatus},
+ initialSyncStatus,
+ lastStableCheckpointTimestamp},
&statusBuilder,
&resultStatus);
ASSERT_OK(resultStatus);
BSONObj rsStatus = statusBuilder.obj();
+ unittest::log() << rsStatus;
// Test results for all non-self members
ASSERT_EQUALS(setName, rsStatus["set"].String());
ASSERT_EQUALS(curTime.asInt64(), rsStatus["date"].Date().asInt64());
- ASSERT_BSONOBJ_EQ(lastCommittedOpTime.toBSON(),
- rsStatus["optimes"]["lastCommittedOpTime"].Obj());
+ ASSERT_EQUALS(lastStableCheckpointTimestamp,
+ rsStatus["lastStableCheckpointTimestamp"].timestamp());
+ ASSERT_FALSE(rsStatus.hasField("electionTime"));
+ ASSERT_FALSE(rsStatus.hasField("pingMs"));
{
const auto optimes = rsStatus["optimes"].Obj();
ASSERT_BSONOBJ_EQ(readConcernMajorityOpTime.toBSON(),
optimes["readConcernMajorityOpTime"].Obj());
ASSERT_BSONOBJ_EQ(oplogProgress.toBSON(), optimes["appliedOpTime"].Obj());
ASSERT_BSONOBJ_EQ((oplogDurable).toBSON(), optimes["durableOpTime"].Obj());
+ ASSERT_BSONOBJ_EQ(lastCommittedOpTime.toBSON(), optimes["lastCommittedOpTime"].Obj());
}
std::vector<BSONElement> memberArray = rsStatus["members"].Array();
ASSERT_EQUALS(4U, memberArray.size());
@@ -1680,6 +1685,9 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
member0Status["optimeDate"].Date());
ASSERT_EQUALS(timeoutTime, member0Status["lastHeartbeat"].date());
ASSERT_EQUALS(Date_t(), member0Status["lastHeartbeatRecv"].date());
+ ASSERT_FALSE(member0Status.hasField("lastStableCheckpointTimestamp"));
+ ASSERT_FALSE(member0Status.hasField("electionTime"));
+ ASSERT_TRUE(member0Status.hasField("pingMs"));
// Test member 1, the node that's SECONDARY
ASSERT_EQUALS(1, member1Status["_id"].Int());
@@ -1696,6 +1704,9 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
ASSERT_EQUALS(heartbeatTime, member1Status["lastHeartbeat"].date());
ASSERT_EQUALS(Date_t(), member1Status["lastHeartbeatRecv"].date());
ASSERT_EQUALS("READY", member1Status["lastHeartbeatMessage"].str());
+ ASSERT_FALSE(member1Status.hasField("lastStableCheckpointTimestamp"));
+ ASSERT_FALSE(member1Status.hasField("electionTime"));
+ ASSERT_TRUE(member1Status.hasField("pingMs"));
// Test member 2, the node that's UNKNOWN
ASSERT_EQUALS(2, member2Status["_id"].numberInt());
@@ -1708,6 +1719,9 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
ASSERT_TRUE(member2Status.hasField("optimeDate"));
ASSERT_FALSE(member2Status.hasField("lastHearbeat"));
ASSERT_FALSE(member2Status.hasField("lastHearbeatRecv"));
+ ASSERT_FALSE(member2Status.hasField("lastStableCheckpointTimestamp"));
+ ASSERT_FALSE(member2Status.hasField("electionTime"));
+ ASSERT_TRUE(member2Status.hasField("pingMs"));
// Now test results for ourself, the PRIMARY
ASSERT_EQUALS(MemberState::RS_PRIMARY, rsStatus["myState"].numberInt());
@@ -1723,11 +1737,28 @@ TEST_F(TopoCoordTest, ReplSetGetStatus) {
ASSERT_TRUE(selfStatus.hasField("optimeDate"));
ASSERT_EQUALS(Date_t::fromMillisSinceEpoch(oplogProgress.getSecs() * 1000ULL),
selfStatus["optimeDate"].Date());
+ ASSERT_FALSE(selfStatus.hasField("lastStableCheckpointTimestamp"));
+ ASSERT_EQUALS(electionTime, selfStatus["electionTime"].timestamp());
+ ASSERT_FALSE(selfStatus.hasField("pingMs"));
ASSERT_EQUALS(2000, rsStatus["heartbeatIntervalMillis"].numberInt());
ASSERT_BSONOBJ_EQ(initialSyncStatus, rsStatus["initialSyncStatus"].Obj());
- // TODO(spencer): Test electionTime and pingMs are set properly
+ // Test no lastStableCheckpointTimestamp field.
+ BSONObjBuilder statusBuilder2;
+ getTopoCoord().prepareStatusResponse(
+ TopologyCoordinator::ReplSetStatusArgs{
+ curTime,
+ static_cast<unsigned>(durationCount<Seconds>(uptimeSecs)),
+ readConcernMajorityOpTime,
+ initialSyncStatus},
+ &statusBuilder2,
+ &resultStatus);
+ ASSERT_OK(resultStatus);
+ rsStatus = statusBuilder2.obj();
+ unittest::log() << rsStatus;
+ ASSERT_EQUALS(setName, rsStatus["set"].String());
+ ASSERT_FALSE(rsStatus.hasField("lastStableCheckpointTimestamp"));
}
TEST_F(TopoCoordTest, NodeReturnsInvalidReplicaSetConfigInResponseToGetStatusWhenAbsentFromConfig) {
@@ -5253,7 +5284,7 @@ TEST_F(HeartbeatResponseTestV1, NodeWillNotTransitionToPrimaryAfterHearingAboutN
ASSERT_EQUALS(-1, getCurrentPrimaryIndex());
getTopoCoord().changeMemberState_forTest(MemberState::RS_PRIMARY,
firstOpTimeOfTerm.getTimestamp());
- getTopoCoord()._setCurrentPrimaryForTest(getSelfIndex());
+ getTopoCoord().setCurrentPrimary_forTest(getSelfIndex());
// At first transition to primary is OK
ASSERT(getTopoCoord().canCompleteTransitionToPrimary(initialTerm));