summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authormatt dannenberg <matt.dannenberg@10gen.com>2015-05-21 09:40:25 -0400
committermatt dannenberg <matt.dannenberg@10gen.com>2015-06-02 05:18:02 -0400
commit34eb51e5d8d05abb56055042da244c30e58dfe08 (patch)
treecdcaf767d19b29f73dfce02ba77f44d982b50efd /src/mongo/db/repl
parentbb8c5523362aa360b02e2c651d643d0ee478b17c (diff)
downloadmongo-34eb51e5d8d05abb56055042da244c30e58dfe08.tar.gz
SERVER-18254 unit test prepareHeartbeatResponseV1()
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/check_quorum_for_config_change_test.cpp2
-rw-r--r--src/mongo/db/repl/repl_set_heartbeat_response.cpp17
-rw-r--r--src/mongo/db/repl/repl_set_heartbeat_response.h13
-rw-r--r--src/mongo/db/repl/repl_set_heartbeat_response_test.cpp63
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp6
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp6
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp4
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp4
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp10
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_test.cpp12
-rw-r--r--src/mongo/db/repl/replication_coordinator_test_fixture.cpp4
-rw-r--r--src/mongo/db/repl/replset_commands.cpp4
-rw-r--r--src/mongo/db/repl/topology_coordinator_impl.cpp1
-rw-r--r--src/mongo/db/repl/topology_coordinator_impl_test.cpp240
14 files changed, 313 insertions, 73 deletions
diff --git a/src/mongo/db/repl/check_quorum_for_config_change_test.cpp b/src/mongo/db/repl/check_quorum_for_config_change_test.cpp
index 5068d0421b1..bc692b43288 100644
--- a/src/mongo/db/repl/check_quorum_for_config_change_test.cpp
+++ b/src/mongo/db/repl/check_quorum_for_config_change_test.cpp
@@ -524,7 +524,7 @@ namespace {
_net->scheduleResponse(noi,
startDate + Milliseconds(10),
ResponseStatus(RemoteCommandResponse(
- hbResp.toBSON(),
+ hbResp.toBSON(false),
Milliseconds(8))));
}
else {
diff --git a/src/mongo/db/repl/repl_set_heartbeat_response.cpp b/src/mongo/db/repl/repl_set_heartbeat_response.cpp
index 4be61c0f279..43b62a43f48 100644
--- a/src/mongo/db/repl/repl_set_heartbeat_response.cpp
+++ b/src/mongo/db/repl/repl_set_heartbeat_response.cpp
@@ -68,7 +68,8 @@ namespace {
} // namespace
- void ReplSetHeartbeatResponse::addToBSON(BSONObjBuilder* builder) const {
+ void ReplSetHeartbeatResponse::addToBSON(BSONObjBuilder* builder,
+ bool isProtocolVersionV1) const {
if (_mismatch) {
*builder << kOkFieldName << 0.0;
*builder << kMismatchFieldName << _mismatch;
@@ -118,23 +119,23 @@ namespace {
builder->append(kPrimaryIdFieldName, _primaryId);
}
if (_opTimeSet) {
- if (_protocolVersion == 0) {
- builder->appendDate(kOpTimeFieldName,
- Date_t::fromMillisSinceEpoch(_opTime.getTimestamp().asLL()));
- }
- else {
+ if (isProtocolVersionV1) {
BSONObjBuilder opTime(builder->subobjStart(kOpTimeFieldName));
opTime.append(kTimestampFieldName, _opTime.getTimestamp());
opTime.append(kTermFieldName, _opTime.getTerm());
opTime.done();
}
+ else {
+ builder->appendDate(kOpTimeFieldName,
+ Date_t::fromMillisSinceEpoch(_opTime.getTimestamp().asLL()));
+ }
}
}
- BSONObj ReplSetHeartbeatResponse::toBSON() const {
+ BSONObj ReplSetHeartbeatResponse::toBSON(bool isProtocolVersionV1) const {
BSONObjBuilder builder;
- addToBSON(&builder);
+ addToBSON(&builder, isProtocolVersionV1);
return builder.obj();
}
diff --git a/src/mongo/db/repl/repl_set_heartbeat_response.h b/src/mongo/db/repl/repl_set_heartbeat_response.h
index f9a49ed603a..8d8fa04b4b5 100644
--- a/src/mongo/db/repl/repl_set_heartbeat_response.h
+++ b/src/mongo/db/repl/repl_set_heartbeat_response.h
@@ -58,17 +58,17 @@ namespace repl {
/**
* Appends all non-default values to "builder".
*/
- void addToBSON(BSONObjBuilder* builder) const;
+ void addToBSON(BSONObjBuilder* builder, bool isProtocolVersionV1) const;
/**
* Returns a BSONObj consisting of all non-default values to "builder".
*/
- BSONObj toBSON() const;
+ BSONObj toBSON(bool isProtocolVersionV1) const;
/**
* Returns toBSON().toString()
*/
- const std::string toString() const { return toBSON().toString(); }
+ const std::string toString() const { return toBSON(true).toString(); }
bool hasDataSet() const { return _hasDataSet; }
bool hasData() const { return _hasData; }
@@ -153,11 +153,6 @@ namespace repl {
void setSyncingTo(const HostAndPort& syncingTo) { _syncingTo = syncingTo; }
/**
- * Sets _protocolVersion to "protocolVersion".
- */
- void setProtocolVersion(int protocolVersion) { _protocolVersion = protocolVersion; }
-
- /**
* Sets _configVersion to "configVersion".
*/
void setConfigVersion(int configVersion) { _configVersion = configVersion; }
@@ -204,8 +199,6 @@ namespace repl {
bool _primaryIdSet = false;
long long _primaryId = -1;
long long _term = -1;
-
- long long _protocolVersion = 0;
};
} // namespace repl
diff --git a/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp b/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp
index 9755bceeb44..29a7812d6f3 100644
--- a/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp
+++ b/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp
@@ -63,12 +63,12 @@ namespace {
ASSERT_EQUALS(HostAndPort(), hbResponse.getSyncingTo());
ASSERT_EQUALS(-1, hbResponse.getConfigVersion());
- BSONObj hbResponseObj = hbResponse.toBSON();
+ BSONObj hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
Status initializeResult = Status::OK();
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toString());
// set version
hbResponse.setConfigVersion(1);
@@ -87,14 +87,14 @@ namespace {
ASSERT_EQUALS(HostAndPort(), hbResponse.getSyncingTo());
ASSERT_EQUALS(1, hbResponse.getConfigVersion());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
ASSERT_EQUALS(1, hbResponseObj["v"].Number());
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toString());
// set setname
hbResponse.setSetName("rs0");
@@ -113,7 +113,7 @@ namespace {
ASSERT_EQUALS(HostAndPort(), hbResponse.getSyncingTo());
ASSERT_EQUALS(1, hbResponse.getConfigVersion());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -121,7 +121,7 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toString());
// set electionTime
hbResponse.setElectionTime(Timestamp(10,0));
@@ -141,7 +141,7 @@ namespace {
ASSERT_EQUALS(1, hbResponse.getConfigVersion());
ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -150,7 +150,7 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toString());
// set opTime
hbResponse.setOpTime(OpTime(Timestamp(10), 0));
@@ -171,7 +171,7 @@ namespace {
ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime());
ASSERT_EQUALS(OpTime(Timestamp(0,10), 0), hbResponse.getOpTime());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -181,7 +181,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set time
hbResponse.setTime(Seconds(10));
@@ -203,7 +204,7 @@ namespace {
ASSERT_EQUALS(OpTime(Timestamp(0,10), 0), hbResponse.getOpTime());
ASSERT_EQUALS(Seconds(10), hbResponse.getTime());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -214,7 +215,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set electable
hbResponse.setElectable(true);
@@ -237,7 +239,7 @@ namespace {
ASSERT_EQUALS(Seconds(10), hbResponse.getTime());
ASSERT_EQUALS(true, hbResponse.isElectable());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -249,7 +251,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set config
ReplicaSetConfig config;
@@ -274,7 +277,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -287,7 +290,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set state
hbResponse.setState(MemberState(MemberState::RS_SECONDARY));
@@ -313,7 +317,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -327,7 +331,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set stateDisagreement
hbResponse.noteStateDisagreement();
@@ -353,7 +358,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -369,7 +374,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set replSet
hbResponse.noteReplSet();
@@ -395,7 +401,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -412,7 +418,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set syncingTo
hbResponse.setSyncingTo(HostAndPort("syncTarget"));
@@ -438,7 +445,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("", hbResponseObj["hbmsg"].String());
@@ -456,7 +463,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set hbmsg
hbResponse.setHbMsg("lub dub");
@@ -481,7 +489,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields());
ASSERT_EQUALS("rs0", hbResponseObj["set"].String());
ASSERT_EQUALS("lub dub", hbResponseObj["hbmsg"].String());
@@ -499,7 +507,8 @@ namespace {
initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
- ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
+ ASSERT_EQUALS(hbResponseObj.toString(),
+ hbResponseObjRoundTripChecker.toBSON(false).toString());
// set mismatched
hbResponse.noteMismatched();
@@ -524,7 +533,7 @@ namespace {
ASSERT_EQUALS(true, hbResponse.isElectable());
ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString());
- hbResponseObj = hbResponse.toBSON();
+ hbResponseObj = hbResponse.toBSON(false);
ASSERT_EQUALS(2, hbResponseObj.nFields());
ASSERT_EQUALS(true, hbResponseObj["mismatch"].trueValue());
diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp
index 0c01373b159..5202e59c65c 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp
@@ -71,7 +71,7 @@ namespace {
hbResp.setConfigVersion(rsConfig.getConfigVersion());
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
}
else {
@@ -354,7 +354,7 @@ namespace {
hbResp2.setState(MemberState::RS_SECONDARY);
BSONObjBuilder respObj2;
respObj2 << "ok" << 1;
- hbResp2.addToBSON(&respObj2);
+ hbResp2.addToBSON(&respObj2, false);
net->runUntil(net->now() + Seconds(10)); // run until we've sent a heartbeat request
const NetworkInterfaceMock::NetworkOperationIterator noi2 = net->getNextReadyRequest();
net->scheduleResponse(noi2, net->now(), makeResponseStatus(respObj2.obj()));
@@ -388,7 +388,7 @@ namespace {
hbResp.setConfigVersion(rsConfig.getConfigVersion());
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
}
else {
diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp
index aa32571fdd5..43d6d2f69b9 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp
@@ -70,7 +70,7 @@ namespace {
hbResp.setState(MemberState::RS_SECONDARY);
hbResp.setConfigVersion(rsConfig.getConfigVersion());
BSONObjBuilder respObj;
- net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON()));
+ net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON(true)));
}
else {
error() << "Black holing unexpected request to " << request.target << ": " <<
@@ -316,7 +316,7 @@ namespace {
hbResp2.setState(MemberState::RS_SECONDARY);
net->runUntil(net->now() + Seconds(10)); // run until we've sent a heartbeat request
const NetworkInterfaceMock::NetworkOperationIterator noi2 = net->getNextReadyRequest();
- net->scheduleResponse(noi2, net->now(), makeResponseStatus(hbResp2.toBSON()));
+ net->scheduleResponse(noi2, net->now(), makeResponseStatus(hbResp2.toBSON(true)));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
@@ -346,7 +346,7 @@ namespace {
hbResp.setState(MemberState::RS_SECONDARY);
hbResp.setConfigVersion(rsConfig.getConfigVersion());
BSONObjBuilder respObj;
- net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON()));
+ net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON(true)));
}
else {
error() << "Black holing unexpected request to " << request.target << ": " <<
diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp
index e9015a1222a..dadc7b5a026 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp
@@ -114,7 +114,7 @@ namespace {
hbResp.setConfig(rsConfig);
BSONObjBuilder responseBuilder;
responseBuilder << "ok" << 1;
- hbResp.addToBSON(&responseBuilder);
+ hbResp.addToBSON(&responseBuilder, false);
net->scheduleResponse(noi,
startDate + Milliseconds(200),
makeResponseStatus(responseBuilder.obj()));
@@ -175,7 +175,7 @@ namespace {
hbResp.setConfig(rsConfig);
BSONObjBuilder responseBuilder;
responseBuilder << "ok" << 1;
- hbResp.addToBSON(&responseBuilder);
+ hbResp.addToBSON(&responseBuilder, false);
net->scheduleResponse(noi,
startDate + Milliseconds(200),
makeResponseStatus(responseBuilder.obj()));
diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp
index 7a64aad68d8..5851b6e7e7b 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp
@@ -114,7 +114,7 @@ namespace {
hbResp.setConfig(rsConfig);
BSONObjBuilder responseBuilder;
responseBuilder << "ok" << 1;
- hbResp.addToBSON(&responseBuilder);
+ hbResp.addToBSON(&responseBuilder, true);
net->scheduleResponse(noi,
startDate + Milliseconds(200),
makeResponseStatus(responseBuilder.obj()));
@@ -175,7 +175,7 @@ namespace {
hbResp.setConfig(rsConfig);
BSONObjBuilder responseBuilder;
responseBuilder << "ok" << 1;
- hbResp.addToBSON(&responseBuilder);
+ hbResp.addToBSON(&responseBuilder, true);
net->scheduleResponse(noi,
startDate + Milliseconds(200),
makeResponseStatus(responseBuilder.obj()));
diff --git a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp
index c91a558e59c..e4a0310daf3 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp
@@ -224,7 +224,7 @@ namespace {
hbResp.setConfigVersion(5);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
@@ -262,7 +262,7 @@ namespace {
hbResp.setConfigVersion(2);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
@@ -371,7 +371,7 @@ namespace {
hbResp.setConfigVersion(2);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
@@ -414,7 +414,7 @@ namespace {
hbResp2.setState(MemberState::RS_SECONDARY);
BSONObjBuilder respObj2;
respObj2 << "ok" << 1;
- hbResp2.addToBSON(&respObj2);
+ hbResp2.addToBSON(&respObj2, false);
net->runUntil(net->now() + Seconds(10)); // run until we've sent a heartbeat request
const NetworkInterfaceMock::NetworkOperationIterator noi2 = net->getNextReadyRequest();
net->scheduleResponse(noi2, net->now(), makeResponseStatus(respObj2.obj()));
@@ -473,7 +473,7 @@ namespace {
hbResp.setState(MemberState::RS_SECONDARY);
BSONObjBuilder respObj2;
respObj2 << "ok" << 1;
- hbResp.addToBSON(&respObj2);
+ hbResp.addToBSON(&respObj2, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj2.obj()));
logger::globalLogDomain()->setMinimumLoggedSeverity(logger::LogSeverity::Debug(1));
diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
index fdde13dbc71..66b2001755c 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -285,7 +285,7 @@ namespace {
getNet()->scheduleResponse(
noi,
startDate + Milliseconds(10),
- ResponseStatus(RemoteCommandResponse(hbResp.toBSON(), Milliseconds(8))));
+ ResponseStatus(RemoteCommandResponse(hbResp.toBSON(false), Milliseconds(8))));
getNet()->runUntil(startDate + Milliseconds(10));
getNet()->exitNetwork();
ASSERT_EQUALS(startDate + Milliseconds(10), getNet()->now());
@@ -974,7 +974,7 @@ namespace {
hbResp.setOpTime(optime1);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
getNet()->scheduleResponse(noi, getNet()->now(), makeResponseStatus(respObj.obj()));
}
while (getNet()->hasReadyRequests()) {
@@ -1162,7 +1162,7 @@ namespace {
hbResp.setOpTime(optime2);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
getNet()->scheduleResponse(noi, getNet()->now(), makeResponseStatus(respObj.obj()));
}
while (getNet()->hasReadyRequests()) {
@@ -1683,7 +1683,7 @@ namespace {
hbResp.setConfigVersion(2);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
@@ -1753,7 +1753,7 @@ namespace {
hbResp.setConfigVersion(2);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
@@ -1821,7 +1821,7 @@ namespace {
hbResp.setConfigVersion(2);
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
net->runReadyNetworkOperations();
getNet()->exitNetwork();
diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
index baaff04e10e..e7bd4d93703 100644
--- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
+++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
@@ -184,7 +184,7 @@ namespace {
hbResp.setSetName(rsConfig.getReplSetName());
hbResp.setState(MemberState::RS_SECONDARY);
hbResp.setConfigVersion(rsConfig.getConfigVersion());
- net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON()));
+ net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON(true)));
}
else if (request.cmdObj.firstElement().fieldNameStringData() == "replSetRequestVotes") {
@@ -246,7 +246,7 @@ namespace {
hbResp.setConfigVersion(rsConfig.getConfigVersion());
BSONObjBuilder respObj;
respObj << "ok" << 1;
- hbResp.addToBSON(&respObj);
+ hbResp.addToBSON(&respObj, false);
net->scheduleResponse(noi, net->now(), makeResponseStatus(respObj.obj()));
}
else if (request.cmdObj.firstElement().fieldNameStringData() == "replSetFresh") {
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index e1954949e96..37e1dfe9deb 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -719,7 +719,7 @@ namespace {
ReplSetHeartbeatResponse response;
status = getGlobalReplicationCoordinator()->processHeartbeatV1(args, &response);
if (status.isOK())
- response.addToBSON(&result);
+ response.addToBSON(&result, true);
return appendCommandStatus(result, status);
}
// else: fall through to old heartbeat protocol as it is likely that
@@ -740,7 +740,7 @@ namespace {
ReplSetHeartbeatResponse response;
status = getGlobalReplicationCoordinator()->processHeartbeat(args, &response);
if (status.isOK())
- response.addToBSON(&result);
+ response.addToBSON(&result, false);
return appendCommandStatus(result, status);
}
} cmdReplSetHeartbeat;
diff --git a/src/mongo/db/repl/topology_coordinator_impl.cpp b/src/mongo/db/repl/topology_coordinator_impl.cpp
index 73346552192..1da923df904 100644
--- a/src/mongo/db/repl/topology_coordinator_impl.cpp
+++ b/src/mongo/db/repl/topology_coordinator_impl.cpp
@@ -750,7 +750,6 @@ namespace {
const OpTime& lastOpApplied,
ReplSetHeartbeatResponse* response) {
- response->setProtocolVersion(1);
// Verify that replica set names match
const std::string rshb = args.getSetName();
if (ourSetName != rshb) {
diff --git a/src/mongo/db/repl/topology_coordinator_impl_test.cpp b/src/mongo/db/repl/topology_coordinator_impl_test.cpp
index 2160f7ed20a..5433f495f22 100644
--- a/src/mongo/db/repl/topology_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/topology_coordinator_impl_test.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/repl/heartbeat_response_action.h"
#include "mongo/db/repl/member_heartbeat_data.h"
#include "mongo/db/repl/repl_set_heartbeat_args.h"
+#include "mongo/db/repl/repl_set_heartbeat_args_v1.h"
#include "mongo/db/repl/repl_set_heartbeat_response.h"
#include "mongo/db/repl/repl_set_declare_election_winner_args.h"
#include "mongo/db/repl/repl_set_request_votes_args.h"
@@ -2068,7 +2069,7 @@ namespace {
"rs0",
election,
&hbResp));
- ASSERT(!hbResp.hasIsElectable() || hbResp.isElectable()) << hbResp.toBSON().toString();
+ ASSERT(!hbResp.hasIsElectable() || hbResp.isElectable()) << hbResp.toString();
}
TEST_F(HeartbeatResponseTest, UpdateHeartbeatDataDoNotStepDownSelfForHighPriorityStaleNode) {
@@ -3363,6 +3364,243 @@ namespace {
};
+ class PrepareHeartbeatResponseV1Test : public TopoCoordTest {
+ public:
+
+ virtual void setUp() {
+ TopoCoordTest::setUp();
+ updateConfig(BSON("_id" << "rs0" <<
+ "version" << 1 <<
+ "members" << BSON_ARRAY(
+ BSON("_id" << 10 << "host" << "hself") <<
+ BSON("_id" << 20 << "host" << "h2") <<
+ BSON("_id" << 30 << "host" << "h3")) <<
+ "protocolVersion" << 1),
+ 0);
+ setSelfMemberState(MemberState::RS_SECONDARY);
+ }
+
+ void prepareHeartbeatResponseV1(const ReplSetHeartbeatArgsV1& args,
+ OpTime lastOpApplied,
+ ReplSetHeartbeatResponse* response,
+ Status* result) {
+ *result = getTopoCoord().prepareHeartbeatResponseV1(now()++,
+ args,
+ "rs0",
+ lastOpApplied,
+ response);
+ }
+
+ };
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseBadSetName) {
+ // set up args with incorrect replset name
+ ReplSetHeartbeatArgsV1 args;
+ args.setSetName("rs1");
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ startCapturingLogMessages();
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ stopCapturingLogMessages();
+ ASSERT_EQUALS(ErrorCodes::InconsistentReplicaSetNames, result);
+ ASSERT(result.reason().find("repl set names do not match")) << "Actual string was \"" <<
+ result.reason() << '"';
+ ASSERT_EQUALS(1,
+ countLogLinesContaining("replSet set names do not match, ours: rs0; remote "
+ "node's: rs1"));
+ // only protocolVersion should be set in this failure case
+ ASSERT_EQUALS("", response.getReplicaSetName());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseWhenOutOfSet) {
+ // reconfig self out of set
+ updateConfig(BSON("_id" << "rs0" <<
+ "version" << 3 <<
+ "members" << BSON_ARRAY(
+ BSON("_id" << 20 << "host" << "h2") <<
+ BSON("_id" << 30 << "host" << "h3")) <<
+ "protocolVersion" << 1),
+ -1);
+ ReplSetHeartbeatArgsV1 args;
+ args.setSetName("rs0");
+ args.setSenderId(20);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ ASSERT_EQUALS(ErrorCodes::InvalidReplicaSetConfig, result);
+ ASSERT(result.reason().find("replica set configuration is invalid or does not include us"))
+ << "Actual string was \"" << result.reason() << '"';
+ // only protocolVersion should be set in this failure case
+ ASSERT_EQUALS("", response.getReplicaSetName());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseFromSelf) {
+ // set up args with our id as the senderId
+ ReplSetHeartbeatArgsV1 args;
+ args.setSetName("rs0");
+ args.setSenderId(10);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ ASSERT_EQUALS(ErrorCodes::BadValue, result);
+ ASSERT(result.reason().find("from member with the same member ID as our self")) <<
+ "Actual string was \"" << result.reason() << '"';
+ // only protocolVersion should be set in this failure case
+ ASSERT_EQUALS("", response.getReplicaSetName());
+ }
+
+ TEST_F(TopoCoordTest, PrepareHeartbeatResponseV1NoConfigYet) {
+ // set up args and acknowledge sender
+ ReplSetHeartbeatArgsV1 args;
+ args.setSetName("rs0");
+ args.setSenderId(20);
+ ReplSetHeartbeatResponse response;
+ // prepare response and check the results
+ Status result = getTopoCoord().prepareHeartbeatResponseV1(now()++,
+ args,
+ "rs0",
+ OpTime(),
+ &response);
+ ASSERT_OK(result);
+ // this change to true because we can now see a majority, unlike in the previous cases
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_STARTUP, response.getState().s);
+ ASSERT_EQUALS(OpTime(), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(-2, response.getConfigVersion());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseSenderIDMissing) {
+ // set up args without a senderID
+ ReplSetHeartbeatArgsV1 args;
+ args.setSetName("rs0");
+ args.setConfigVersion(1);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ // prepare response and check the results
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ ASSERT_OK(result);
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s);
+ ASSERT_EQUALS(OpTime(), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(1, response.getConfigVersion());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseSenderIDNotInConfig) {
+ // set up args with a senderID which is not present in our config
+ ReplSetHeartbeatArgsV1 args;
+ args.setSetName("rs0");
+ args.setConfigVersion(1);
+ args.setSenderId(2);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ // prepare response and check the results
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ ASSERT_OK(result);
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s);
+ ASSERT_EQUALS(OpTime(), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(1, response.getConfigVersion());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseConfigVersionLow) {
+ // set up args with a config version lower than ours
+ ReplSetHeartbeatArgsV1 args;
+ args.setConfigVersion(0);
+ args.setSetName("rs0");
+ args.setSenderId(20);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ // prepare response and check the results
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ ASSERT_OK(result);
+ ASSERT_TRUE(response.hasConfig());
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s);
+ ASSERT_EQUALS(OpTime(), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(1, response.getConfigVersion());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseConfigVersionHigh) {
+ // set up args with a config version higher than ours
+ ReplSetHeartbeatArgsV1 args;
+ args.setConfigVersion(10);
+ args.setSetName("rs0");
+ args.setSenderId(20);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ // prepare response and check the results
+ prepareHeartbeatResponseV1(args, OpTime(), &response, &result);
+ ASSERT_OK(result);
+ ASSERT_FALSE(response.hasConfig());
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s);
+ ASSERT_EQUALS(OpTime(), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(1, response.getConfigVersion());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseAsPrimary) {
+ makeSelfPrimary(Timestamp(10,0));
+
+ ReplSetHeartbeatArgsV1 args;
+ args.setConfigVersion(1);
+ args.setSetName("rs0");
+ args.setSenderId(20);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ // prepare response and check the results
+ prepareHeartbeatResponseV1(args, OpTime(Timestamp(11,0), 0), &response, &result);
+ ASSERT_OK(result);
+ ASSERT_FALSE(response.hasConfig());
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_PRIMARY, response.getState().s);
+ ASSERT_EQUALS(OpTime(Timestamp(11,0), 0), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(1, response.getConfigVersion());
+ }
+
+ TEST_F(PrepareHeartbeatResponseV1Test, PrepareHeartbeatResponseWithSyncSource) {
+ // get a sync source
+ heartbeatFromMember(HostAndPort("h3"), "rs0",
+ MemberState::RS_SECONDARY, OpTime());
+ heartbeatFromMember(HostAndPort("h3"), "rs0",
+ MemberState::RS_SECONDARY, OpTime());
+ heartbeatFromMember(HostAndPort("h2"), "rs0",
+ MemberState::RS_SECONDARY, OpTime(Timestamp(1,0), 0));
+ heartbeatFromMember(HostAndPort("h2"), "rs0",
+ MemberState::RS_SECONDARY, OpTime(Timestamp(1,0), 0));
+ getTopoCoord().chooseNewSyncSource(now()++, OpTime());
+
+ // set up args
+ ReplSetHeartbeatArgsV1 args;
+ args.setConfigVersion(1);
+ args.setSetName("rs0");
+ args.setSenderId(20);
+ ReplSetHeartbeatResponse response;
+ Status result(ErrorCodes::InternalError, "prepareHeartbeatResponse didn't set result");
+
+ // prepare response and check the results
+ prepareHeartbeatResponseV1(args, OpTime(Timestamp(100,0), 0), &response, &result);
+ ASSERT_OK(result);
+ ASSERT_FALSE(response.hasConfig());
+ ASSERT_EQUALS("rs0", response.getReplicaSetName());
+ ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s);
+ ASSERT_EQUALS(OpTime(Timestamp(100,0), 0), response.getOpTime());
+ ASSERT_EQUALS(0, response.getTerm());
+ ASSERT_EQUALS(1, response.getConfigVersion());
+ ASSERT_EQUALS(HostAndPort("h2"), response.getSyncingTo());
+ }
+
TEST_F(PrepareHeartbeatResponseTest, PrepareHeartbeatResponseBadProtocolVersion) {
// set up args with bad protocol version
ReplSetHeartbeatArgs args;