diff options
author | matt dannenberg <matt.dannenberg@10gen.com> | 2015-05-21 09:40:25 -0400 |
---|---|---|
committer | matt dannenberg <matt.dannenberg@10gen.com> | 2015-06-02 05:18:02 -0400 |
commit | 34eb51e5d8d05abb56055042da244c30e58dfe08 (patch) | |
tree | cdcaf767d19b29f73dfce02ba77f44d982b50efd /src/mongo/db | |
parent | bb8c5523362aa360b02e2c651d643d0ee478b17c (diff) | |
download | mongo-34eb51e5d8d05abb56055042da244c30e58dfe08.tar.gz |
SERVER-18254 unit test prepareHeartbeatResponseV1()
Diffstat (limited to 'src/mongo/db')
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; |