diff options
Diffstat (limited to 'src/mongo/client/dbclient_rs_test.cpp')
-rw-r--r-- | src/mongo/client/dbclient_rs_test.cpp | 1237 |
1 files changed, 611 insertions, 626 deletions
diff --git a/src/mongo/client/dbclient_rs_test.cpp b/src/mongo/client/dbclient_rs_test.cpp index 7f0e1d703e1..86c893b18b2 100644 --- a/src/mongo/client/dbclient_rs_test.cpp +++ b/src/mongo/client/dbclient_rs_test.cpp @@ -50,776 +50,761 @@ #include "mongo/util/assert_util.h" namespace { - using std::make_pair; - using std::map; - using std::pair; - using std::string; - using std::unique_ptr; - using std::vector; - - using mongo::AssertionException; - using mongo::BSONArray; - using mongo::BSONElement; - using mongo::BSONField; - using mongo::BSONObj; - using mongo::BSONObjBuilder; - using mongo::ConnectionString; - using mongo::DBClientCursor; - using mongo::DBClientReplicaSet; - using mongo::HostAndPort; - using mongo::HostField; - using mongo::IdentityNS; - using mongo::MockReplicaSet; - using mongo::Query; - using mongo::ReadPreference; - using mongo::ReadPreferenceSetting; - using mongo::ReplicaSetMonitor; - using mongo::ScopedDbConnection; - using mongo::StringData; - using mongo::TagSet; - using mongo::rpc::ServerSelectionMetadata; - - /** - * Constructs a metadata object containing the passed server selection metadata. - */ - BSONObj makeMetadata(ReadPreference rp, TagSet tagSet, bool secondaryOk) { - BSONObjBuilder metadataBob; - ServerSelectionMetadata ssm(secondaryOk, - ReadPreferenceSetting(rp, tagSet)); - uassertStatusOK(ssm.writeToMetadata(&metadataBob)); - return metadataBob.obj(); - } +using std::make_pair; +using std::map; +using std::pair; +using std::string; +using std::unique_ptr; +using std::vector; + +using mongo::AssertionException; +using mongo::BSONArray; +using mongo::BSONElement; +using mongo::BSONField; +using mongo::BSONObj; +using mongo::BSONObjBuilder; +using mongo::ConnectionString; +using mongo::DBClientCursor; +using mongo::DBClientReplicaSet; +using mongo::HostAndPort; +using mongo::HostField; +using mongo::IdentityNS; +using mongo::MockReplicaSet; +using mongo::Query; +using mongo::ReadPreference; +using mongo::ReadPreferenceSetting; +using mongo::ReplicaSetMonitor; +using mongo::ScopedDbConnection; +using mongo::StringData; +using mongo::TagSet; +using mongo::rpc::ServerSelectionMetadata; - /** - * Basic fixture with one primary and one secondary. - */ - class BasicRS: public mongo::unittest::Test { - protected: - void setUp() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(new MockReplicaSet("test", 2)); - ConnectionString::setConnectionHook( - mongo::MockConnRegistry::get()->getConnStrHook()); - } +/** + * Constructs a metadata object containing the passed server selection metadata. + */ +BSONObj makeMetadata(ReadPreference rp, TagSet tagSet, bool secondaryOk) { + BSONObjBuilder metadataBob; + ServerSelectionMetadata ssm(secondaryOk, ReadPreferenceSetting(rp, tagSet)); + uassertStatusOK(ssm.writeToMetadata(&metadataBob)); + return metadataBob.obj(); +} - void tearDown() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(); +/** + * Basic fixture with one primary and one secondary. + */ +class BasicRS : public mongo::unittest::Test { +protected: + void setUp() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(new MockReplicaSet("test", 2)); + ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook()); + } - mongo::ScopedDbConnection::clearPool(); - } + void tearDown() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(); - MockReplicaSet* getReplSet() { - return _replSet.get(); - } + mongo::ScopedDbConnection::clearPool(); + } - private: - std::unique_ptr<MockReplicaSet> _replSet; - }; - - void assertOneOfNodesSelected(MockReplicaSet* replSet, - ReadPreference rp, - const std::vector<std::string> hostNames) { - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); - bool secondaryOk = (rp != ReadPreference::PrimaryOnly); - auto tagSet = secondaryOk ? TagSet() : TagSet::primaryOnly(); - // We need the command to be a "SecOk command" - auto res = replConn.runCommandWithMetadata("foo", "dbStats", - makeMetadata(rp, tagSet, secondaryOk), - BSON("dbStats" << 1)); - std::unordered_set<HostAndPort> hostSet; - for (const auto& hostName : hostNames) { - hostSet.emplace(hostName); - } - ASSERT_EQ(hostSet.count(HostAndPort{res->getCommandReply()["host"].str()}), 1u); + MockReplicaSet* getReplSet() { + return _replSet.get(); } - void assertNodeSelected(MockReplicaSet* replSet, ReadPreference rp, StringData host) { - assertOneOfNodesSelected(replSet, rp, std::vector<std::string>{host.toString()}); +private: + std::unique_ptr<MockReplicaSet> _replSet; +}; + +void assertOneOfNodesSelected(MockReplicaSet* replSet, + ReadPreference rp, + const std::vector<std::string> hostNames) { + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); + ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); + bool secondaryOk = (rp != ReadPreference::PrimaryOnly); + auto tagSet = secondaryOk ? TagSet() : TagSet::primaryOnly(); + // We need the command to be a "SecOk command" + auto res = replConn.runCommandWithMetadata( + "foo", "dbStats", makeMetadata(rp, tagSet, secondaryOk), BSON("dbStats" << 1)); + std::unordered_set<HostAndPort> hostSet; + for (const auto& hostName : hostNames) { + hostSet.emplace(hostName); } + ASSERT_EQ(hostSet.count(HostAndPort{res->getCommandReply()["host"].str()}), 1u); +} - TEST_F(BasicRS, QueryPrimary) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +void assertNodeSelected(MockReplicaSet* replSet, ReadPreference rp, StringData host) { + assertOneOfNodesSelected(replSet, rp, std::vector<std::string>{host.toString()}); +} - Query query; - query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); +TEST_F(BasicRS, QueryPrimary) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - } + Query query; + query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); - TEST_F(BasicRS, CommandPrimary) { - assertNodeSelected(getReplSet(), ReadPreference::PrimaryOnly, getReplSet()->getPrimary()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); +} - TEST_F(BasicRS, QuerySecondaryOnly) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(BasicRS, CommandPrimary) { + assertNodeSelected(getReplSet(), ReadPreference::PrimaryOnly, getReplSet()->getPrimary()); +} - Query query; - query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); +TEST_F(BasicRS, QuerySecondaryOnly) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); - } + Query query; + query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); - TEST_F(BasicRS, CommandSecondaryOnly) { - assertOneOfNodesSelected(getReplSet(), - ReadPreference::SecondaryOnly, - getReplSet()->getSecondaries()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); +} - TEST_F(BasicRS, QueryPrimaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(BasicRS, CommandSecondaryOnly) { + assertOneOfNodesSelected( + getReplSet(), ReadPreference::SecondaryOnly, getReplSet()->getSecondaries()); +} - // Need up-to-date view, since either host is valid if view is stale. - ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); +TEST_F(BasicRS, QueryPrimaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + // Need up-to-date view, since either host is valid if view is stale. + ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - } + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - TEST_F(BasicRS, CommandPrimaryPreferred) { - assertNodeSelected(getReplSet(), - ReadPreference::PrimaryPreferred, - getReplSet()->getPrimary()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); +} - TEST_F(BasicRS, QuerySecondaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(BasicRS, CommandPrimaryPreferred) { + assertNodeSelected(getReplSet(), ReadPreference::PrimaryPreferred, getReplSet()->getPrimary()); +} - // Need up-to-date view, since either host is valid if view is stale. - ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); +TEST_F(BasicRS, QuerySecondaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); + // Need up-to-date view, since either host is valid if view is stale. + ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); + Query query; + query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); + + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); +} + +TEST_F(BasicRS, CommandSecondaryPreferred) { + assertOneOfNodesSelected( + getReplSet(), ReadPreference::SecondaryPreferred, getReplSet()->getSecondaries()); +} + +/** + * Setup for 2 member replica set will all of the nodes down. + */ +class AllNodesDown : public mongo::unittest::Test { +protected: + void setUp() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(new MockReplicaSet("test", 2)); + ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook()); + + vector<HostAndPort> hostList(_replSet->getHosts()); + for (vector<HostAndPort>::const_iterator iter = hostList.begin(); iter != hostList.end(); + ++iter) { + _replSet->kill(iter->toString()); + } } - TEST_F(BasicRS, CommandSecondaryPreferred) { - assertOneOfNodesSelected(getReplSet(), - ReadPreference::SecondaryPreferred, - getReplSet()->getSecondaries()); + void tearDown() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(); + + mongo::ScopedDbConnection::clearPool(); } - /** - * Setup for 2 member replica set will all of the nodes down. - */ - class AllNodesDown: public mongo::unittest::Test { - protected: - void setUp() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(new MockReplicaSet("test", 2)); - ConnectionString::setConnectionHook( - mongo::MockConnRegistry::get()->getConnStrHook()); - - vector<HostAndPort> hostList(_replSet->getHosts()); - for (vector<HostAndPort>::const_iterator iter = hostList.begin(); - iter != hostList.end(); ++iter) { - _replSet->kill(iter->toString()); - } - } + MockReplicaSet* getReplSet() { + return _replSet.get(); + } - void tearDown() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(); +private: + std::unique_ptr<MockReplicaSet> _replSet; +}; - mongo::ScopedDbConnection::clearPool(); - } +void assertRunCommandWithReadPrefThrows(MockReplicaSet* replSet, ReadPreference rp) { + bool isPrimaryOnly = (rp == ReadPreference::PrimaryOnly); - MockReplicaSet* getReplSet() { - return _replSet.get(); - } + bool secondaryOk = !isPrimaryOnly; + TagSet ts = isPrimaryOnly ? TagSet::primaryOnly() : TagSet(); - private: - std::unique_ptr<MockReplicaSet> _replSet; - }; + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); + ASSERT_THROWS(replConn.runCommandWithMetadata( + "foo", "whoami", makeMetadata(rp, ts, secondaryOk), BSON("dbStats" << 1)), + AssertionException); +} - void assertRunCommandWithReadPrefThrows(MockReplicaSet* replSet, ReadPreference rp) { - bool isPrimaryOnly = (rp == ReadPreference::PrimaryOnly); +TEST_F(AllNodesDown, QueryPrimary) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - bool secondaryOk = !isPrimaryOnly; - TagSet ts = isPrimaryOnly? TagSet::primaryOnly() : TagSet(); + Query query; + query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - ASSERT_THROWS(replConn.runCommandWithMetadata("foo", - "whoami", - makeMetadata(rp, - ts, - secondaryOk), - BSON("dbStats" << 1)), - AssertionException); - } +TEST_F(AllNodesDown, CommandPrimary) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::PrimaryOnly); +} - TEST_F(AllNodesDown, QueryPrimary) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(AllNodesDown, QuerySecondaryOnly) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); - } + Query query; + query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} - TEST_F(AllNodesDown, CommandPrimary) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::PrimaryOnly); - } +TEST_F(AllNodesDown, CommandSecondaryOnly) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::SecondaryOnly); +} - TEST_F(AllNodesDown, QuerySecondaryOnly) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(AllNodesDown, QueryPrimaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); - } + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} - TEST_F(AllNodesDown, CommandSecondaryOnly) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::SecondaryOnly); - } +TEST_F(AllNodesDown, CommandPrimaryPreferred) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::PrimaryPreferred); +} - TEST_F(AllNodesDown, QueryPrimaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(AllNodesDown, QuerySecondaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); - } + Query query; + query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} - TEST_F(AllNodesDown, CommandPrimaryPreferred) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::PrimaryPreferred); - } +TEST_F(AllNodesDown, CommandSecondaryPreferred) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::SecondaryPreferred); +} - TEST_F(AllNodesDown, QuerySecondaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(AllNodesDown, QueryNearest) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); - } + Query query; + query.readPref(mongo::ReadPreference::Nearest, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} + +TEST_F(AllNodesDown, CommandNearest) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::Nearest); +} - TEST_F(AllNodesDown, CommandSecondaryPreferred) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::SecondaryPreferred); +/** + * Setup for 2 member replica set with the primary down. + */ +class PrimaryDown : public mongo::unittest::Test { +protected: + void setUp() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(new MockReplicaSet("test", 2)); + ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook()); + _replSet->kill(_replSet->getPrimary()); } - TEST_F(AllNodesDown, QueryNearest) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); + void tearDown() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(); - Query query; - query.readPref(mongo::ReadPreference::Nearest, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); + mongo::ScopedDbConnection::clearPool(); } - TEST_F(AllNodesDown, CommandNearest) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::Nearest); + MockReplicaSet* getReplSet() { + return _replSet.get(); } - /** - * Setup for 2 member replica set with the primary down. - */ - class PrimaryDown: public mongo::unittest::Test { - protected: - void setUp() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(new MockReplicaSet("test", 2)); - ConnectionString::setConnectionHook( - mongo::MockConnRegistry::get()->getConnStrHook()); - _replSet->kill(_replSet->getPrimary()); - } +private: + std::unique_ptr<MockReplicaSet> _replSet; +}; - void tearDown() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(); +TEST_F(PrimaryDown, QueryPrimary) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - mongo::ScopedDbConnection::clearPool(); - } + Query query; + query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} - MockReplicaSet* getReplSet() { - return _replSet.get(); - } +TEST_F(PrimaryDown, CommandPrimary) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::PrimaryOnly); +} - private: - std::unique_ptr<MockReplicaSet> _replSet; - }; +TEST_F(PrimaryDown, QuerySecondaryOnly) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - TEST_F(PrimaryDown, QueryPrimary) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); + Query query; + query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); - Query query; - query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); +} - TEST_F(PrimaryDown, CommandPrimary) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::PrimaryOnly); - } +TEST_F(PrimaryDown, CommandSecondaryOnly) { + assertOneOfNodesSelected( + getReplSet(), ReadPreference::SecondaryOnly, getReplSet()->getSecondaries()); +} - TEST_F(PrimaryDown, QuerySecondaryOnly) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(PrimaryDown, QueryPrimaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); +} - TEST_F(PrimaryDown, CommandSecondaryOnly) { - assertOneOfNodesSelected(getReplSet(), - ReadPreference::SecondaryOnly, - getReplSet()->getSecondaries()); - } +TEST_F(PrimaryDown, CommandPrimaryPreferred) { + assertOneOfNodesSelected( + getReplSet(), ReadPreference::PrimaryPreferred, getReplSet()->getSecondaries()); +} - TEST_F(PrimaryDown, QueryPrimaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(PrimaryDown, QuerySecondaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + Query query; + query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); +} - TEST_F(PrimaryDown, CommandPrimaryPreferred) { - assertOneOfNodesSelected(getReplSet(), - ReadPreference::PrimaryPreferred, - getReplSet()->getSecondaries()); - } +TEST_F(PrimaryDown, CommandSecondaryPreferred) { + assertOneOfNodesSelected( + getReplSet(), ReadPreference::SecondaryPreferred, getReplSet()->getSecondaries()); +} - TEST_F(PrimaryDown, QuerySecondaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(PrimaryDown, Nearest) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); + Query query; + query.readPref(mongo::ReadPreference::Nearest, BSONArray()); + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); +} - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); - } +/** + * Setup for 2 member replica set with the secondary down. + */ +class SecondaryDown : public mongo::unittest::Test { +protected: + void setUp() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(new MockReplicaSet("test", 2)); + ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook()); - TEST_F(PrimaryDown, CommandSecondaryPreferred) { - assertOneOfNodesSelected(getReplSet(), - ReadPreference::SecondaryPreferred, - getReplSet()->getSecondaries()); + _replSet->kill(_replSet->getSecondaries().front()); } - TEST_F(PrimaryDown, Nearest) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); + void tearDown() { + ReplicaSetMonitor::cleanup(); + _replSet.reset(); - Query query; - query.readPref(mongo::ReadPreference::Nearest, BSONArray()); - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str()); + mongo::ScopedDbConnection::clearPool(); } - /** - * Setup for 2 member replica set with the secondary down. - */ - class SecondaryDown: public mongo::unittest::Test { - protected: - void setUp() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(new MockReplicaSet("test", 2)); - ConnectionString::setConnectionHook( - mongo::MockConnRegistry::get()->getConnStrHook()); - - _replSet->kill(_replSet->getSecondaries().front()); - } + MockReplicaSet* getReplSet() { + return _replSet.get(); + } - void tearDown() { - ReplicaSetMonitor::cleanup(); - _replSet.reset(); +private: + std::unique_ptr<MockReplicaSet> _replSet; +}; - mongo::ScopedDbConnection::clearPool(); - } +TEST_F(SecondaryDown, QueryPrimary) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - MockReplicaSet* getReplSet() { - return _replSet.get(); - } + Query query; + query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); - private: - std::unique_ptr<MockReplicaSet> _replSet; - }; + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); +} - TEST_F(SecondaryDown, QueryPrimary) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(SecondaryDown, CommandPrimary) { + assertNodeSelected(getReplSet(), ReadPreference::PrimaryOnly, getReplSet()->getPrimary()); +} - Query query; - query.readPref(mongo::ReadPreference::PrimaryOnly, BSONArray()); +TEST_F(SecondaryDown, QuerySecondaryOnly) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - } + Query query; + query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); + ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); +} - TEST_F(SecondaryDown, CommandPrimary) { - assertNodeSelected(getReplSet(), ReadPreference::PrimaryOnly, getReplSet()->getPrimary()); - } +TEST_F(SecondaryDown, CommandSecondaryOnly) { + assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::SecondaryOnly); +} - TEST_F(SecondaryDown, QuerySecondaryOnly) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(SecondaryDown, QueryPrimaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - Query query; - query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); - ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException); - } + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - TEST_F(SecondaryDown, CommandSecondaryOnly) { - assertRunCommandWithReadPrefThrows(getReplSet(), ReadPreference::SecondaryOnly); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); +} - TEST_F(SecondaryDown, QueryPrimaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(SecondaryDown, CommandPrimaryPreferred) { + assertNodeSelected(getReplSet(), ReadPreference::PrimaryPreferred, getReplSet()->getPrimary()); +} - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); +TEST_F(SecondaryDown, QuerySecondaryPreferred) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - } + Query query; + query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); - TEST_F(SecondaryDown, CommandPrimaryPreferred) { - assertNodeSelected(getReplSet(), - ReadPreference::PrimaryPreferred, - getReplSet()->getPrimary()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); +} - TEST_F(SecondaryDown, QuerySecondaryPreferred) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(SecondaryDown, CommandSecondaryPreferred) { + assertNodeSelected(getReplSet(), ReadPreference::PrimaryPreferred, getReplSet()->getPrimary()); +} - Query query; - query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); +TEST_F(SecondaryDown, QueryNearest) { + MockReplicaSet* replSet = getReplSet(); + DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - } + Query query; + query.readPref(mongo::ReadPreference::Nearest, BSONArray()); - TEST_F(SecondaryDown, CommandSecondaryPreferred) { - assertNodeSelected(getReplSet(), - ReadPreference::PrimaryPreferred, - getReplSet()->getPrimary()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); +} - TEST_F(SecondaryDown, QueryNearest) { - MockReplicaSet* replSet = getReplSet(); - DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts()); +TEST_F(SecondaryDown, CommandNearest) { + assertNodeSelected(getReplSet(), ReadPreference::Nearest, getReplSet()->getPrimary()); +} - Query query; - query.readPref(mongo::ReadPreference::Nearest, BSONArray()); +/** + * Warning: Tests running this fixture cannot be run in parallel with other tests + * that uses ConnectionString::setConnectionHook + */ +class TaggedFiveMemberRS : public mongo::unittest::Test { +protected: + void setUp() { + // Tests for pinning behavior require this. + ReplicaSetMonitor::useDeterministicHostSelection = true; - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str()); - } + // This shuts down the background RSMWatcher thread and prevents it from running. These + // tests depend on controlling when the RSMs are updated. + ReplicaSetMonitor::cleanup(); - TEST_F(SecondaryDown, CommandNearest) { - assertNodeSelected(getReplSet(), ReadPreference::Nearest, getReplSet()->getPrimary()); - } + _replSet.reset(new MockReplicaSet("test", 5)); + _originalConnectionHook = ConnectionString::getConnectionHook(); + ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook()); - /** - * Warning: Tests running this fixture cannot be run in parallel with other tests - * that uses ConnectionString::setConnectionHook - */ - class TaggedFiveMemberRS: public mongo::unittest::Test { - protected: - void setUp() { - // Tests for pinning behavior require this. - ReplicaSetMonitor::useDeterministicHostSelection = true; - - // This shuts down the background RSMWatcher thread and prevents it from running. These - // tests depend on controlling when the RSMs are updated. - ReplicaSetMonitor::cleanup(); - - _replSet.reset(new MockReplicaSet("test", 5)); - _originalConnectionHook = ConnectionString::getConnectionHook(); - ConnectionString::setConnectionHook( - mongo::MockConnRegistry::get()->getConnStrHook()); + { + mongo::repl::ReplicaSetConfig oldConfig = _replSet->getReplConfig(); + + mongo::BSONObjBuilder newConfigBuilder; + newConfigBuilder.append("_id", oldConfig.getReplSetName()); + newConfigBuilder.append("version", oldConfig.getConfigVersion()); + mongo::BSONArrayBuilder membersBuilder(newConfigBuilder.subarrayStart("members")); { - mongo::repl::ReplicaSetConfig oldConfig = _replSet->getReplConfig(); - - mongo::BSONObjBuilder newConfigBuilder; - newConfigBuilder.append("_id", oldConfig.getReplSetName()); - newConfigBuilder.append("version", oldConfig.getConfigVersion()); - - mongo::BSONArrayBuilder membersBuilder(newConfigBuilder.subarrayStart("members")); - { - const string host(_replSet->getPrimary()); - const mongo::repl::MemberConfig* member = - oldConfig.findMemberByHostAndPort(HostAndPort(host)); - membersBuilder.append(BSON("_id" << member->getId() << - "host" << host << - "tags" << BSON("dc" << "ny" << - "p" << "1"))); - _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); - } - - vector<string> secNodes = _replSet->getSecondaries(); - vector<string>::const_iterator secIter = secNodes.begin(); - - { - const string host(*secIter); - const mongo::repl::MemberConfig* member = - oldConfig.findMemberByHostAndPort(HostAndPort(host)); - membersBuilder.append(BSON("_id" << member->getId() << - "host" << host << - "tags" << BSON("dc" << "sf" << - "s" << "1" << - "group" << "1"))); - _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); - } - - { - ++secIter; - const string host(*secIter); - const mongo::repl::MemberConfig* member = - oldConfig.findMemberByHostAndPort(HostAndPort(host)); - membersBuilder.append(BSON("_id" << member->getId() << - "host" << host << - "tags" << BSON("dc" << "ma" << - "s" << "2" << - "group" << "1"))); - _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); - } - - { - ++secIter; - const string host(*secIter); - const mongo::repl::MemberConfig* member = - oldConfig.findMemberByHostAndPort(HostAndPort(host)); - membersBuilder.append(BSON("_id" << member->getId() << - "host" << host << - "tags" << BSON("dc" << "eu" << - "s" << "3"))); - _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); - } - - { - ++secIter; - const string host(*secIter); - const mongo::repl::MemberConfig* member = - oldConfig.findMemberByHostAndPort(HostAndPort(host)); - membersBuilder.append(BSON("_id" << member->getId() << - "host" << host << - "tags" << BSON("dc" << "jp" << - "s" << "4"))); - _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); - } - - membersBuilder.done(); - mongo::repl::ReplicaSetConfig newConfig; - fassert(28569, newConfig.initialize(newConfigBuilder.done())); - fassert(28568, newConfig.validate()); - _replSet->setConfig(newConfig); + const string host(_replSet->getPrimary()); + const mongo::repl::MemberConfig* member = + oldConfig.findMemberByHostAndPort(HostAndPort(host)); + membersBuilder.append( + BSON("_id" << member->getId() << "host" << host << "tags" << BSON("dc" + << "ny" + << "p" + << "1"))); + _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); } - } - void tearDown() { - ReplicaSetMonitor::useDeterministicHostSelection = false; + vector<string> secNodes = _replSet->getSecondaries(); + vector<string>::const_iterator secIter = secNodes.begin(); - ConnectionString::setConnectionHook(_originalConnectionHook); - ReplicaSetMonitor::cleanup(); - _replSet.reset(); + { + const string host(*secIter); + const mongo::repl::MemberConfig* member = + oldConfig.findMemberByHostAndPort(HostAndPort(host)); + membersBuilder.append( + BSON("_id" << member->getId() << "host" << host << "tags" << BSON("dc" + << "sf" + << "s" + << "1" + << "group" + << "1"))); + _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); + } - mongo::ScopedDbConnection::clearPool(); - } + { + ++secIter; + const string host(*secIter); + const mongo::repl::MemberConfig* member = + oldConfig.findMemberByHostAndPort(HostAndPort(host)); + membersBuilder.append( + BSON("_id" << member->getId() << "host" << host << "tags" << BSON("dc" + << "ma" + << "s" + << "2" + << "group" + << "1"))); + _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); + } - MockReplicaSet* getReplSet() { - return _replSet.get(); - } + { + ++secIter; + const string host(*secIter); + const mongo::repl::MemberConfig* member = + oldConfig.findMemberByHostAndPort(HostAndPort(host)); + membersBuilder.append( + BSON("_id" << member->getId() << "host" << host << "tags" << BSON("dc" + << "eu" + << "s" + << "3"))); + _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); + } - private: - ConnectionString::ConnectionHook* _originalConnectionHook; - std::unique_ptr<MockReplicaSet> _replSet; - }; + { + ++secIter; + const string host(*secIter); + const mongo::repl::MemberConfig* member = + oldConfig.findMemberByHostAndPort(HostAndPort(host)); + membersBuilder.append( + BSON("_id" << member->getId() << "host" << host << "tags" << BSON("dc" + << "jp" + << "s" + << "4"))); + _replSet->getNode(host)->insert(IdentityNS, BSON(HostField(host))); + } - TEST_F(TaggedFiveMemberRS, ConnShouldPinIfSameSettings) { - MockReplicaSet* replSet = getReplSet(); - vector<HostAndPort> seedList; - seedList.push_back(HostAndPort(replSet->getPrimary())); + membersBuilder.done(); + mongo::repl::ReplicaSetConfig newConfig; + fassert(28569, newConfig.initialize(newConfigBuilder.done())); + fassert(28568, newConfig.validate()); + _replSet->setConfig(newConfig); + } + } - DBClientReplicaSet replConn(replSet->getSetName(), seedList); + void tearDown() { + ReplicaSetMonitor::useDeterministicHostSelection = false; - string dest; - { - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + ConnectionString::setConnectionHook(_originalConnectionHook); + ReplicaSetMonitor::cleanup(); + _replSet.reset(); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - dest = doc[HostField.name()].str(); - } + mongo::ScopedDbConnection::clearPool(); + } - { - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - const string newDest = doc[HostField.name()].str(); - ASSERT_EQUALS(dest, newDest); - } + MockReplicaSet* getReplSet() { + return _replSet.get(); } - TEST_F(TaggedFiveMemberRS, ConnShouldNotPinIfHostMarkedAsFailed) { - MockReplicaSet* replSet = getReplSet(); - vector<HostAndPort> seedList; - seedList.push_back(HostAndPort(replSet->getPrimary())); +private: + ConnectionString::ConnectionHook* _originalConnectionHook; + std::unique_ptr<MockReplicaSet> _replSet; +}; - DBClientReplicaSet replConn(replSet->getSetName(), seedList); +TEST_F(TaggedFiveMemberRS, ConnShouldPinIfSameSettings) { + MockReplicaSet* replSet = getReplSet(); + vector<HostAndPort> seedList; + seedList.push_back(HostAndPort(replSet->getPrimary())); - string dest; - { - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + DBClientReplicaSet replConn(replSet->getSetName(), seedList); - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - dest = doc[HostField.name()].str(); - } + string dest; + { + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - // This is the only difference from ConnShouldPinIfSameSettings which tests that we *do* pin - // in if the host is still marked as up. Note that this only notifies the RSM, and does not - // directly effect the DBClientRS. - ReplicaSetMonitor::get(replSet->getSetName())->failedHost(HostAndPort(dest)); + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + dest = doc[HostField.name()].str(); + } - { - Query query; - query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - const string newDest = doc[HostField.name()].str(); - ASSERT_NOT_EQUALS(dest, newDest); - } + { + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + const string newDest = doc[HostField.name()].str(); + ASSERT_EQUALS(dest, newDest); } +} - TEST_F(TaggedFiveMemberRS, ConnShouldNotPinIfDiffMode) { - MockReplicaSet* replSet = getReplSet(); - vector<HostAndPort> seedList; - seedList.push_back(HostAndPort(replSet->getPrimary())); +TEST_F(TaggedFiveMemberRS, ConnShouldNotPinIfHostMarkedAsFailed) { + MockReplicaSet* replSet = getReplSet(); + vector<HostAndPort> seedList; + seedList.push_back(HostAndPort(replSet->getPrimary())); - DBClientReplicaSet replConn(replSet->getSetName(), seedList); + DBClientReplicaSet replConn(replSet->getSetName(), seedList); - // Need up-to-date view to ensure there are multiple valid choices. - ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); + string dest; + { + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); - string dest; - { - Query query; - query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); - - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - dest = doc[HostField.name()].str(); - ASSERT_NOT_EQUALS(dest, replSet->getPrimary()); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + dest = doc[HostField.name()].str(); + } - { - Query query; - query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - const string newDest = doc[HostField.name()].str(); - ASSERT_NOT_EQUALS(dest, newDest); - } + // This is the only difference from ConnShouldPinIfSameSettings which tests that we *do* pin + // in if the host is still marked as up. Note that this only notifies the RSM, and does not + // directly effect the DBClientRS. + ReplicaSetMonitor::get(replSet->getSetName())->failedHost(HostAndPort(dest)); + + { + Query query; + query.readPref(mongo::ReadPreference::PrimaryPreferred, BSONArray()); + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + const string newDest = doc[HostField.name()].str(); + ASSERT_NOT_EQUALS(dest, newDest); } +} - TEST_F(TaggedFiveMemberRS, ConnShouldNotPinIfDiffTag) { - MockReplicaSet* replSet = getReplSet(); - vector<HostAndPort> seedList; - seedList.push_back(HostAndPort(replSet->getPrimary())); +TEST_F(TaggedFiveMemberRS, ConnShouldNotPinIfDiffMode) { + MockReplicaSet* replSet = getReplSet(); + vector<HostAndPort> seedList; + seedList.push_back(HostAndPort(replSet->getPrimary())); - DBClientReplicaSet replConn(replSet->getSetName(), seedList); + DBClientReplicaSet replConn(replSet->getSetName(), seedList); - // Need up-to-date view to ensure there are multiple valid choices. - ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); + // Need up-to-date view to ensure there are multiple valid choices. + ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); - string dest; - { - Query query; - query.readPref(mongo::ReadPreference::SecondaryPreferred, - BSON_ARRAY(BSON("dc" << "sf"))); - - // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - dest = doc[HostField.name()].str(); - ASSERT_NOT_EQUALS(dest, replSet->getPrimary()); - } + string dest; + { + Query query; + query.readPref(mongo::ReadPreference::SecondaryPreferred, BSONArray()); - { - Query query; - vector<pair<string, string> > tagSet; - query.readPref(mongo::ReadPreference::SecondaryPreferred, - BSON_ARRAY(BSON("group" << 1))); - unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); - BSONObj doc = cursor->next(); - const string newDest = doc[HostField.name()].str(); - ASSERT_NOT_EQUALS(dest, newDest); - } + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + dest = doc[HostField.name()].str(); + ASSERT_NOT_EQUALS(dest, replSet->getPrimary()); + } + + { + Query query; + query.readPref(mongo::ReadPreference::SecondaryOnly, BSONArray()); + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + const string newDest = doc[HostField.name()].str(); + ASSERT_NOT_EQUALS(dest, newDest); } +} - // Note: slaveConn is dangerous and should be deprecated! Also see SERVER-7801. - TEST_F(TaggedFiveMemberRS, SlaveConnReturnsSecConn) { - MockReplicaSet* replSet = getReplSet(); - vector<HostAndPort> seedList; - seedList.push_back(HostAndPort(replSet->getPrimary())); +TEST_F(TaggedFiveMemberRS, ConnShouldNotPinIfDiffTag) { + MockReplicaSet* replSet = getReplSet(); + vector<HostAndPort> seedList; + seedList.push_back(HostAndPort(replSet->getPrimary())); - DBClientReplicaSet replConn(replSet->getSetName(), seedList); + DBClientReplicaSet replConn(replSet->getSetName(), seedList); - // Need up-to-date view since slaveConn() uses SecondaryPreferred, and this test assumes it - // knows about at least one secondary. - ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); + // Need up-to-date view to ensure there are multiple valid choices. + ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); - string dest; - mongo::DBClientConnection& secConn = replConn.slaveConn(); + string dest; + { + Query query; + query.readPref(mongo::ReadPreference::SecondaryPreferred, + BSON_ARRAY(BSON("dc" + << "sf"))); // Note: IdentityNS contains the name of the server. - unique_ptr<DBClientCursor> cursor = secConn.query(IdentityNS, Query()); + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); BSONObj doc = cursor->next(); dest = doc[HostField.name()].str(); ASSERT_NOT_EQUALS(dest, replSet->getPrimary()); } + + { + Query query; + vector<pair<string, string>> tagSet; + query.readPref(mongo::ReadPreference::SecondaryPreferred, BSON_ARRAY(BSON("group" << 1))); + unique_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query); + BSONObj doc = cursor->next(); + const string newDest = doc[HostField.name()].str(); + ASSERT_NOT_EQUALS(dest, newDest); + } +} + +// Note: slaveConn is dangerous and should be deprecated! Also see SERVER-7801. +TEST_F(TaggedFiveMemberRS, SlaveConnReturnsSecConn) { + MockReplicaSet* replSet = getReplSet(); + vector<HostAndPort> seedList; + seedList.push_back(HostAndPort(replSet->getPrimary())); + + DBClientReplicaSet replConn(replSet->getSetName(), seedList); + + // Need up-to-date view since slaveConn() uses SecondaryPreferred, and this test assumes it + // knows about at least one secondary. + ReplicaSetMonitor::get(replSet->getSetName())->startOrContinueRefresh().refreshAll(); + + string dest; + mongo::DBClientConnection& secConn = replConn.slaveConn(); + + // Note: IdentityNS contains the name of the server. + unique_ptr<DBClientCursor> cursor = secConn.query(IdentityNS, Query()); + BSONObj doc = cursor->next(); + dest = doc[HostField.name()].str(); + ASSERT_NOT_EQUALS(dest, replSet->getPrimary()); +} } |