diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2020-05-14 10:17:23 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-05-14 20:16:05 +0000 |
commit | b3a13073bb5de88bf62a9c88ac4b2abd9166505b (patch) | |
tree | 12eb73d1ed5f7007f32bc356354bf4d7e6c8e86f | |
parent | ece6d35fbe5337fc9ce22094367905e5cab712ff (diff) | |
download | mongo-b3a13073bb5de88bf62a9c88ac4b2abd9166505b.tar.gz |
SERVER-47557 Write unit test for interaction of quiesce mode and REMOVED state
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl_test.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index 1334d289f44..5806c34b7a6 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -3450,6 +3450,97 @@ TEST_F(ReplCoordTest, DoNotEnterQuiesceModeInStatesOtherThanSecondary) { ASSERT_FALSE(getReplCoord()->enterQuiesceModeIfSecondary()); } +TEST_F(ReplCoordTest, IsMasterReturnsErrorInQuiesceModeWhenNodeIsRemoved) { + init(); + assertStartSuccess(BSON("_id" + << "mySet" + << "version" << 1 << "members" + << BSON_ARRAY(BSON("host" + << "node1:12345" + << "_id" << 1) + << BSON("host" + << "node2:12345" + << "_id" << 2))), + HostAndPort("node1", 12345)); + ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); + getReplCoord()->cancelAndRescheduleElectionTimeout(); + + // Enter quiesce mode. Test that we increment the topology version. + auto topologyVersionBeforeQuiesceMode = getTopoCoord().getTopologyVersion(); + ASSERT(getReplCoord()->enterQuiesceModeIfSecondary()); + auto topologyVersionAfterQuiesceMode = getTopoCoord().getTopologyVersion(); + ASSERT_EQUALS(topologyVersionBeforeQuiesceMode.getCounter() + 1, + topologyVersionAfterQuiesceMode.getCounter()); + + // Remove the node. + auto net = getNet(); + enterNetwork(); + ASSERT_TRUE(net->hasReadyRequests()); + auto noi = net->getNextReadyRequest(); + auto&& request = noi->getRequest(); + ASSERT_EQUALS(HostAndPort("node2", 12345), request.target); + ASSERT_EQUALS("replSetHeartbeat", request.cmdObj.firstElement().fieldNameStringData()); + ReplSetHeartbeatResponse hbResp; + auto removedFromConfig = + ReplSetConfig::parse(BSON("_id" + << "mySet" + << "protocolVersion" << 1 << "version" << 2 << "members" + << BSON_ARRAY(BSON("host" + << "node2:12345" + << "_id" << 2)))); + hbResp.setConfig(removedFromConfig); + hbResp.setConfigVersion(2); + hbResp.setSetName("mySet"); + hbResp.setState(MemberState::RS_SECONDARY); + hbResp.setAppliedOpTimeAndWallTime({OpTime(Timestamp(100, 1), 0), Date_t() + Seconds(100)}); + hbResp.setDurableOpTimeAndWallTime({OpTime(Timestamp(100, 1), 0), Date_t() + Seconds(100)}); + net->scheduleResponse(noi, net->now(), makeResponseStatus(hbResp.toBSON())); + net->runReadyNetworkOperations(); + exitNetwork(); + + // Wait for the node to be removed. Test that we increment the topology version. + ASSERT_OK(getReplCoord()->waitForMemberState(MemberState::RS_REMOVED, Seconds(1))); + ASSERT_EQUALS(removedFromConfig.getConfigVersion(), + getReplCoord()->getConfig().getConfigVersion()); + auto topologyVersionAfterRemoved = getTopoCoord().getTopologyVersion(); + ASSERT_EQUALS(topologyVersionAfterQuiesceMode.getCounter() + 1, + topologyVersionAfterRemoved.getCounter()); + + // Test isMaster requests. + + auto opCtx = makeOperationContext(); + auto maxAwaitTime = Milliseconds(5000); + auto deadline = getNet()->now() + maxAwaitTime; + + // Stale topology version + ASSERT_THROWS_CODE(getReplCoord()->awaitIsMasterResponse( + opCtx.get(), {}, topologyVersionAfterQuiesceMode, deadline), + AssertionException, + ErrorCodes::ShutdownInProgress); + + // Current topology version + ASSERT_THROWS_CODE(getReplCoord()->awaitIsMasterResponse( + opCtx.get(), {}, topologyVersionAfterRemoved, deadline), + AssertionException, + ErrorCodes::ShutdownInProgress); + + // Different process ID + auto differentPid = OID::gen(); + ASSERT_NOT_EQUALS(differentPid, topologyVersionAfterRemoved.getProcessId()); + auto topologyVersionWithDifferentProcessId = + TopologyVersion(differentPid, topologyVersionAfterRemoved.getCounter()); + ASSERT_THROWS_CODE(getReplCoord()->awaitIsMasterResponse( + opCtx.get(), {}, topologyVersionWithDifferentProcessId, deadline), + AssertionException, + ErrorCodes::ShutdownInProgress); + + // No topology version + ASSERT_THROWS_CODE( + getReplCoord()->awaitIsMasterResponse(opCtx.get(), {}, boost::none, boost::none), + AssertionException, + ErrorCodes::ShutdownInProgress); +} + TEST_F(ReplCoordTest, AllIsMasterFieldsRespectHorizon) { init(); const auto primaryHostName = "node1:12345"; |