From 0ebbedb45382c922d4873c2689d67fd80a735e5c Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Thu, 26 Mar 2020 21:46:52 -0400 Subject: SERVER-47097 Add ReplSetMetadata.isPrimary --- src/mongo/db/repl/README.md | 1 + .../repl/check_quorum_for_config_change_test.cpp | 3 +- src/mongo/db/repl/oplog_fetcher_test.cpp | 4 +- ...lication_coordinator_impl_heartbeat_v1_test.cpp | 17 ++-- .../db/repl/replication_coordinator_impl_test.cpp | 92 ++++++++++++---------- src/mongo/db/repl/topology_coordinator.cpp | 3 +- src/mongo/db/repl/topology_coordinator_v1_test.cpp | 6 +- src/mongo/rpc/metadata/repl_set_metadata.cpp | 30 ++++++- src/mongo/rpc/metadata/repl_set_metadata.h | 16 +++- src/mongo/rpc/metadata/repl_set_metadata_test.cpp | 58 +++++++++----- src/mongo/s/catalog/sharding_catalog_test.cpp | 12 ++- 11 files changed, 158 insertions(+), 84 deletions(-) diff --git a/src/mongo/db/repl/README.md b/src/mongo/db/repl/README.md index 20085f7a6ae..a3ffc9afad9 100644 --- a/src/mongo/db/repl/README.md +++ b/src/mongo/db/repl/README.md @@ -320,6 +320,7 @@ It then creates a `ReplSetHeartbeatResponse` object. This includes: 7. The state of the receiving node 8. The receiving node's sync source 9. The receiving node's `ReplicaSetConfig` version +10. Whether the receiving node is primary When the sending node receives the response to the heartbeat, it first processes its `ReplSetMetadata` like before. 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 d592d3fbfba..e84b1881961 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 @@ -449,7 +449,8 @@ TEST_F(CheckQuorumForInitiate, QuorumCheckFailedDueToSetIdMismatch) { rsConfig.getConfigVersion(), unexpectedId, rpc::ReplSetMetadata::kNoPrimary, - -1); + -1, + false); BSONObjBuilder bob; uassertStatusOK(metadata.writeToMetadata(&bob)); diff --git a/src/mongo/db/repl/oplog_fetcher_test.cpp b/src/mongo/db/repl/oplog_fetcher_test.cpp index ab6db9e2358..0309db2f51a 100644 --- a/src/mongo/db/repl/oplog_fetcher_test.cpp +++ b/src/mongo/db/repl/oplog_fetcher_test.cpp @@ -335,8 +335,8 @@ const Date_t OplogFetcherTest::staleWallTime = Date_t() + Seconds(staleOpTime.ge const rpc::OplogQueryMetadata OplogFetcherTest::staleOqMetadata = rpc::OplogQueryMetadata( {staleOpTime, staleWallTime}, staleOpTime, rbid, primaryIndex, syncSourceIndex); -const rpc::ReplSetMetadata OplogFetcherTest::replSetMetadata = - rpc::ReplSetMetadata(1, OpTimeAndWallTime(), OpTime(), 1, OID(), primaryIndex, syncSourceIndex); +const rpc::ReplSetMetadata OplogFetcherTest::replSetMetadata = rpc::ReplSetMetadata( + 1, OpTimeAndWallTime(), OpTime(), 1, OID(), primaryIndex, syncSourceIndex, false); void OplogFetcherTest::setUp() { executor::ThreadPoolExecutorTest::setUp(); 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 c8bb9b6c08c..b497d407730 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 @@ -786,7 +786,8 @@ TEST_F(ReplCoordHBV1Test, IgnoreTheContentsOfMetadataWhenItsReplicaSetIdDoesNotM rsConfig.getConfigVersion(), unexpectedId, 1, - -1); + -1, + true); uassertStatusOK(metadata.writeToMetadata(&responseBuilder)); heartbeatResponse = makeResponseStatus(responseBuilder.obj()); @@ -869,9 +870,10 @@ TEST_F(ReplCoordHBV1Test, {commitPoint, Date_t() + Seconds(commitPoint.getSecs())}, // committed OpTime commitPoint, // visibleOpTime config.getConfigVersion(), - {}, // replset id - 1, // currentPrimaryIndex, - 1); // currentSyncSourceIndex + {}, // replset id + 1, // currentPrimaryIndex, + 1, // currentSyncSourceIndex + true); // isPrimary auto net = getNet(); BSONObjBuilder responseBuilder; @@ -944,9 +946,10 @@ TEST_F(ReplCoordHBV1Test, LastCommittedOpTimeOnlyUpdatesFromHeartbeatIfNotInStar {commitPoint, Date_t() + Seconds(commitPoint.getSecs())}, // committed OpTime commitPoint, // visibleOpTime config.getConfigVersion(), - {}, // replset id - 1, // currentPrimaryIndex, - 1); // currentSyncSourceIndex + {}, // replset id + 1, // currentPrimaryIndex, + 1, // currentSyncSourceIndex + true); // isPrimary auto net = getNet(); BSONObjBuilder responseBuilder; diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index f2f79e2c07b..aff27217a52 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -5645,12 +5645,12 @@ TEST_F(ReplCoordTest, DoNotIgnoreTheContentsOfMetadataWhenItsConfigVersionDoesNo // lower configVersion auto lowerConfigVersion = 1; StatusWith metadata = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName - << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 2) - << "lastCommittedWall" << Date_t() + Seconds(100) - << "lastOpVisible" << BSON("ts" << Timestamp(10, 0) << "t" << 2) - << "configVersion" << lowerConfigVersion << "primaryIndex" << 2 - << "term" << 2 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName << BSON( + "lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 2) << "lastCommittedWall" + << Date_t() + Seconds(100) << "lastOpVisible" + << BSON("ts" << Timestamp(10, 0) << "t" << 2) << "configVersion" + << lowerConfigVersion << "primaryIndex" << 2 << "term" << 2 + << "syncSourceIndex" << 1 << "isPrimary" << true))); getReplCoord()->processReplSetMetadata(metadata.getValue()); // term should advance ASSERT_EQUALS(2, getReplCoord()->getTerm()); @@ -5658,12 +5658,12 @@ TEST_F(ReplCoordTest, DoNotIgnoreTheContentsOfMetadataWhenItsConfigVersionDoesNo // higher configVersion auto higherConfigVersion = 100; StatusWith metadata2 = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName - << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 2) - << "lastCommittedWall" << Date_t() + Seconds(100) - << "lastOpVisible" << BSON("ts" << Timestamp(10, 0) << "t" << 2) - << "configVersion" << higherConfigVersion << "primaryIndex" << 2 - << "term" << 2 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName << BSON( + "lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 2) << "lastCommittedWall" + << Date_t() + Seconds(100) << "lastOpVisible" + << BSON("ts" << Timestamp(10, 0) << "t" << 2) << "configVersion" + << higherConfigVersion << "primaryIndex" << 2 << "term" << 2 + << "syncSourceIndex" << 1 << "isPrimary" << true))); getReplCoord()->processReplSetMetadata(metadata2.getValue()); // term should advance ASSERT_EQUALS(2, getReplCoord()->getTerm()); @@ -5733,11 +5733,12 @@ TEST_F(ReplCoordTest, UpdateTermWhenTheTermFromMetadataIsNewerButNeverUpdateCurr // higher term, should change StatusWith metadata = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName << BSON( - "lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 3) << "lastCommittedWall" - << Date_t() + Seconds(100) << "lastOpVisible" - << BSON("ts" << Timestamp(10, 0) << "t" << 3) << "configVersion" << 2 - << "primaryIndex" << 2 << "term" << 3 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName + << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 3) + << "lastCommittedWall" << Date_t() + Seconds(100) + << "lastOpVisible" << BSON("ts" << Timestamp(10, 0) << "t" << 3) + << "configVersion" << 2 << "primaryIndex" << 2 << "term" << 3 + << "syncSourceIndex" << 1 << "isPrimary" << true))); getReplCoord()->processReplSetMetadata(metadata.getValue()); ASSERT_EQUALS(3, getReplCoord()->getTerm()); ASSERT_EQUALS(-1, getTopoCoord().getCurrentPrimaryIndex()); @@ -5745,11 +5746,12 @@ TEST_F(ReplCoordTest, UpdateTermWhenTheTermFromMetadataIsNewerButNeverUpdateCurr // lower term, should not change StatusWith metadata2 = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName << BSON( - "lastOpCommitted" << BSON("ts" << Timestamp(11, 0) << "t" << 3) << "lastCommittedWall" - << Date_t() + Seconds(100) << "lastOpVisible" - << BSON("ts" << Timestamp(11, 0) << "t" << 3) << "configVersion" << 2 - << "primaryIndex" << 1 << "term" << 2 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName + << BSON("lastOpCommitted" << BSON("ts" << Timestamp(11, 0) << "t" << 3) + << "lastCommittedWall" << Date_t() + Seconds(100) + << "lastOpVisible" << BSON("ts" << Timestamp(11, 0) << "t" << 3) + << "configVersion" << 2 << "primaryIndex" << 1 << "term" << 2 + << "syncSourceIndex" << 1 << "isPrimary" << true))); getReplCoord()->processReplSetMetadata(metadata2.getValue()); ASSERT_EQUALS(3, getReplCoord()->getTerm()); ASSERT_EQUALS(-1, getTopoCoord().getCurrentPrimaryIndex()); @@ -5757,11 +5759,12 @@ TEST_F(ReplCoordTest, UpdateTermWhenTheTermFromMetadataIsNewerButNeverUpdateCurr // same term, should not change StatusWith metadata3 = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName << BSON( - "lastOpCommitted" << BSON("ts" << Timestamp(11, 0) << "t" << 3) << "lastCommittedWall" - << Date_t() + Seconds(100) << "lastOpVisible" - << BSON("ts" << Timestamp(11, 0) << "t" << 3) << "configVersion" << 2 - << "primaryIndex" << 1 << "term" << 3 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName + << BSON("lastOpCommitted" << BSON("ts" << Timestamp(11, 0) << "t" << 3) + << "lastCommittedWall" << Date_t() + Seconds(100) + << "lastOpVisible" << BSON("ts" << Timestamp(11, 0) << "t" << 3) + << "configVersion" << 2 << "primaryIndex" << 1 << "term" << 3 + << "syncSourceIndex" << 1 << "isPrimary" << true))); getReplCoord()->processReplSetMetadata(metadata3.getValue()); ASSERT_EQUALS(3, getReplCoord()->getTerm()); ASSERT_EQUALS(-1, getTopoCoord().getCurrentPrimaryIndex()); @@ -5792,12 +5795,12 @@ TEST_F(ReplCoordTest, // Higher term - should update term but not last committed optime. StatusWith metadata = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName - << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 3) - << "lastCommittedWall" << Date_t() + Seconds(100) - << "lastOpVisible" << BSON("ts" << Timestamp(10, 0) << "t" << 3) - << "configVersion" << config.getConfigVersion() << "primaryIndex" - << 1 << "term" << 3 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName << BSON( + "lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 3) << "lastCommittedWall" + << Date_t() + Seconds(100) << "lastOpVisible" + << BSON("ts" << Timestamp(10, 0) << "t" << 3) << "configVersion" + << config.getConfigVersion() << "primaryIndex" << 1 << "term" << 3 + << "syncSourceIndex" << 1 << "isPrimary" << true))); BSONObjBuilder responseBuilder; ASSERT_OK(metadata.getValue().writeToMetadata(&responseBuilder)); @@ -5904,6 +5907,7 @@ TEST_F(ReplCoordTest, PrepareOplogQueryMetadata) { ASSERT_EQ(replMetadata.getValue().getTerm(), 0); ASSERT_EQ(replMetadata.getValue().getSyncSourceIndex(), -1); ASSERT_EQ(replMetadata.getValue().getPrimaryIndex(), -1); + ASSERT_EQ(replMetadata.getValue().getIsPrimary(), false); } TEST_F(ReplCoordTest, TermAndLastCommittedOpTimeUpdatedFromHeartbeatWhenArbiter) { @@ -5930,12 +5934,12 @@ TEST_F(ReplCoordTest, TermAndLastCommittedOpTimeUpdatedFromHeartbeatWhenArbiter) // Higher term - should update term and lastCommittedOpTime since arbiters learn of the // commit point via heartbeats. StatusWith metadata = rpc::ReplSetMetadata::readFromMetadata(BSON( - rpc::kReplSetMetadataFieldName - << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 1) << "t" << 3) - << "lastCommittedWall" << Date_t() + Seconds(100) - << "lastOpVisible" << BSON("ts" << Timestamp(10, 1) << "t" << 3) - << "configVersion" << config.getConfigVersion() << "primaryIndex" - << 1 << "term" << 3 << "syncSourceIndex" << 1))); + rpc::kReplSetMetadataFieldName << BSON( + "lastOpCommitted" << BSON("ts" << Timestamp(10, 1) << "t" << 3) << "lastCommittedWall" + << Date_t() + Seconds(100) << "lastOpVisible" + << BSON("ts" << Timestamp(10, 1) << "t" << 3) << "configVersion" + << config.getConfigVersion() << "primaryIndex" << 1 << "term" << 3 + << "syncSourceIndex" << 1 << "isPrimary" << true))); BSONObjBuilder responseBuilder; ASSERT_OK(metadata.getValue().writeToMetadata(&responseBuilder)); @@ -6648,8 +6652,14 @@ TEST_F(ReplCoordTest, UpdatePositionCmdHasMetadata) { // Set last committed optime via metadata. Pass dummy Date_t to avoid advanceCommitPoint // invariant. - rpc::ReplSetMetadata syncSourceMetadata( - optime.getTerm(), {optime, Date_t() + Seconds(optime.getSecs())}, optime, 1, OID(), -1, 1); + rpc::ReplSetMetadata syncSourceMetadata(optime.getTerm(), + {optime, Date_t() + Seconds(optime.getSecs())}, + optime, + 1, + OID(), + -1, + 1, + false); getReplCoord()->processReplSetMetadata(syncSourceMetadata); // Pass dummy Date_t to avoid advanceCommitPoint invariant. getReplCoord()->advanceCommitPoint({optime, Date_t() + Seconds(optime.getSecs())}, true); diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp index e1ffa9a6339..3116173a018 100644 --- a/src/mongo/db/repl/topology_coordinator.cpp +++ b/src/mongo/db/repl/topology_coordinator.cpp @@ -3022,7 +3022,8 @@ rpc::ReplSetMetadata TopologyCoordinator::prepareReplSetMetadata( _rsConfig.getConfigVersion(), _rsConfig.getReplicaSetId(), _currentPrimaryIndex, - _rsConfig.findMemberIndexByHostAndPort(getSyncSourceAddress())); + _rsConfig.findMemberIndexByHostAndPort(getSyncSourceAddress()), + _role == Role::kLeader /* isPrimary */); } rpc::OplogQueryMetadata TopologyCoordinator::prepareOplogQueryMetadata(int rbid) const { diff --git a/src/mongo/db/repl/topology_coordinator_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_v1_test.cpp index 06c47afbfa0..01d658c6cb8 100644 --- a/src/mongo/db/repl/topology_coordinator_v1_test.cpp +++ b/src/mongo/db/repl/topology_coordinator_v1_test.cpp @@ -221,13 +221,15 @@ protected: int syncSourceIndex = -1, long long configVersion = -1) { auto configIn = (configVersion != -1) ? configVersion : _currentConfig.getConfigVersion(); + auto isPrimary = primaryIndex != -1 && _topo->getCurrentPrimaryIndex() == primaryIndex; return ReplSetMetadata(_topo->getTerm(), OpTimeAndWallTime(), visibleOpTime, configIn, OID(), primaryIndex, - syncSourceIndex); + syncSourceIndex, + isPrimary); } // Make the OplogQueryMetadata coming from sync source. @@ -4297,7 +4299,7 @@ TEST_F(HeartbeatResponseTestV1, ShouldNotChangeSyncSourceWhenMemberHasYetToHeart TEST_F(HeartbeatResponseTestV1, ShouldNotChangeSyncSourceWhenMemberNotInConfig) { // In this test, the TopologyCoordinator should tell us to change sync sources away from // "host4" since "host4" is absent from the config of version 10. - ReplSetMetadata replMetadata(0, {OpTime(), Date_t()}, OpTime(), 10, OID(), -1, -1); + ReplSetMetadata replMetadata(0, {OpTime(), Date_t()}, OpTime(), 10, OID(), -1, -1, false); ASSERT_TRUE(getTopoCoord().shouldChangeSyncSource( HostAndPort("host4"), replMetadata, makeOplogQueryMetadata(), now())); } diff --git a/src/mongo/rpc/metadata/repl_set_metadata.cpp b/src/mongo/rpc/metadata/repl_set_metadata.cpp index 210412eb4c6..9698ded3eb5 100644 --- a/src/mongo/rpc/metadata/repl_set_metadata.cpp +++ b/src/mongo/rpc/metadata/repl_set_metadata.cpp @@ -53,6 +53,7 @@ const char kReplicaSetIdFieldName[] = "replicaSetId"; const char kPrimaryIndexFieldName[] = "primaryIndex"; const char kSyncSourceIndexFieldName[] = "syncSourceIndex"; const char kTermFieldName[] = "term"; +const char kIsPrimaryFieldName[] = "isPrimary"; } // unnamed namespace @@ -64,14 +65,16 @@ ReplSetMetadata::ReplSetMetadata(long long term, long long configVersion, OID id, int currentPrimaryIndex, - int currentSyncSourceIndex) + int currentSyncSourceIndex, + boost::optional isPrimary) : _lastOpCommitted(std::move(committedOpTime)), _lastOpVisible(std::move(visibleOpTime)), _currentTerm(term), _configVersion(configVersion), _replicaSetId(id), _currentPrimaryIndex(currentPrimaryIndex), - _currentSyncSourceIndex(currentSyncSourceIndex) {} + _currentSyncSourceIndex(currentSyncSourceIndex), + _isPrimary(isPrimary) {} StatusWith ReplSetMetadata::readFromMetadata(const BSONObj& metadataObj) { BSONElement replMetadataElement; @@ -105,6 +108,17 @@ StatusWith ReplSetMetadata::readFromMetadata(const BSONObj& met if (!status.isOK()) return status; + // TODO(SERVER-47125): require the isPrimary field. + boost::optional isPrimary; + if (replMetadataObj.hasField(kIsPrimaryFieldName)) { + bool isPrimaryBool; + status = bsonExtractBooleanField(replMetadataObj, kIsPrimaryFieldName, &isPrimaryBool); + if (!status.isOK()) + return status; + + isPrimary = isPrimaryBool; + } + long long term; status = bsonExtractIntegerField(replMetadataObj, kTermFieldName, &term); if (!status.isOK()) @@ -131,8 +145,14 @@ StatusWith ReplSetMetadata::readFromMetadata(const BSONObj& met } lastOpCommitted.wallTime = wallClockTimeElement.Date(); - return ReplSetMetadata( - term, lastOpCommitted, lastOpVisible, configVersion, id, primaryIndex, syncSourceIndex); + return ReplSetMetadata(term, + lastOpCommitted, + lastOpVisible, + configVersion, + id, + primaryIndex, + syncSourceIndex, + isPrimary); } Status ReplSetMetadata::writeToMetadata(BSONObjBuilder* builder) const { @@ -145,6 +165,7 @@ Status ReplSetMetadata::writeToMetadata(BSONObjBuilder* builder) const { replMetadataBuilder.append(kReplicaSetIdFieldName, _replicaSetId); replMetadataBuilder.append(kPrimaryIndexFieldName, _currentPrimaryIndex); replMetadataBuilder.append(kSyncSourceIndexFieldName, _currentSyncSourceIndex); + replMetadataBuilder.append(kIsPrimaryFieldName, _isPrimary.get()); replMetadataBuilder.doneFast(); return Status::OK(); @@ -158,6 +179,7 @@ std::string ReplSetMetadata::toString() const { output << " Term: " << _currentTerm; output << " Primary Index: " << _currentPrimaryIndex; output << " Sync Source Index: " << _currentSyncSourceIndex; + output << " Is Primary: " << _isPrimary; output << " Last Op Committed: " << _lastOpCommitted.toString(); output << " Last Op Visible: " << _lastOpVisible.toString(); return output; diff --git a/src/mongo/rpc/metadata/repl_set_metadata.h b/src/mongo/rpc/metadata/repl_set_metadata.h index 48b71f8cb69..df2e2ae96b2 100644 --- a/src/mongo/rpc/metadata/repl_set_metadata.h +++ b/src/mongo/rpc/metadata/repl_set_metadata.h @@ -59,7 +59,8 @@ public: long long configVersion, OID replicaSetId, int currentPrimaryIndex, - int currentSyncSourceIndex); + int currentSyncSourceIndex, + boost::optional isPrimary); /** * format: @@ -70,7 +71,8 @@ public: * configVersion: 0, * replicaSetId: ObjectId("..."), // Only present in certain versions and above. * primaryIndex: 0, - * syncSourceIndex: 0 + * syncSourceIndex: 0, + * isPrimary: false // 4.4 and later * } */ static StatusWith readFromMetadata(const BSONObj& doc); @@ -127,6 +129,15 @@ public: return _currentSyncSourceIndex; } + /** + * Returns true if the sender is primary, false if it isn't, and boost::none if this metadata + * is from a pre-4.4 node that doesn't send isPrimary. + */ + // TODO(SERVER-47125): make this a regular bool post-4.4. + boost::optional getIsPrimary() const { + return _isPrimary; + } + /** * Returns the current term from the perspective of the sender. */ @@ -147,6 +158,7 @@ private: OID _replicaSetId; int _currentPrimaryIndex = kNoPrimary; int _currentSyncSourceIndex = -1; + boost::optional _isPrimary; }; } // namespace rpc diff --git a/src/mongo/rpc/metadata/repl_set_metadata_test.cpp b/src/mongo/rpc/metadata/repl_set_metadata_test.cpp index 9775bbf3724..ca89b0f7e64 100644 --- a/src/mongo/rpc/metadata/repl_set_metadata_test.cpp +++ b/src/mongo/rpc/metadata/repl_set_metadata_test.cpp @@ -40,17 +40,18 @@ namespace { using repl::OpTime; using repl::OpTimeAndWallTime; +static const OpTime opTime(Timestamp(1234, 100), 5); +static const OpTime opTime2(Timestamp(7777, 100), 6); +static const Date_t committedWallTime = Date_t() + Seconds(opTime.getSecs()); +static const ReplSetMetadata metadata( + 3, {opTime, committedWallTime}, opTime2, 6, OID("abcdefabcdefabcdefabcdef"), 12, -1, false); + TEST(ReplResponseMetadataTest, ReplicaSetIdNotSet) { - ASSERT_FALSE( - ReplSetMetadata(3, OpTimeAndWallTime(), OpTime(), 6, OID(), 12, -1).hasReplicaSetId()); + ASSERT_FALSE(ReplSetMetadata(3, OpTimeAndWallTime(), OpTime(), 6, OID(), 12, -1, false) + .hasReplicaSetId()); } TEST(ReplResponseMetadataTest, Roundtrip) { - OpTime opTime(Timestamp(1234, 100), 5); - OpTime opTime2(Timestamp(7777, 100), 6); - Date_t committedWallTime = Date_t() + Seconds(opTime.getSecs()); - ReplSetMetadata metadata(3, {opTime, committedWallTime}, opTime2, 6, OID::gen(), 12, -1); - ASSERT_EQ(opTime, metadata.getLastOpCommitted().opTime); ASSERT_EQ(committedWallTime, metadata.getLastOpCommitted().wallTime); ASSERT_EQ(opTime2, metadata.getLastOpVisible()); @@ -59,14 +60,14 @@ TEST(ReplResponseMetadataTest, Roundtrip) { BSONObjBuilder builder; metadata.writeToMetadata(&builder).transitional_ignore(); - BSONObj expectedObj( - BSON(kReplSetMetadataFieldName - << BSON("term" << 3 << "lastOpCommitted" - << BSON("ts" << opTime.getTimestamp() << "t" << opTime.getTerm()) - << "lastCommittedWall" << committedWallTime << "lastOpVisible" - << BSON("ts" << opTime2.getTimestamp() << "t" << opTime2.getTerm()) - << "configVersion" << 6 << "replicaSetId" << metadata.getReplicaSetId() - << "primaryIndex" << 12 << "syncSourceIndex" << -1))); + BSONObj expectedObj(BSON( + kReplSetMetadataFieldName << BSON( + "term" << 3 << "lastOpCommitted" + << BSON("ts" << opTime.getTimestamp() << "t" << opTime.getTerm()) + << "lastCommittedWall" << committedWallTime << "lastOpVisible" + << BSON("ts" << opTime2.getTimestamp() << "t" << opTime2.getTerm()) + << "configVersion" << 6 << "replicaSetId" << metadata.getReplicaSetId() + << "primaryIndex" << 12 << "syncSourceIndex" << -1 << "isPrimary" << false))); BSONObj serializedObj = builder.obj(); ASSERT_BSONOBJ_EQ(expectedObj, serializedObj); @@ -89,21 +90,38 @@ TEST(ReplResponseMetadataTest, Roundtrip) { } TEST(ReplResponseMetadataTest, MetadataCanBeConstructedWhenMissingOplogQueryMetadataFields) { - auto id = OID::gen(); - Date_t committedWallTime = Date_t(); BSONObj obj(BSON(kReplSetMetadataFieldName - << BSON("term" << 3 << "configVersion" << 6 << "replicaSetId" << id - << "lastCommittedWall" << committedWallTime))); + << BSON("term" << 3 << "configVersion" << 6 << "replicaSetId" + << metadata.getReplicaSetId() << "lastCommittedWall" + << committedWallTime << "isPrimary" << false))); auto status = ReplSetMetadata::readFromMetadata(obj); ASSERT_OK(status.getStatus()); const auto& metadata = status.getValue(); ASSERT_EQ(metadata.getConfigVersion(), 6); - ASSERT_EQ(metadata.getReplicaSetId(), id); + ASSERT_EQ(metadata.getReplicaSetId(), metadata.getReplicaSetId()); ASSERT_EQ(metadata.getTerm(), 3); } +TEST(ReplResponseMetadataTest, MetadataCanBeConstructedWhenMissingIsPrimary) { + // TODO(SERVER-47125): delete this test in 4.6 when we can rely on the isPrimary field. + BSONObj obj( + BSON(kReplSetMetadataFieldName + << BSON("term" << 3 << "lastOpCommitted" + << BSON("ts" << opTime.getTimestamp() << "t" << opTime.getTerm()) + << "lastCommittedWall" << committedWallTime << "lastOpVisible" + << BSON("ts" << opTime2.getTimestamp() << "t" << opTime2.getTerm()) + << "configVersion" << 6 << "replicaSetId" << metadata.getReplicaSetId() + << "primaryIndex" << 12 << "syncSourceIndex" << -1))); + + auto status = ReplSetMetadata::readFromMetadata(obj); + ASSERT_OK(status.getStatus()); + + const auto& metadata = status.getValue(); + ASSERT_FALSE(metadata.getIsPrimary().is_initialized()); +} + } // unnamed namespace } // namespace rpc } // namespace mongo diff --git a/src/mongo/s/catalog/sharding_catalog_test.cpp b/src/mongo/s/catalog/sharding_catalog_test.cpp index c0c019db581..6905cfa1e2f 100644 --- a/src/mongo/s/catalog/sharding_catalog_test.cpp +++ b/src/mongo/s/catalog/sharding_catalog_test.cpp @@ -123,7 +123,8 @@ TEST_F(ShardingCatalogClientTest, GetCollectionExisting) { 100, OID(), 30, - -1); + -1, + true); BSONObjBuilder builder; metadata.writeToMetadata(&builder).transitional_ignore(); @@ -196,7 +197,8 @@ TEST_F(ShardingCatalogClientTest, GetDatabaseExisting) { 100, OID(), 30, - -1); + -1, + true); BSONObjBuilder builder; metadata.writeToMetadata(&builder).transitional_ignore(); @@ -423,7 +425,8 @@ TEST_F(ShardingCatalogClientTest, GetChunksForNSWithSortAndLimit) { 100, OID(), 30, - -1); + -1, + true); BSONObjBuilder builder; metadata.writeToMetadata(&builder).transitional_ignore(); @@ -824,7 +827,8 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsValidResultsNoDb) { 100, OID(), 30, - -1); + -1, + true); BSONObjBuilder builder; metadata.writeToMetadata(&builder).transitional_ignore(); -- cgit v1.2.1