summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/replica_set_monitor_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/dbtests/replica_set_monitor_test.cpp')
-rw-r--r--src/mongo/dbtests/replica_set_monitor_test.cpp450
1 files changed, 225 insertions, 225 deletions
diff --git a/src/mongo/dbtests/replica_set_monitor_test.cpp b/src/mongo/dbtests/replica_set_monitor_test.cpp
index 12b814f4ad2..188a85ce966 100644
--- a/src/mongo/dbtests/replica_set_monitor_test.cpp
+++ b/src/mongo/dbtests/replica_set_monitor_test.cpp
@@ -40,264 +40,264 @@
namespace {
- using namespace mongo;
-
- using std::map;
- using std::vector;
- using std::set;
- using std::string;
- using std::unique_ptr;
-
- // TODO: Port these existing tests here: replmonitor_bad_seed.js, repl_monitor_refresh.js
-
- /**
- * Warning: Tests running this fixture cannot be run in parallel with other tests
- * that uses ConnectionString::setConnectionHook
- */
- class ReplicaSetMonitorTest: public mongo::unittest::Test {
- protected:
- void setUp() {
- _replSet.reset(new MockReplicaSet("test", 3));
- _originalConnectionHook = ConnectionString::getConnectionHook();
- ConnectionString::setConnectionHook(
- mongo::MockConnRegistry::get()->getConnStrHook());
- }
+using namespace mongo;
+
+using std::map;
+using std::vector;
+using std::set;
+using std::string;
+using std::unique_ptr;
+
+// TODO: Port these existing tests here: replmonitor_bad_seed.js, repl_monitor_refresh.js
+
+/**
+ * Warning: Tests running this fixture cannot be run in parallel with other tests
+ * that uses ConnectionString::setConnectionHook
+ */
+class ReplicaSetMonitorTest : public mongo::unittest::Test {
+protected:
+ void setUp() {
+ _replSet.reset(new MockReplicaSet("test", 3));
+ _originalConnectionHook = ConnectionString::getConnectionHook();
+ ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook());
+ }
+
+ void tearDown() {
+ ConnectionString::setConnectionHook(_originalConnectionHook);
+ ReplicaSetMonitor::cleanup();
+ _replSet.reset();
+ mongo::ScopedDbConnection::clearPool();
+ }
- void tearDown() {
- ConnectionString::setConnectionHook(_originalConnectionHook);
- ReplicaSetMonitor::cleanup();
- _replSet.reset();
- mongo::ScopedDbConnection::clearPool();
+ MockReplicaSet* getReplSet() {
+ return _replSet.get();
+ }
+
+private:
+ ConnectionString::ConnectionHook* _originalConnectionHook;
+ std::unique_ptr<MockReplicaSet> _replSet;
+};
+
+TEST_F(ReplicaSetMonitorTest, SeedWithPriOnlySecDown) {
+ // Test to make sure that the monitor doesn't crash when
+ // ConnectionString::connect returns NULL
+ MockReplicaSet* replSet = getReplSet();
+ replSet->kill(replSet->getSecondaries());
+
+ // Create a monitor with primary as the only seed list and the two secondaries
+ // down so a NULL connection object will be stored for these secondaries in
+ // the _nodes vector.
+ const string replSetName(replSet->getSetName());
+ set<HostAndPort> seedList;
+ seedList.insert(HostAndPort(replSet->getPrimary()));
+ ReplicaSetMonitor::createIfNeeded(replSetName, seedList);
+
+ replSet->kill(replSet->getPrimary());
+
+ ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
+ // Trigger calls to Node::getConnWithRefresh
+ monitor->startOrContinueRefresh().refreshAll();
+}
+
+namespace {
+/**
+ * Takes a repl::ReplicaSetConfig and a node to remove and returns a new config with equivalent
+ * members minus the one specified to be removed. NOTE: Does not copy over properties of the
+ * members other than their id and host.
+ */
+repl::ReplicaSetConfig _getConfigWithMemberRemoved(const repl::ReplicaSetConfig& oldConfig,
+ const HostAndPort& toRemove) {
+ BSONObjBuilder newConfigBuilder;
+ newConfigBuilder.append("_id", oldConfig.getReplSetName());
+ newConfigBuilder.append("version", oldConfig.getConfigVersion());
+
+ BSONArrayBuilder membersBuilder(newConfigBuilder.subarrayStart("members"));
+ for (repl::ReplicaSetConfig::MemberIterator member = oldConfig.membersBegin();
+ member != oldConfig.membersEnd();
+ ++member) {
+ if (member->getHostAndPort() == toRemove) {
+ continue;
}
- MockReplicaSet* getReplSet() {
- return _replSet.get();
+ membersBuilder.append(
+ BSON("_id" << member->getId() << "host" << member->getHostAndPort().toString()));
+ }
+
+ membersBuilder.done();
+ repl::ReplicaSetConfig newConfig;
+ ASSERT_OK(newConfig.initialize(newConfigBuilder.obj()));
+ ASSERT_OK(newConfig.validate());
+ return newConfig;
+}
+} // namespace
+
+// Stress test case for a node that is previously a primary being removed from the set.
+// This test goes through configurations with different positions for the primary node
+// in the host list returned from the isMaster command. The test here is to make sure
+// that the ReplicaSetMonitor will not crash under these situations.
+TEST(ReplicaSetMonitorTest, PrimaryRemovedFromSetStress) {
+ const size_t NODE_COUNT = 5;
+ MockReplicaSet replSet("test", NODE_COUNT);
+ ConnectionString::ConnectionHook* originalConnHook = ConnectionString::getConnectionHook();
+ ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook());
+
+ const string replSetName(replSet.getSetName());
+ set<HostAndPort> seedList;
+ seedList.insert(HostAndPort(replSet.getPrimary()));
+ ReplicaSetMonitor::createIfNeeded(replSetName, seedList);
+
+ const repl::ReplicaSetConfig& origConfig = replSet.getReplConfig();
+ mongo::ReplicaSetMonitorPtr replMonitor = ReplicaSetMonitor::get(replSetName);
+
+ for (size_t idxToRemove = 0; idxToRemove < NODE_COUNT; idxToRemove++) {
+ replSet.setConfig(origConfig);
+ // Make sure the monitor sees the change
+ replMonitor->startOrContinueRefresh().refreshAll();
+
+ string hostToRemove;
+ {
+ BSONObjBuilder monitorStateBuilder;
+ replMonitor->appendInfo(monitorStateBuilder);
+ BSONObj monitorState = monitorStateBuilder.done();
+
+ BSONElement hostsElem = monitorState["hosts"];
+ BSONElement addrElem = hostsElem[mongo::str::stream() << idxToRemove]["addr"];
+ hostToRemove = addrElem.String();
}
- private:
- ConnectionString::ConnectionHook* _originalConnectionHook;
- std::unique_ptr<MockReplicaSet> _replSet;
- };
-
- TEST_F(ReplicaSetMonitorTest, SeedWithPriOnlySecDown) {
- // Test to make sure that the monitor doesn't crash when
- // ConnectionString::connect returns NULL
- MockReplicaSet* replSet = getReplSet();
- replSet->kill(replSet->getSecondaries());
-
- // Create a monitor with primary as the only seed list and the two secondaries
- // down so a NULL connection object will be stored for these secondaries in
- // the _nodes vector.
- const string replSetName(replSet->getSetName());
- set<HostAndPort> seedList;
- seedList.insert(HostAndPort(replSet->getPrimary()));
- ReplicaSetMonitor::createIfNeeded(replSetName, seedList);
-
- replSet->kill(replSet->getPrimary());
-
- ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
- // Trigger calls to Node::getConnWithRefresh
- monitor->startOrContinueRefresh().refreshAll();
+ replSet.setPrimary(hostToRemove);
+ // Make sure the monitor sees the new primary
+ replMonitor->startOrContinueRefresh().refreshAll();
+
+ repl::ReplicaSetConfig newConfig =
+ _getConfigWithMemberRemoved(origConfig, HostAndPort(hostToRemove));
+ replSet.setConfig(newConfig);
+ replSet.setPrimary(newConfig.getMemberAt(0).getHostAndPort().toString());
+ // Force refresh -> should not crash
+ replMonitor->startOrContinueRefresh().refreshAll();
}
-namespace {
- /**
- * Takes a repl::ReplicaSetConfig and a node to remove and returns a new config with equivalent
- * members minus the one specified to be removed. NOTE: Does not copy over properties of the
- * members other than their id and host.
- */
- repl::ReplicaSetConfig _getConfigWithMemberRemoved(const repl::ReplicaSetConfig& oldConfig,
- const HostAndPort& toRemove) {
- BSONObjBuilder newConfigBuilder;
+ ReplicaSetMonitor::cleanup();
+ ConnectionString::setConnectionHook(originalConnHook);
+ mongo::ScopedDbConnection::clearPool();
+}
+
+/**
+ * Warning: Tests running this fixture cannot be run in parallel with other tests
+ * that use ConnectionString::setConnectionHook.
+ */
+class TwoNodeWithTags : public mongo::unittest::Test {
+protected:
+ void setUp() {
+ _replSet.reset(new MockReplicaSet("test", 2));
+ _originalConnectionHook = ConnectionString::getConnectionHook();
+ ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook());
+
+ repl::ReplicaSetConfig oldConfig = _replSet->getReplConfig();
+
+ mongo::BSONObjBuilder newConfigBuilder;
newConfigBuilder.append("_id", oldConfig.getReplSetName());
newConfigBuilder.append("version", oldConfig.getConfigVersion());
- BSONArrayBuilder membersBuilder(newConfigBuilder.subarrayStart("members"));
- for (repl::ReplicaSetConfig::MemberIterator member = oldConfig.membersBegin();
- member != oldConfig.membersEnd(); ++member) {
- if (member->getHostAndPort() == toRemove) {
- continue;
- }
+ 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"
+ << "num"
+ << "1")));
+ }
- membersBuilder.append(BSON("_id" << member->getId() <<
- "host" << member->getHostAndPort().toString()));
+ {
+ const string host(_replSet->getSecondaries().front());
+ const mongo::repl::MemberConfig* member =
+ oldConfig.findMemberByHostAndPort(HostAndPort(host));
+ membersBuilder.append(
+ BSON("_id" << member->getId() << "host" << host << "tags" << BSON("dc"
+ << "ny"
+ << "num"
+ << "2")));
}
membersBuilder.done();
+
repl::ReplicaSetConfig newConfig;
- ASSERT_OK(newConfig.initialize(newConfigBuilder.obj()));
- ASSERT_OK(newConfig.validate());
- return newConfig;
+ fassert(28572, newConfig.initialize(newConfigBuilder.done()));
+ fassert(28571, newConfig.validate());
+ _replSet->setConfig(newConfig);
}
-} // namespace
-
- // Stress test case for a node that is previously a primary being removed from the set.
- // This test goes through configurations with different positions for the primary node
- // in the host list returned from the isMaster command. The test here is to make sure
- // that the ReplicaSetMonitor will not crash under these situations.
- TEST(ReplicaSetMonitorTest, PrimaryRemovedFromSetStress) {
- const size_t NODE_COUNT = 5;
- MockReplicaSet replSet("test", NODE_COUNT);
- ConnectionString::ConnectionHook* originalConnHook =
- ConnectionString::getConnectionHook();
- ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook());
-
- const string replSetName(replSet.getSetName());
- set<HostAndPort> seedList;
- seedList.insert(HostAndPort(replSet.getPrimary()));
- ReplicaSetMonitor::createIfNeeded(replSetName, seedList);
-
- const repl::ReplicaSetConfig& origConfig = replSet.getReplConfig();
- mongo::ReplicaSetMonitorPtr replMonitor = ReplicaSetMonitor::get(replSetName);
-
- for (size_t idxToRemove = 0; idxToRemove < NODE_COUNT; idxToRemove++) {
-
- replSet.setConfig(origConfig);
- // Make sure the monitor sees the change
- replMonitor->startOrContinueRefresh().refreshAll();
-
- string hostToRemove;
- {
- BSONObjBuilder monitorStateBuilder;
- replMonitor->appendInfo(monitorStateBuilder);
- BSONObj monitorState = monitorStateBuilder.done();
-
- BSONElement hostsElem = monitorState["hosts"];
- BSONElement addrElem = hostsElem[mongo::str::stream() << idxToRemove]["addr"];
- hostToRemove = addrElem.String();
- }
-
- replSet.setPrimary(hostToRemove);
- // Make sure the monitor sees the new primary
- replMonitor->startOrContinueRefresh().refreshAll();
-
- repl::ReplicaSetConfig newConfig =
- _getConfigWithMemberRemoved(origConfig, HostAndPort(hostToRemove));
- replSet.setConfig(newConfig);
- replSet.setPrimary(newConfig.getMemberAt(0).getHostAndPort().toString());
- // Force refresh -> should not crash
- replMonitor->startOrContinueRefresh().refreshAll();
- }
+ void tearDown() {
+ ConnectionString::setConnectionHook(_originalConnectionHook);
ReplicaSetMonitor::cleanup();
- ConnectionString::setConnectionHook(originalConnHook);
- mongo::ScopedDbConnection::clearPool();
+ _replSet.reset();
}
- /**
- * Warning: Tests running this fixture cannot be run in parallel with other tests
- * that use ConnectionString::setConnectionHook.
- */
- class TwoNodeWithTags: public mongo::unittest::Test {
- protected:
- void setUp() {
- _replSet.reset(new MockReplicaSet("test", 2));
- _originalConnectionHook = ConnectionString::getConnectionHook();
- ConnectionString::setConnectionHook(
- mongo::MockConnRegistry::get()->getConnStrHook());
-
- 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" <<
- "num" << "1")));
- }
-
- {
- const string host(_replSet->getSecondaries().front());
- const mongo::repl::MemberConfig* member =
- oldConfig.findMemberByHostAndPort(HostAndPort(host));
- membersBuilder.append(BSON("_id" << member->getId() <<
- "host" << host <<
- "tags" << BSON("dc" << "ny" <<
- "num" << "2")));
- }
-
- membersBuilder.done();
-
- repl::ReplicaSetConfig newConfig;
- fassert(28572, newConfig.initialize(newConfigBuilder.done()));
- fassert(28571, newConfig.validate());
- _replSet->setConfig(newConfig);
- }
-
- void tearDown() {
- ConnectionString::setConnectionHook(_originalConnectionHook);
- ReplicaSetMonitor::cleanup();
- _replSet.reset();
- }
+ MockReplicaSet* getReplSet() {
+ return _replSet.get();
+ }
- MockReplicaSet* getReplSet() {
- return _replSet.get();
- }
+private:
+ ConnectionString::ConnectionHook* _originalConnectionHook;
+ std::unique_ptr<MockReplicaSet> _replSet;
+};
- private:
- ConnectionString::ConnectionHook* _originalConnectionHook;
- std::unique_ptr<MockReplicaSet> _replSet;
- };
+// Tests the case where the connection to secondary went bad and the replica set
+// monitor needs to perform a refresh of it's local view then retry the node selection
+// again after the refresh.
+TEST_F(TwoNodeWithTags, SecDownRetryNoTag) {
+ MockReplicaSet* replSet = getReplSet();
- // Tests the case where the connection to secondary went bad and the replica set
- // monitor needs to perform a refresh of it's local view then retry the node selection
- // again after the refresh.
- TEST_F(TwoNodeWithTags, SecDownRetryNoTag) {
- MockReplicaSet* replSet = getReplSet();
+ set<HostAndPort> seedList;
+ seedList.insert(HostAndPort(replSet->getPrimary()));
+ ReplicaSetMonitor::createIfNeeded(replSet->getSetName(), seedList);
- set<HostAndPort> seedList;
- seedList.insert(HostAndPort(replSet->getPrimary()));
- ReplicaSetMonitor::createIfNeeded(replSet->getSetName(), seedList);
+ const string secHost(replSet->getSecondaries().front());
+ replSet->kill(secHost);
- const string secHost(replSet->getSecondaries().front());
- replSet->kill(secHost);
+ ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
+ // Make sure monitor sees the dead secondary
+ monitor->startOrContinueRefresh().refreshAll();
- ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
- // Make sure monitor sees the dead secondary
- monitor->startOrContinueRefresh().refreshAll();
+ replSet->restore(secHost);
- replSet->restore(secHost);
+ HostAndPort node = monitor->getHostOrRefresh(
+ ReadPreferenceSetting(mongo::ReadPreference::SecondaryOnly, TagSet()));
- HostAndPort node = monitor->getHostOrRefresh(
- ReadPreferenceSetting(mongo::ReadPreference::SecondaryOnly, TagSet()));
+ ASSERT_FALSE(monitor->isPrimary(node));
+ ASSERT_EQUALS(secHost, node.toString());
+}
- ASSERT_FALSE(monitor->isPrimary(node));
- ASSERT_EQUALS(secHost, node.toString());
- }
+// Tests the case where the connection to secondary went bad and the replica set
+// monitor needs to perform a refresh of it's local view then retry the node selection
+// with tags again after the refresh.
+TEST_F(TwoNodeWithTags, SecDownRetryWithTag) {
+ MockReplicaSet* replSet = getReplSet();
- // Tests the case where the connection to secondary went bad and the replica set
- // monitor needs to perform a refresh of it's local view then retry the node selection
- // with tags again after the refresh.
- TEST_F(TwoNodeWithTags, SecDownRetryWithTag) {
- MockReplicaSet* replSet = getReplSet();
+ set<HostAndPort> seedList;
+ seedList.insert(HostAndPort(replSet->getPrimary()));
+ ReplicaSetMonitor::createIfNeeded(replSet->getSetName(), seedList);
- set<HostAndPort> seedList;
- seedList.insert(HostAndPort(replSet->getPrimary()));
- ReplicaSetMonitor::createIfNeeded(replSet->getSetName(), seedList);
+ const string secHost(replSet->getSecondaries().front());
+ replSet->kill(secHost);
- const string secHost(replSet->getSecondaries().front());
- replSet->kill(secHost);
+ ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
+ // Make sure monitor sees the dead secondary
+ monitor->startOrContinueRefresh().refreshAll();
- ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
- // Make sure monitor sees the dead secondary
- monitor->startOrContinueRefresh().refreshAll();
+ replSet->restore(secHost);
- replSet->restore(secHost);
+ TagSet tags(BSON_ARRAY(BSON("dc"
+ << "ny")));
+ HostAndPort node = monitor->getHostOrRefresh(
+ ReadPreferenceSetting(mongo::ReadPreference::SecondaryOnly, tags));
- TagSet tags(BSON_ARRAY(BSON("dc" << "ny")));
- HostAndPort node = monitor->getHostOrRefresh(
- ReadPreferenceSetting(mongo::ReadPreference::SecondaryOnly, tags));
-
- ASSERT_FALSE(monitor->isPrimary(node));
- ASSERT_EQUALS(secHost, node.toString());
- }
+ ASSERT_FALSE(monitor->isPrimary(node));
+ ASSERT_EQUALS(secHost, node.toString());
+}
-} // namespace mongo
+} // namespace mongo