summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2013-03-29 16:00:59 -0400
committerRandolph Tan <randolph@10gen.com>2013-04-01 19:17:36 -0400
commit0502e6aadada1ce1bf5187a44c367714e8c142b2 (patch)
tree69153262cb8d3abc507db27ab298964ead07370a
parentf1017ee04454faace5997a3604527d3fd6bccda9 (diff)
downloadmongo-0502e6aadada1ce1bf5187a44c367714e8c142b2.tar.gz
SERVER-9174 Race condition on read_pref_rs_client.js after reconfig
Replaced js test with cpp unit test that does not rely on reconfig.
-rw-r--r--jstests/sharding/read_pref_rs_client.js220
-rw-r--r--src/mongo/client/dbclient_rs_test.cpp405
-rw-r--r--src/mongo/dbtests/mock/mock_remote_db_server.cpp2
-rw-r--r--src/mongo/dbtests/mock/mock_remote_db_server.h10
4 files changed, 385 insertions, 252 deletions
diff --git a/jstests/sharding/read_pref_rs_client.js b/jstests/sharding/read_pref_rs_client.js
deleted file mode 100644
index 8a458101aa2..00000000000
--- a/jstests/sharding/read_pref_rs_client.js
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * Testing read preference on DBClientReplicaSets, specifically on the auto-retry
- * and automatic failover selection
- */
-// NOTE: this test is skipped when running smoke.py with --auth because of SERVER-6972
-
-function basicTest() {
- var replTest = new ReplSetTest({ name: 'basic', nodes: 2, useHostName: true });
- replTest.startSet({ oplogSize: 1 });
- replTest.initiate();
- replTest.awaitSecondaryNodes();
-
- var PRI_HOST = replTest.getPrimary().host;
- var SEC_HOST = replTest.getSecondary().host;
-
- var replConn = new Mongo(replTest.getURL());
- var coll = replConn.getDB('test').user;
- var dest = coll.find().readPref('primary').explain().server;
- assert.eq(PRI_HOST, dest);
-
- // Create brand new connection to make sure that the last cached is not used
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('secondary').explain().server;
- assert.eq(SEC_HOST, dest);
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('primaryPreferred').explain().server;
- assert.eq(PRI_HOST, dest);
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('secondaryPreferred').explain().server;
- assert.eq(SEC_HOST, dest);
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- // just make sure that it doesn't throw
- coll.find().readPref('nearest').explain();
-
- replTest.stopSet();
-}
-
-function noPriNoSecTest() {
- var replTest = new ReplSetTest({ name: 'noPriNoSec', useHostName: true,
- nodes: [{}, { arbiter: true }, { arbiter: true }]});
- replTest.startSet({ oplogSize: 1 });
- replTest.initiate();
- replTest.awaitSecondaryNodes();
-
- var replConn = new Mongo(replTest.getURL());
- var coll = replConn.getDB('test').user;
-
- replTest.stop(0);
-
- assert.throws(function() {
- coll.find().readPref('primary').explain();
- });
-
- // Make sure that it still fails even when trying to refresh
- assert.throws(function() {
- coll.find().readPref('primary').explain();
- });
-
- // Don't need to create new connection because failed connections
- // would never be reused, and also becasue the js Mongo contructor
- // will throw when it can't connect to a primary
- assert.throws(function() {
- coll.find().readPref('secondary').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('secondary').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('primaryPreferred').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('primaryPreferred').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('secondaryPreferred').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('secondaryPreferred').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('neareset').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('nearest').explain();
- });
-
- replTest.stopSet();
-}
-
-function priOkNoSecTest() {
- var replTest = new ReplSetTest({ name: 'priOkNoSec', useHostName: true,
- nodes: [{}, { arbiter: true }, {}]});
- replTest.startSet({ oplogSize: 1 });
- replTest.initiate();
- replTest.awaitSecondaryNodes();
-
- var replConn = new Mongo(replTest.getURL());
- var coll = replConn.getDB('test').user;
-
- replTest.stop(2);
-
- var PRI_HOST = replTest.getPrimary().host;
-
- var dest = coll.find().readPref('primary').explain().server;
- assert.eq(PRI_HOST, dest);
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('primaryPreferred').explain().server;
- assert.eq(PRI_HOST, dest);
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- assert.throws(function() {
- coll.find().readPref('secondary').explain();
- });
-
- assert.throws(function() {
- coll.find().readPref('secondary').explain();
- });
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('secondaryPreferred').explain().server;
- assert.eq(PRI_HOST, dest);
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('nearest').explain().server;
- assert.eq(PRI_HOST, dest);
-
- replTest.stopSet();
-}
-
-function noPriSecOkTest() {
- var replTest = new ReplSetTest({ name: 'noPriSecOk', useHostName: true,
- nodes: [{ }, { arbiter: true }, { }]});
- replTest.startSet({ oplogSize: 1 });
- replTest.initiate();
- replTest.awaitSecondaryNodes();
-
- var priConn = replTest.getPrimary();
- var conf = priConn.getDB('local').system.replset.findOne();
- conf.version++;
- conf.members[0].priority = 99;
- conf.members[2].priority = 0;
-
- var SEC_HOST = replTest.nodes[2].host;
-
- try {
- priConn.getDB('admin').runCommand({ replSetReconfig: conf });
- } catch (x) {
- print('Exception from reconfig: ' + x);
- }
-
- var replConn = new Mongo(replTest.getURL());
- var coll = replConn.getDB('test').user;
-
- replTest.stop(0);
-
- assert.throws(function() {
- coll.find().readPref('primary').explain();
- });
-
- // Make sure that it still fails even when trying to refresh
- assert.throws(function() {
- coll.find().readPref('primary').explain();
- });
-
- replConn = new Mongo(replTest.getURL());
- coll = replConn.getDB('test').user;
- var dest = coll.find().readPref('primaryPreferred').explain().server;
- assert.eq(SEC_HOST, dest);
-
- replTest.start(0, {}, true);
- replTest.awaitSecondaryNodes();
- replConn = new Mongo(replTest.getURL());
- replTest.stop(0);
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('secondary').explain().server;
- assert.eq(SEC_HOST, dest);
-
- replTest.start(0, {}, true);
- replTest.awaitSecondaryNodes();
- replConn = new Mongo(replTest.getURL());
- replTest.stop(0);
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('secondaryPreferred').explain().server;
- assert.eq(SEC_HOST, dest);
-
- replTest.start(0, {}, true);
- replTest.awaitSecondaryNodes();
- replConn = new Mongo(replTest.getURL());
- replTest.stop(0);
- coll = replConn.getDB('test').user;
- dest = coll.find().readPref('nearest').explain().server;
- assert.eq(SEC_HOST, dest);
-
- replTest.stopSet();
-}
-
-basicTest();
-noPriNoSecTest();
-priOkNoSecTest();
-noPriSecOkTest();
-
diff --git a/src/mongo/client/dbclient_rs_test.cpp b/src/mongo/client/dbclient_rs_test.cpp
index 19e94a0fc9f..ccb7b71063e 100644
--- a/src/mongo/client/dbclient_rs_test.cpp
+++ b/src/mongo/client/dbclient_rs_test.cpp
@@ -15,7 +15,8 @@
*/
/**
- * This file contains tests for DBClientReplicaSet.
+ * This file contains tests for DBClientReplicaSet. The tests mocks the servers
+ * the DBClientReplicaSet talks to, so the tests only covers the client side logic.
*/
#include "mongo/bson/bson_field.h"
@@ -25,35 +26,13 @@
#include "mongo/dbtests/mock/mock_conn_registry.h"
#include "mongo/dbtests/mock/mock_replica_set.h"
#include "mongo/unittest/unittest.h"
+#include "mongo/util/assert_util.h"
#include <map>
#include <memory>
#include <string>
#include <vector>
-using std::auto_ptr;
-using std::map;
-using std::make_pair;
-using std::pair;
-using std::string;
-using std::vector;
-using boost::scoped_ptr;
-
-using mongo::BSONField;
-using mongo::BSONObj;
-using mongo::BSONArray;
-using mongo::BSONElement;
-using mongo::ConnectionString;
-using mongo::DBClientCursor;
-using mongo::DBClientReplicaSet;
-using mongo::HostAndPort;
-using mongo::MockReplicaSet;
-using mongo::Query;
-using mongo::ReadPreference;
-using mongo::ReplicaSetMonitor;
-using mongo::ScopedDbConnection;
-using mongo::TagSet;
-
namespace mongo {
// Symbols defined to build the binary correctly.
CmdLine cmdLine;
@@ -73,16 +52,373 @@ namespace mongo {
}
}
-namespace mongo_test {
+namespace {
+ using boost::scoped_ptr;
+ using std::auto_ptr;
+ using std::map;
+ using std::make_pair;
+ using std::pair;
+ using std::string;
+ using std::vector;
+
+ using mongo::AssertionException;
+ using mongo::BSONArray;
+ using mongo::BSONElement;
+ using mongo::BSONField;
+ using mongo::BSONObj;
+ 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::ReplicaSetMonitor;
+ using mongo::ScopedDbConnection;
+ using mongo::TagSet;
+
+ /**
+ * Basic fixture with one primary and one secondary.
+ */
+ class BasicRS: public mongo::unittest::Test {
+ protected:
+ void setUp() {
+ _replSet.reset(new MockReplicaSet("test", 2));
+ ConnectionString::setConnectionHook(
+ mongo::MockConnRegistry::get()->getConnStrHook());
+ }
+
+ void tearDown() {
+ ReplicaSetMonitor::remove(_replSet->getSetName(), true);
+ _replSet.reset();
+
+ // TODO: remove this after we remove replSetGetStatus from ReplicaSetMonitor.
+ mongo::ScopedDbConnection::clearPool();
+ }
+
+ MockReplicaSet* getReplSet() {
+ return _replSet.get();
+ }
+
+ private:
+ boost::scoped_ptr<MockReplicaSet> _replSet;
+ };
+
+ TEST_F(BasicRS, ReadFromPrimary) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryOnly, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str());
+ }
+
+ TEST_F(BasicRS, SecondaryOnly) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryOnly, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str());
+ }
+
+ TEST_F(BasicRS, PrimaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str());
+ }
+
+ TEST_F(BasicRS, SecondaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_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 will all of the nodes down.
+ */
+ class AllNodesDown: public mongo::unittest::Test {
+ protected:
+ void setUp() {
+ _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(true));
+ }
+ }
+
+ void tearDown() {
+ ReplicaSetMonitor::remove(_replSet->getSetName(), true);
+ _replSet.reset();
+
+ // TODO: remove this after we remove replSetGetStatus from ReplicaSetMonitor.
+ mongo::ScopedDbConnection::clearPool();
+ }
+
+ MockReplicaSet* getReplSet() {
+ return _replSet.get();
+ }
+
+ private:
+ boost::scoped_ptr<MockReplicaSet> _replSet;
+ };
+
+ TEST_F(AllNodesDown, ReadFromPrimary) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryOnly, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ TEST_F(AllNodesDown, SecondaryOnly) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryOnly, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ TEST_F(AllNodesDown, PrimaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryPreferred, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ TEST_F(AllNodesDown, SecondaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryPreferred, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ TEST_F(AllNodesDown, Nearest) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_Nearest, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ /**
+ * Setup for 2 member replica set with the primary down.
+ */
+ class PrimaryDown: public mongo::unittest::Test {
+ protected:
+ void setUp() {
+ _replSet.reset(new MockReplicaSet("test", 2));
+ ConnectionString::setConnectionHook(
+ mongo::MockConnRegistry::get()->getConnStrHook());
+ _replSet->kill(_replSet->getPrimary());
+ }
+
+ void tearDown() {
+ ReplicaSetMonitor::remove(_replSet->getSetName(), true);
+ _replSet.reset();
+
+ // TODO: remove this after we remove replSetGetStatus from ReplicaSetMonitor.
+ mongo::ScopedDbConnection::clearPool();
+ }
+
+ MockReplicaSet* getReplSet() {
+ return _replSet.get();
+ }
+
+ private:
+ boost::scoped_ptr<MockReplicaSet> _replSet;
+ };
+
+ TEST_F(PrimaryDown, ReadFromPrimary) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryOnly, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ TEST_F(PrimaryDown, SecondaryOnly) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryOnly, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str());
+ }
+
+ TEST_F(PrimaryDown, PrimaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str());
+ }
+
+ TEST_F(PrimaryDown, SecondaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getSecondaries().front(), doc[HostField.name()].str());
+ }
+
+ TEST_F(PrimaryDown, Nearest) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_Nearest, BSONArray());
+ auto_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() {
+ _replSet.reset(new MockReplicaSet("test", 2));
+ ConnectionString::setConnectionHook(
+ mongo::MockConnRegistry::get()->getConnStrHook());
+
+ _replSet->kill(_replSet->getSecondaries().front());
+ }
+
+ void tearDown() {
+ ReplicaSetMonitor::remove(_replSet->getSetName(), true);
+ _replSet.reset();
+
+ // TODO: remove this after we remove replSetGetStatus from ReplicaSetMonitor.
+ mongo::ScopedDbConnection::clearPool();
+ }
+
+ MockReplicaSet* getReplSet() {
+ return _replSet.get();
+ }
+
+ private:
+ boost::scoped_ptr<MockReplicaSet> _replSet;
+ };
+
+ TEST_F(SecondaryDown, ReadFromPrimary) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryOnly, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str());
+ }
+
+ TEST_F(SecondaryDown, SecondaryOnly) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryOnly, BSONArray());
+ ASSERT_THROWS(replConn.query(IdentityNS, query), AssertionException);
+ }
+
+ TEST_F(SecondaryDown, PrimaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_PrimaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str());
+ }
+
+ TEST_F(SecondaryDown, SecondaryPreferred) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_SecondaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str());
+ }
+
+ TEST_F(SecondaryDown, Nearest) {
+ MockReplicaSet* replSet = getReplSet();
+ DBClientReplicaSet replConn(replSet->getSetName(), replSet->getHosts());
+
+ Query query;
+ query.readPref(mongo::ReadPreference_Nearest, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
+ auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
+ BSONObj doc = cursor->next();
+ ASSERT_EQUALS(replSet->getPrimary(), doc[HostField.name()].str());
+ }
+
/**
* Warning: Tests running this fixture cannot be run in parallel with other tests
* that uses ConnectionString::setConnectionHook
*/
class TaggedFiveMemberRS: public mongo::unittest::Test {
protected:
- static const string IdentityNS;
- static const BSONField<string> HostField;
-
void setUp() {
_replSet.reset(new MockReplicaSet("test", 5));
_originalConnectionHook = ConnectionString::getConnectionHook();
@@ -153,6 +489,8 @@ namespace mongo_test {
ConnectionString::setConnectionHook(_originalConnectionHook);
ReplicaSetMonitor::remove(_replSet->getSetName(), true);
_replSet.reset();
+
+ // TODO: remove this after we remove replSetGetStatus from ReplicaSetMonitor.
mongo::ScopedDbConnection::clearPool();
}
@@ -165,9 +503,6 @@ namespace mongo_test {
boost::scoped_ptr<MockReplicaSet> _replSet;
};
- const string TaggedFiveMemberRS::IdentityNS("local.me");
- const BSONField<string> TaggedFiveMemberRS::HostField("host", "bad");
-
TEST_F(TaggedFiveMemberRS, ConnShouldPinIfSameSettings) {
MockReplicaSet* replSet = getReplSet();
vector<HostAndPort> seedList;
@@ -179,6 +514,8 @@ namespace mongo_test {
{
Query query;
query.readPref(mongo::ReadPreference_PrimaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
BSONObj doc = cursor->next();
dest = doc[HostField.name()].str();
@@ -205,6 +542,8 @@ namespace mongo_test {
{
Query query;
query.readPref(mongo::ReadPreference_SecondaryPreferred, BSONArray());
+
+ // Note: IdentityNS contains the name of the server.
auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
BSONObj doc = cursor->next();
dest = doc[HostField.name()].str();
@@ -233,6 +572,8 @@ namespace mongo_test {
Query query;
query.readPref(mongo::ReadPreference_SecondaryPreferred,
BSON_ARRAY(BSON("dc" << "sf")));
+
+ // Note: IdentityNS contains the name of the server.
auto_ptr<DBClientCursor> cursor = replConn.query(IdentityNS, query);
BSONObj doc = cursor->next();
dest = doc[HostField.name()].str();
@@ -261,6 +602,8 @@ namespace mongo_test {
string dest;
mongo::DBClientConnection& secConn = replConn.slaveConn();
+
+ // Note: IdentityNS contains the name of the server.
auto_ptr<DBClientCursor> cursor = secConn.query(IdentityNS, Query());
BSONObj doc = cursor->next();
dest = doc[HostField.name()].str();
diff --git a/src/mongo/dbtests/mock/mock_remote_db_server.cpp b/src/mongo/dbtests/mock/mock_remote_db_server.cpp
index e78d245c70c..9d8506b37ba 100644
--- a/src/mongo/dbtests/mock/mock_remote_db_server.cpp
+++ b/src/mongo/dbtests/mock/mock_remote_db_server.cpp
@@ -24,6 +24,7 @@ using std::string;
using std::vector;
namespace mongo {
+
MockRemoteDBServer::CircularBSONIterator::CircularBSONIterator(
const vector<BSONObj>& replyVector) {
for (std::vector<mongo::BSONObj>::const_iterator iter = replyVector.begin();
@@ -54,6 +55,7 @@ namespace mongo {
_cmdCount(0),
_queryCount(0),
_instanceID(0) {
+ insert(IdentityNS, BSON(HostField(hostAndPort)), 0);
}
MockRemoteDBServer::~MockRemoteDBServer() {
diff --git a/src/mongo/dbtests/mock/mock_remote_db_server.h b/src/mongo/dbtests/mock/mock_remote_db_server.h
index 6aaba91113c..0455e755d07 100644
--- a/src/mongo/dbtests/mock/mock_remote_db_server.h
+++ b/src/mongo/dbtests/mock/mock_remote_db_server.h
@@ -19,12 +19,17 @@
#include <string>
#include <vector>
+#include "mongo/bson/bson_field.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/platform/unordered_map.h"
#include "mongo/util/concurrency/spin_lock.h"
namespace mongo {
+
+ const std::string IdentityNS("local.me");
+ const BSONField<string> HostField("host");
+
/**
* A very simple mock that acts like a database server. Every object keeps track of its own
* InstanceID, which initially starts at zero and increments every time it is restarted.
@@ -51,6 +56,9 @@ namespace mongo {
* 1. hostAndPort of this server should start with $.
* 2. No other instance has the same hostAndPort as this.
*
+ * This server will also contain the hostAndPort inside the IdentityNS
+ * collection. This is convenient for testing query routing.
+ *
* @param hostAndPort the host name with port for this server.
*
* @see MockConnRegistry
@@ -70,7 +78,7 @@ namespace mongo {
/**
* Shuts down this server. Any operations on this server with an InstanceID
* less than or equal to the current one will throw a mongo::SocketException.
- * To bring the server up again, use the #reboot method.
+ * To bring the server up again, use the reboot method.
*/
void shutdown();