diff options
author | Siyuan Zhou <siyuan.zhou@mongodb.com> | 2015-07-29 18:02:37 -0400 |
---|---|---|
committer | Siyuan Zhou <siyuan.zhou@mongodb.com> | 2015-09-23 14:50:56 -0400 |
commit | 2c1facf471cce8254e314755c3c7d2fbc753e5f4 (patch) | |
tree | 8e3f51519dd151cda6799dd52e6d0640c4a0ec05 /src/mongo | |
parent | 75115dfaab9da2854b0fd892ce029781afea2731 (diff) | |
download | mongo-2c1facf471cce8254e314755c3c7d2fbc753e5f4.tar.gz |
SERVER-18498 New replica set configurations have protocolVersion=1 by default
Diffstat (limited to 'src/mongo')
11 files changed, 168 insertions, 107 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index d6de5b44011..031558554c4 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -1891,7 +1891,7 @@ Status ReplicationCoordinatorImpl::processReplSetReconfig(OperationContext* txn, if (args.force) { newConfigObj = incrementConfigVersionByRandom(newConfigObj); } - Status status = newConfig.initialize(newConfigObj); + Status status = newConfig.initialize(newConfigObj, oldConfig.getProtocolVersion() == 1); if (!status.isOK()) { error() << "replSetReconfig got " << status << " while parsing " << newConfigObj; return Status(ErrorCodes::InvalidReplicaSetConfig, status.reason()); @@ -2003,11 +2003,10 @@ Status ReplicationCoordinatorImpl::processReplSetInitiate(OperationContext* txn, } ReplicaSetConfig newConfig; - Status status = newConfig.initialize(configObj); + Status status = newConfig.initialize(configObj, true); if (!status.isOK()) { error() << "replSet initiate got " << status << " while parsing " << configObj; return Status(ErrorCodes::InvalidReplicaSetConfig, status.reason()); - ; } if (replEnabled && newConfig.getReplSetName() != _settings.ourSetName()) { str::stream errmsg; 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 1eb90c747ac..e75ad1a675c 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp @@ -54,10 +54,15 @@ using executor::RemoteCommandResponse; class ReplCoordElectTest : public ReplCoordTest { protected: + void assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost); void simulateEnoughHeartbeatsForElectability(); void simulateFreshEnoughForElectability(); }; +void ReplCoordElectTest::assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost) { + ReplCoordTest::assertStartSuccess(addProtocolVersion(configDoc, 0), selfHost); +} + void ReplCoordElectTest::simulateEnoughHeartbeatsForElectability() { ReplicationCoordinatorImpl* replCoord = getReplCoord(); ReplicaSetConfig rsConfig = replCoord->getReplicaSetConfig_forTest(); 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 fa9843b15ad..0c630f772a5 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp @@ -53,12 +53,17 @@ using executor::RemoteCommandResponse; class ReplCoordHBTest : public ReplCoordTest { protected: + void assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost); void assertMemberState(MemberState expected, std::string msg = ""); ReplSetHeartbeatResponse receiveHeartbeatFrom(const ReplicaSetConfig& rsConfig, int sourceId, const HostAndPort& source); }; +void ReplCoordHBTest::assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost) { + ReplCoordTest::assertStartSuccess(addProtocolVersion(configDoc, 0), selfHost); +} + void ReplCoordHBTest::assertMemberState(const MemberState expected, std::string msg) { const MemberState actual = getReplCoord()->getMemberState(); ASSERT(expected == actual) << "Expected coordinator to report state " << expected.toString() @@ -83,15 +88,15 @@ ReplSetHeartbeatResponse ReplCoordHBTest::receiveHeartbeatFrom(const ReplicaSetC TEST_F(ReplCoordHBTest, JoinExistingReplSet) { logger::globalLogDomain()->setMinimumLoggedSeverity(logger::LogSeverity::Debug(3)); - ReplicaSetConfig rsConfig = - assertMakeRSConfig(BSON("_id" - << "mySet" - << "version" << 3 << "members" - << BSON_ARRAY(BSON("_id" << 1 << "host" - << "h1:1") - << BSON("_id" << 2 << "host" - << "h2:1") << BSON("_id" << 3 << "host" - << "h3:1")))); + ReplicaSetConfig rsConfig = assertMakeRSConfigV0(BSON("_id" + << "mySet" + << "version" << 3 << "members" + << BSON_ARRAY(BSON("_id" << 1 << "host" + << "h1:1") + << BSON("_id" << 2 << "host" + << "h2:1") + << BSON("_id" << 3 << "host" + << "h3:1")))); init("mySet"); addSelf(HostAndPort("h2", 1)); const Date_t startDate = getNet()->now(); @@ -146,15 +151,15 @@ TEST_F(ReplCoordHBTest, DoNotJoinReplSetIfNotAMember) { // Tests that a node in RS_STARTUP will not transition to RS_REMOVED if it receives a // configuration that does not contain it. logger::globalLogDomain()->setMinimumLoggedSeverity(logger::LogSeverity::Debug(3)); - ReplicaSetConfig rsConfig = - assertMakeRSConfig(BSON("_id" - << "mySet" - << "version" << 3 << "members" - << BSON_ARRAY(BSON("_id" << 1 << "host" - << "h1:1") - << BSON("_id" << 2 << "host" - << "h2:1") << BSON("_id" << 3 << "host" - << "h3:1")))); + ReplicaSetConfig rsConfig = assertMakeRSConfigV0(BSON("_id" + << "mySet" + << "version" << 3 << "members" + << BSON_ARRAY(BSON("_id" << 1 << "host" + << "h1:1") + << BSON("_id" << 2 << "host" + << "h2:1") + << BSON("_id" << 3 << "host" + << "h3:1")))); init("mySet"); addSelf(HostAndPort("h4", 1)); const Date_t startDate = getNet()->now(); 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 f7a70005a7f..9fc73d5ec61 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 @@ -94,7 +94,7 @@ TEST_F(ReplCoordHBV1Test, JoinExistingReplSet) { << BSON("_id" << 2 << "host" << "h2:1") << BSON("_id" << 3 << "host" << "h3:1")) - << "settings" << BSON("protocolVersion" << 1))); + << "protocolVersion" << 1)); init("mySet"); addSelf(HostAndPort("h2", 1)); const Date_t startDate = getNet()->now(); @@ -157,7 +157,7 @@ TEST_F(ReplCoordHBV1Test, DoNotJoinReplSetIfNotAMember) { << BSON("_id" << 2 << "host" << "h2:1") << BSON("_id" << 3 << "host" << "h3:1")) - << "settings" << BSON("protocolVersion" << 1))); + << "protocolVersion" << 1)); init("mySet"); addSelf(HostAndPort("h4", 1)); const Date_t startDate = getNet()->now(); 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 e35a58eaae9..d75b2c847fa 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp @@ -100,7 +100,7 @@ TEST_F(ReplCoordTest, ReconfigWithUninitializableConfig) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); BSONObjBuilder result; ReplSetReconfigArgs args; @@ -133,7 +133,7 @@ TEST_F(ReplCoordTest, ReconfigWithWrongReplSetName) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); BSONObjBuilder result; ReplSetReconfigArgs args; @@ -164,7 +164,7 @@ TEST_F(ReplCoordTest, ReconfigValidateFails) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); BSONObjBuilder result; ReplSetReconfigArgs args; @@ -227,7 +227,7 @@ TEST_F(ReplCoordTest, ReconfigQuorumCheckFails) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); Status status(ErrorCodes::InternalError, "Not Set"); stdx::thread reconfigThread(stdx::bind(doReplSetReconfig, getReplCoord(), &status)); @@ -265,7 +265,7 @@ TEST_F(ReplCoordTest, ReconfigStoreLocalConfigDocumentFails) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); Status status(ErrorCodes::InternalError, "Not Set"); getExternalState()->setStoreLocalConfigDocumentStatus( @@ -290,7 +290,7 @@ TEST_F(ReplCoordTest, ReconfigWhileReconfiggingFails) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); Status status(ErrorCodes::InternalError, "Not Set"); // first reconfig @@ -367,7 +367,7 @@ TEST_F(ReplCoordTest, ReconfigSuccessful) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); Status status(ErrorCodes::InternalError, "Not Set"); stdx::thread reconfigThread(stdx::bind(doReplSetReconfig, getReplCoord(), &status)); @@ -406,7 +406,7 @@ TEST_F(ReplCoordTest, ReconfigDuringHBReconfigFails) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ASSERT_TRUE(getReplCoord()->getMemberState().primary()); // set hbreconfig to hang while in progress @@ -461,7 +461,7 @@ TEST_F(ReplCoordTest, HBReconfigDuringReconfigFails) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ASSERT_TRUE(getReplCoord()->getMemberState().primary()); // start reconfigThread diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index cce2003c814..fe2811a8127 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -44,6 +44,7 @@ #include "mongo/db/repl/read_concern_args.h" #include "mongo/db/repl/read_concern_response.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_settings.h" #include "mongo/db/repl/replica_set_config.h" #include "mongo/db/repl/replication_coordinator.h" // ReplSetReconfigArgs @@ -91,6 +92,18 @@ struct OpTimeWithTermZero { Timestamp timestamp; }; +void runSingleNodeElection(ReplicationCoordinatorImpl* replCoord) { + replCoord->setMyLastOptime(OpTime(Timestamp(1, 0), 0)); + ASSERT(replCoord->setFollowerMode(MemberState::RS_SECONDARY)); + replCoord->waitForElectionFinish_forTest(); + + ASSERT(replCoord->isWaitingForApplierToDrain()); + ASSERT(replCoord->getMemberState().primary()) << replCoord->getMemberState().toString(); + + OperationContextReplMock txn; + replCoord->signalDrainComplete(&txn); +} + TEST_F(ReplCoordTest, StartupWithValidLocalConfig) { assertStartSuccess(BSON("_id" << "mySet" @@ -681,7 +694,7 @@ TEST_F(ReplCoordTest, AwaitReplicationReplSetBaseCases) { ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); statusAndDur = getReplCoord()->awaitReplication(&txn, time, writeConcern); ASSERT_OK(statusAndDur.status); @@ -708,7 +721,7 @@ TEST_F(ReplCoordTest, AwaitReplicationNumberOfNodesNonBlocking) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); OpTimeWithTermZero time1(100, 1); OpTimeWithTermZero time2(100, 2); @@ -796,7 +809,7 @@ TEST_F(ReplCoordTest, AwaitReplicationNamedModesNonBlocking) { HostAndPort("node0")); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); OpTime time1(Timestamp(100, 1), 1); OpTime time2(Timestamp(100, 2), 1); @@ -964,7 +977,7 @@ TEST_F(ReplCoordTest, AwaitReplicationNumberOfNodesBlocking) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ReplicationAwaiter awaiter(getReplCoord(), &txn); @@ -1020,7 +1033,7 @@ TEST_F(ReplCoordTest, AwaitReplicationTimeout) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ReplicationAwaiter awaiter(getReplCoord(), &txn); @@ -1058,7 +1071,7 @@ TEST_F(ReplCoordTest, AwaitReplicationShutdown) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ReplicationAwaiter awaiter(getReplCoord(), &txn); @@ -1099,7 +1112,7 @@ TEST_F(ReplCoordTest, AwaitReplicationStepDown) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ReplicationAwaiter awaiter(getReplCoord(), &txn); @@ -1137,7 +1150,7 @@ TEST_F(ReplCoordTest, AwaitReplicationInterrupt) { HostAndPort("node1")); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ReplicationAwaiter awaiter(getReplCoord(), &txn); @@ -1257,7 +1270,7 @@ TEST_F(StepDownTest, StepDownTimeoutAcquiringGlobalLock) { ASSERT_OK(getReplCoord()->setLastOptime_forTest(1, 1, optime1)); ASSERT_OK(getReplCoord()->setLastOptime_forTest(1, 2, optime1)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); // Make sure stepDown cannot grab the global shared lock Lock::GlobalWrite lk(txn.lockState()); @@ -1275,7 +1288,7 @@ TEST_F(StepDownTest, StepDownNoWaiting) { ASSERT_OK(getReplCoord()->setLastOptime_forTest(1, 1, optime1)); ASSERT_OK(getReplCoord()->setLastOptime_forTest(1, 2, optime1)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); enterNetwork(); getNet()->runUntil(getNet()->now() + Seconds(2)); @@ -1283,7 +1296,7 @@ TEST_F(StepDownTest, StepDownNoWaiting) { NetworkInterfaceMock::NetworkOperationIterator noi = getNet()->getNextReadyRequest(); RemoteCommandRequest request = noi->getRequest(); log() << request.target.toString() << " processing " << request.cmdObj; - ReplSetHeartbeatArgs hbArgs; + ReplSetHeartbeatArgsV1 hbArgs; if (hbArgs.initialize(request.cmdObj).isOK()) { ReplSetHeartbeatResponse hbResp; hbResp.setSetName(hbArgs.getSetName()); @@ -1321,9 +1334,7 @@ TEST_F(ReplCoordTest, StepDownAndBackUpSingleNode) { << "test1:1234"))), HostAndPort("test1", 1234)); OperationContextReplMock txn; - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); - - ASSERT_TRUE(getReplCoord()->getMemberState().primary()); + runSingleNodeElection(getReplCoord()); ASSERT_OK(getReplCoord()->stepDown(&txn, true, Milliseconds(0), Milliseconds(1000))); getNet()->enterNetwork(); // Must do this before inspecting the topocoord Date_t stepdownUntil = getNet()->now() + Seconds(1); @@ -1419,7 +1430,7 @@ TEST_F(StepDownTest, StepDownNotCaughtUp) { runner.setWaitTime(Milliseconds(0)); runner.setStepDownTime(Milliseconds(1000)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); runner.start(&txn); Status status = runner.getResult(); @@ -1460,7 +1471,7 @@ TEST_F(StepDownTest, StepDownCatchUp) { runner.setWaitTime(Milliseconds(10000)); runner.setStepDownTime(Milliseconds(60000)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); runner.start(&txn); @@ -1471,7 +1482,7 @@ TEST_F(StepDownTest, StepDownCatchUp) { NetworkInterfaceMock::NetworkOperationIterator noi = getNet()->getNextReadyRequest(); RemoteCommandRequest request = noi->getRequest(); log() << request.target.toString() << " processing " << request.cmdObj; - ReplSetHeartbeatArgs hbArgs; + ReplSetHeartbeatArgsV1 hbArgs; if (hbArgs.initialize(request.cmdObj).isOK()) { ReplSetHeartbeatResponse hbResp; hbResp.setSetName(hbArgs.getSetName()); @@ -1509,7 +1520,7 @@ TEST_F(StepDownTest, InterruptStepDown) { runner.setWaitTime(Milliseconds(10000)); runner.setStepDownTime(Milliseconds(60000)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ASSERT_TRUE(getReplCoord()->getMemberState().primary()); runner.start(&txn); @@ -1592,13 +1603,14 @@ TEST_F(ReplCoordTest, TestPrepareReplSetUpdatePositionCommand) { memberIds.insert(memberId); if (memberId == 0) { // TODO(siyuan) Update when we change replSetUpdatePosition format - ASSERT_EQUALS(optime1.timestamp, entry["optime"].timestamp()); + ASSERT_EQUALS(optime1.timestamp, entry["optime"]["ts"].timestamp()); } else if (memberId == 1) { - ASSERT_EQUALS(optime2.timestamp, entry["optime"].timestamp()); + ASSERT_EQUALS(optime2.timestamp, entry["optime"]["ts"].timestamp()); } else { ASSERT_EQUALS(2, memberId); - ASSERT_EQUALS(optime3.timestamp, entry["optime"].timestamp()); + ASSERT_EQUALS(optime3.timestamp, entry["optime"]["ts"].timestamp()); } + ASSERT_EQUALS(0, entry["optime"]["t"].Number()); } ASSERT_EQUALS(3U, memberIds.size()); // Make sure we saw all 3 nodes } @@ -1916,7 +1928,7 @@ TEST_F(ReplCoordTest, UpdatePositionWithConfigVersionAndMemberIdTest) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 0)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); OpTimeWithTermZero time1(100, 1); OpTimeWithTermZero time2(100, 2); @@ -2016,7 +2028,7 @@ TEST_F(ReplCoordTest, AwaitReplicationReconfigSimple) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 2)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); OpTimeWithTermZero time(100, 2); @@ -2078,7 +2090,7 @@ TEST_F(ReplCoordTest, AwaitReplicationReconfigNodeCountExceedsNumberOfNodes) { HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 2)); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); OpTimeWithTermZero time(100, 2); @@ -2127,8 +2139,8 @@ TEST_F(ReplCoordTest, AwaitReplicationReconfigToSmallerMajority) { << "_id" << 4))), HostAndPort("node1", 12345)); ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); - getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 1), 0)); - simulateSuccessfulElection(); + getReplCoord()->setMyLastOptime(OpTimeWithTermZero(100, 1)); + simulateSuccessfulV1Election(); OpTime time(Timestamp(100, 2), 1); @@ -2193,7 +2205,7 @@ TEST_F(ReplCoordTest, AwaitReplicationMajority) { ASSERT(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY)); OpTime time(Timestamp(100, 0), 1); getReplCoord()->setMyLastOptime(time); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); WriteConcernOptions majorityWriteConcern; majorityWriteConcern.wTimeout = WriteConcernOptions::kNoWaiting; @@ -2244,7 +2256,7 @@ TEST_F(ReplCoordTest, LastCommittedOpTime) { OpTime zero(Timestamp(0, 0), 0); OpTime time(Timestamp(100, 0), 1); getReplCoord()->setMyLastOptime(time); - simulateSuccessfulElection(); + simulateSuccessfulV1Election(); ASSERT_EQUALS(zero, getReplCoord()->getLastCommittedOpTime()); ASSERT_OK(getReplCoord()->setLastOptime_forTest(2, 1, time)); @@ -2389,7 +2401,7 @@ TEST_F(ReplCoordTest, ReadAfterCommittedWhileShutdown) { << "node1:12345" << "_id" << 0))), HostAndPort("node1", 12345)); - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); + runSingleNodeElection(getReplCoord()); getReplCoord()->setMyLastOptime(OpTime(Timestamp(10, 0), 0)); @@ -2410,7 +2422,7 @@ TEST_F(ReplCoordTest, ReadAfterCommittedInterrupted) { << "node1:12345" << "_id" << 0))), HostAndPort("node1", 12345)); - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); + runSingleNodeElection(getReplCoord()); getReplCoord()->setMyLastOptime(OpTime(Timestamp(10, 0), 0)); @@ -2431,12 +2443,12 @@ TEST_F(ReplCoordTest, ReadAfterCommittedGreaterOpTime) { << "node1:12345" << "_id" << 0))), HostAndPort("node1", 12345)); - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); + runSingleNodeElection(getReplCoord()); - getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 0)); - getReplCoord()->onSnapshotCreate(OpTime(Timestamp(100, 0), 0), SnapshotName(1)); + getReplCoord()->setMyLastOptime(OpTime(Timestamp(100, 0), 1)); + getReplCoord()->onSnapshotCreate(OpTime(Timestamp(100, 0), 1), SnapshotName(1)); auto result = getReplCoord()->waitUntilOpTime( - &txn, ReadConcernArgs(OpTime(Timestamp(50, 0), 0), ReadConcernLevel::kMajorityReadConcern)); + &txn, ReadConcernArgs(OpTime(Timestamp(50, 0), 1), ReadConcernLevel::kMajorityReadConcern)); ASSERT_TRUE(result.didWait()); ASSERT_OK(result.getStatus()); @@ -2450,10 +2462,8 @@ TEST_F(ReplCoordTest, ReadAfterCommittedEqualOpTime) { << "node1:12345" << "_id" << 0))), HostAndPort("node1", 12345)); - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); - - - OpTime time(Timestamp(100, 0), 0); + runSingleNodeElection(getReplCoord()); + OpTime time(Timestamp(100, 0), 1); getReplCoord()->setMyLastOptime(time); getReplCoord()->onSnapshotCreate(time, SnapshotName(1)); auto result = getReplCoord()->waitUntilOpTime( @@ -2471,10 +2481,9 @@ TEST_F(ReplCoordTest, ReadAfterCommittedDeferredGreaterOpTime) { << "node1:12345" << "_id" << 0))), HostAndPort("node1", 12345)); - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); - - getReplCoord()->setMyLastOptime(OpTime(Timestamp(0, 0), 0)); - OpTime committedOpTime(Timestamp(200, 0), 0); + runSingleNodeElection(getReplCoord()); + getReplCoord()->setMyLastOptime(OpTime(Timestamp(0, 0), 1)); + OpTime committedOpTime(Timestamp(200, 0), 1); auto pseudoLogOp = stdx::async(stdx::launch::async, [this, &committedOpTime]() { @@ -2485,7 +2494,7 @@ TEST_F(ReplCoordTest, ReadAfterCommittedDeferredGreaterOpTime) { auto result = getReplCoord()->waitUntilOpTime( &txn, - ReadConcernArgs(OpTime(Timestamp(100, 0), 0), ReadConcernLevel::kMajorityReadConcern)); + ReadConcernArgs(OpTime(Timestamp(100, 0), 1), ReadConcernLevel::kMajorityReadConcern)); pseudoLogOp.get(); ASSERT_TRUE(result.didWait()); @@ -2500,11 +2509,10 @@ TEST_F(ReplCoordTest, ReadAfterCommittedDeferredEqualOpTime) { << "node1:12345" << "_id" << 0))), HostAndPort("node1", 12345)); - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); - - getReplCoord()->setMyLastOptime(OpTime(Timestamp(0, 0), 0)); + runSingleNodeElection(getReplCoord()); + getReplCoord()->setMyLastOptime(OpTime(Timestamp(0, 0), 1)); - OpTime opTimeToWait(Timestamp(100, 0), 0); + OpTime opTimeToWait(Timestamp(100, 0), 1); auto pseudoLogOp = stdx::async(stdx::launch::async, @@ -2703,12 +2711,13 @@ TEST_F(ReplCoordTest, CancelAndRescheduleElectionTimeout) { TEST_F(ReplCoordTest, CancelAndRescheduleElectionTimeoutWhenNotProtocolVersion1) { assertStartSuccess(BSON("_id" << "mySet" - << "version" << 2 << "members" << BSON_ARRAY(BSON("host" - << "node1:12345" - << "_id" << 0) - << BSON("host" - << "node2:12345" - << "_id" << 1))), + << "protocolVersion" << 0 << "version" << 2 << "members" + << BSON_ARRAY(BSON("host" + << "node1:12345" + << "_id" << 0) + << BSON("host" + << "node2:12345" + << "_id" << 1))), HostAndPort("node1", 12345)); ReplicationCoordinatorImpl* replCoord = getReplCoord(); ASSERT_TRUE(replCoord->setFollowerMode(MemberState::RS_SECONDARY)); @@ -2914,7 +2923,7 @@ TEST_F(ReplCoordTest, SnapshotCommitting) { << "test1:1234"))), HostAndPort("test1", 1234)); OperationContextReplMock txn; - getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY); + runSingleNodeElection(getReplCoord()); OpTime time1(Timestamp(100, 1), 1); OpTime time2(Timestamp(100, 2), 1); diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp index 7f0b3799217..738626eabdc 100644 --- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp +++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp @@ -61,6 +61,18 @@ ReplicaSetConfig ReplCoordTest::assertMakeRSConfig(const BSONObj& configBson) { return config; } +ReplicaSetConfig ReplCoordTest::assertMakeRSConfigV0(const BSONObj& configBson) { + return assertMakeRSConfig(addProtocolVersion(configBson, 0)); +} + +BSONObj ReplCoordTest::addProtocolVersion(const BSONObj& configDoc, int protocolVersion) { + BSONObjBuilder builder; + builder << "protocolVersion" << protocolVersion; + builder.appendElementsUnique(configDoc); + return builder.obj(); +} + + void ReplCoordTest::setUp() { _settings.replSet = "mySet/node1:12345,node2:54321"; } @@ -149,7 +161,12 @@ void ReplCoordTest::start(const HostAndPort& selfHost) { } void ReplCoordTest::assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost) { - start(configDoc, selfHost); + // Set default protocol version to 1. + if (!configDoc.hasField("protocolVersion")) { + start(addProtocolVersion(configDoc, 1), selfHost); + } else { + start(configDoc, selfHost); + } ASSERT_NE(MemberState::RS_STARTUP, getReplCoord()->getMemberState().s); } diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.h b/src/mongo/db/repl/replication_coordinator_test_fixture.h index 7d64c936fd0..a4023857091 100644 --- a/src/mongo/db/repl/replication_coordinator_test_fixture.h +++ b/src/mongo/db/repl/replication_coordinator_test_fixture.h @@ -67,12 +67,24 @@ public: * Constructs a ReplicaSetConfig from the given BSON, or raises a test failure exception. */ static ReplicaSetConfig assertMakeRSConfig(const BSONObj& configBSON); + static ReplicaSetConfig assertMakeRSConfigV0(const BSONObj& configBson); + + /** + * Adds { protocolVersion: 0 or 1 } to the config. + */ + static BSONObj addProtocolVersion(const BSONObj& configDoc, int protocolVersion); protected: virtual void setUp(); virtual void tearDown(); /** + * Asserts that calling start(configDoc, selfHost) successfully initiates the + * ReplicationCoordinator under test. + */ + virtual void assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost); + + /** * Gets the network mock. */ executor::NetworkInterfaceMock* getNet() { @@ -184,12 +196,6 @@ protected: void simulateSuccessfulV1Election(); /** - * Asserts that calling start(configDoc, selfHost) successfully initiates the - * ReplicationCoordinator under test. - */ - void assertStartSuccess(const BSONObj& configDoc, const HostAndPort& selfHost); - - /** * Shuts down the objects under test. */ void shutdown(); diff --git a/src/mongo/db/repl/topology_coordinator_impl_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_impl_v1_test.cpp index 63f0c80532e..0b0e87e7a70 100644 --- a/src/mongo/db/repl/topology_coordinator_impl_v1_test.cpp +++ b/src/mongo/db/repl/topology_coordinator_impl_v1_test.cpp @@ -2307,12 +2307,14 @@ TEST_F(HeartbeatResponseTestV1, ShouldRespondNegativelyToPV0ElectionCommands) { ASSERT_EQUALS("replset: incompatible replset protocol version: 1", status.reason()); ASSERT_TRUE(responseBuilder.obj().isEmpty()); + BSONObjBuilder electResponseBuilder; ReplicationCoordinator::ReplSetElectArgs electArgs; status = internalErrorStatus; - getTopoCoord().prepareElectResponse(electArgs, Date_t(), OpTime(), &responseBuilder, &status); + getTopoCoord().prepareElectResponse( + electArgs, Date_t(), OpTime(), &electResponseBuilder, &status); ASSERT_EQUALS(ErrorCodes::BadValue, status); ASSERT_EQUALS("replset: incompatible replset protocol version: 1", status.reason()); - ASSERT_TRUE(responseBuilder.obj().isEmpty()); + ASSERT_TRUE(electResponseBuilder.obj().isEmpty()); } TEST_F(HeartbeatResponseTestV1, ShouldChangeSyncSourceFresherMemberIsDown) { diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js index 2547db80a52..548eb0c434a 100644 --- a/src/mongo/shell/replsettest.js +++ b/src/mongo/shell/replsettest.js @@ -472,13 +472,23 @@ ReplSetTest.prototype.initiate = function( cfg , initCmd , timeout ) { } } -ReplSetTest.prototype.reInitiate = function(timeout) { - var master = this.nodes[0]; - var c = master.getDB("local")['system.replset'].findOne(); - var config = this.getReplSetConfig(); - var timeout = timeout || 60000; - config.version = c.version + 1; - this.initiate( config , 'replSetReconfig', timeout ); +ReplSetTest.prototype.reInitiate = function() { + "use strict"; + + var master = this.getMaster(); + var res = master.adminCommand({ replSetGetConfig: 1 }); + assert.commandWorked(res); + var config = this.getReplSetConfig(); + config.version = res.config.version + 1; + + try { + assert.commandWorked(master.adminCommand({replSetReconfig: config})); + } + catch (e) { + if (tojson(e).indexOf("error doing query: failed") < 0) { + throw e; + } + } } ReplSetTest.prototype.getLastOpTimeWritten = function() { diff --git a/src/mongo/shell/shardingtest.js b/src/mongo/shell/shardingtest.js index 99ed173c615..e794e02c874 100644 --- a/src/mongo/shell/shardingtest.js +++ b/src/mongo/shell/shardingtest.js @@ -19,6 +19,8 @@ * contain: * { * nodes {number}: number of replica members. Defaults to 3. + * protocolVersion {number}: protocol version of replset used by the + * replset initiation. * For other options, @see ReplSetTest#start * } * @@ -64,10 +66,10 @@ * specify options that are common all replica members. * useHostname {boolean}: if true, use hostname of machine, * otherwise use localhost - * numReplicas {number} + * numReplicas {number} * } * } - * + * * Member variables: * s {Mongo} - connection to the first mongos * s0, s1, ... {Mongo} - connection to different mongos @@ -193,8 +195,10 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other rsDefaults = Object.merge( rsDefaults, otherParams["rs" + i] ) rsDefaults.nodes = rsDefaults.nodes || otherParams.numReplicas - var numReplicas = rsDefaults.nodes || 3 - delete rsDefaults.nodes + var numReplicas = rsDefaults.nodes || 3; + delete rsDefaults.nodes; + var protocolVersion = rsDefaults.protocolVersion; + delete rsDefaults.protocolVersion; print( "Replica set test!" ) @@ -209,7 +213,11 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other nodes : rs.startSet(rsDefaults), url : rs.getURL() }; - rs.initiate(); + var config = rs.getReplSetConfig(); + if (protocolVersion !== undefined && protocolVersion !== null) { + config.protocolVersion = protocolVersion; + } + rs.initiate(config); this["rs" + i] = rs this._rsObjects[i] = rs |