summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaley Connelly <haley.connelly@mongodb.com>2020-02-28 16:43:26 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-03 00:17:45 +0000
commitb7dfdde9d038433cf34e77618d4b1b114d3f4d91 (patch)
treeda9853830a63a84dac2441eab819b0460afc6a39
parent7a7ff689ca4ab64caab4c96e4947c30257d61b89 (diff)
downloadmongo-b7dfdde9d038433cf34e77618d4b1b114d3f4d91.tar.gz
SERVER-46509 Change disableStreamableReplicaSetMonitor server parameter to an enum
-rw-r--r--jstests/sharding/read_pref.js2
-rw-r--r--src/mongo/client/SConscript30
-rw-r--r--src/mongo/client/dbclient_rs_test.cpp48
-rw-r--r--src/mongo/client/disable_streamable_rsm_flag_test.cpp128
-rw-r--r--src/mongo/client/replica_set_monitor_manager.cpp13
-rw-r--r--src/mongo/client/replica_set_monitor_protocol_test_fixture.cpp59
-rw-r--r--src/mongo/client/replica_set_monitor_protocol_test_fixture.h70
-rw-r--r--src/mongo/client/replica_set_monitor_server_parameters.cpp67
-rw-r--r--src/mongo/client/replica_set_monitor_server_parameters.h42
-rw-r--r--src/mongo/client/replica_set_monitor_server_parameters.idl (renamed from src/mongo/client/replica_set_monitor_params.idl)11
-rw-r--r--src/mongo/client/replica_set_monitor_server_parameters_test.cpp97
-rw-r--r--src/mongo/client/scanning_replica_set_monitor_test_fixture.cpp17
-rw-r--r--src/mongo/client/scanning_replica_set_monitor_test_fixture.h9
-rw-r--r--src/mongo/client/streamable_replica_set_monitor.cpp4
-rw-r--r--src/mongo/client/streamable_replica_set_monitor.h2
-rw-r--r--src/mongo/dbtests/SConscript3
-rw-r--r--src/mongo/dbtests/scanning_replica_set_monitor_test.cpp (renamed from src/mongo/dbtests/replica_set_monitor_test.cpp)11
17 files changed, 416 insertions, 197 deletions
diff --git a/jstests/sharding/read_pref.js b/jstests/sharding/read_pref.js
index b3e4f835ea7..0c2bb707a56 100644
--- a/jstests/sharding/read_pref.js
+++ b/jstests/sharding/read_pref.js
@@ -1,6 +1,6 @@
/**
* Integration test for read preference and tagging. The more comprehensive unit test can be found
- * in dbtests/replica_set_monitor_test.cpp.
+ * in dbtests/scanning_replica_set_monitor_test.cpp.
*/
// Checking UUID consistency involves talking to a shard node, which in this test is shutdown
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript
index b06b7d6f20d..add7d9c29fc 100644
--- a/src/mongo/client/SConscript
+++ b/src/mongo/client/SConscript
@@ -197,7 +197,6 @@ clientDriverEnv.Library(
'scanning_replica_set_monitor.cpp',
'streamable_replica_set_monitor.cpp',
'replica_set_monitor_manager.cpp',
- env.Idlc('replica_set_monitor_params.idl')[0],
'server_ping_monitor.cpp',
],
LIBDEPS=[
@@ -210,6 +209,7 @@ clientDriverEnv.Library(
'$BUILD_DIR/mongo/util/background_job',
'$BUILD_DIR/mongo/util/md5',
'$BUILD_DIR/mongo/util/net/network',
+ 'replica_set_monitor_server_parameters',
'clientdriver_minimal',
'read_preference',
],
@@ -221,6 +221,17 @@ clientDriverEnv.Library(
)
env.Library(
+ target='replica_set_monitor_server_parameters',
+ source=[
+ 'replica_set_monitor_server_parameters.cpp',
+ env.Idlc('replica_set_monitor_server_parameters.idl')[0],
+ ],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/idl/server_parameter',
+ ]
+)
+
+env.Library(
target='async_client',
source=[
'async_client.cpp',
@@ -307,12 +318,12 @@ env.CppUnitTest(
'authenticate_test.cpp',
'connection_string_test.cpp',
'dbclient_cursor_test.cpp',
- 'disable_streamable_rsm_flag_test.cpp',
'fetcher_test.cpp',
'index_spec_test.cpp',
'mongo_uri_test.cpp',
'read_preference_test.cpp',
'remote_command_retry_scheduler_test.cpp',
+ 'replica_set_monitor_server_parameters_test.cpp',
'scanning_replica_set_monitor_internal_test.cpp',
'scanning_replica_set_monitor_read_preference_test.cpp',
'scanning_replica_set_monitor_scan_test.cpp',
@@ -342,6 +353,18 @@ env.CppUnitTest(
'fetcher',
'read_preference',
'remote_command_retry_scheduler',
+ 'replica_set_monitor_protocol_test_fixture',
+ ],
+)
+
+env.Library(
+ target='replica_set_monitor_protocol_test_fixture',
+ source=[
+ 'replica_set_monitor_protocol_test_fixture.cpp',
+ ],
+ LIBDEPS=[
+ '$BUILD_DIR/mongo/dbtests/mocklib',
+ 'clientdriver_network',
],
)
@@ -350,11 +373,12 @@ env.CppUnitTest(
env.CppUnitTest(
target='client_rs_test',
source=[
- 'dbclient_rs_test.cpp'
+ 'dbclient_rs_test.cpp',
],
LIBDEPS=[
'$BUILD_DIR/mongo/dbtests/mocklib',
'clientdriver_network',
+ 'replica_set_monitor_protocol_test_fixture',
],
)
diff --git a/src/mongo/client/dbclient_rs_test.cpp b/src/mongo/client/dbclient_rs_test.cpp
index 9a08319b5c1..27653197c33 100644
--- a/src/mongo/client/dbclient_rs_test.cpp
+++ b/src/mongo/client/dbclient_rs_test.cpp
@@ -44,7 +44,7 @@
#include "mongo/client/connpool.h"
#include "mongo/client/dbclient_rs.h"
#include "mongo/client/replica_set_monitor.h"
-#include "mongo/client/replica_set_monitor_params_gen.h"
+#include "mongo/client/replica_set_monitor_protocol_test_fixture.h"
#include "mongo/db/jsobj.h"
#include "mongo/dbtests/mock/mock_conn_registry.h"
#include "mongo/dbtests/mock/mock_replica_set.h"
@@ -77,58 +77,18 @@ BSONObj makeMetadata(ReadPreference rp, TagSet tagSet) {
/**
* Ensures a global ServiceContext exists and the ScanningReplicaSetMonitor is used for each test.
*/
-class DBClientRSTest : public unittest::Test {
+class DBClientRSTest : public ReplicaSetMonitorProtocolTestFixture {
protected:
void setUp() {
auto serviceContext = ServiceContext::make();
setGlobalServiceContext(std::move(serviceContext));
- setDisableStreamableTrue();
+ setRSMProtocol(ReplicaSetMonitorProtocol::kScanning);
}
void tearDown() {
- resetDisableStreamable();
+ unsetRSMProtocol();
}
-
- /**
- * Ensures the ScanningReplicaSetMonitor is used for the tests.
- */
- void setDisableStreamableTrue() {
- const BSONObj newFlagParameter = BSON(kDisableStreamableFlagName << true);
- BSONObjIterator parameterIterator(newFlagParameter);
- BSONElement newParameter = parameterIterator.next();
- const auto foundParameter = findDisableStreamableServerParameter();
-
- uassertStatusOK(foundParameter->second->set(newParameter));
- ASSERT_TRUE(disableStreamableReplicaSetMonitor.load());
- }
-
- /**
- * Restores the disableStreamableReplicaSetMonitor parameter to its default value.
- */
- void resetDisableStreamable() {
- const auto defaultParameter = kDefaultParameter[kDisableStreamableFlagName];
- const auto foundParameter = findDisableStreamableServerParameter();
-
- uassertStatusOK(foundParameter->second->set(defaultParameter));
- }
-
- /**
- * Finds the disableStreamableReplicaSetMonitor ServerParameter.
- */
- ServerParameter::Map::const_iterator findDisableStreamableServerParameter() {
- const ServerParameter::Map& parameterMap = ServerParameterSet::getGlobal()->getMap();
- return parameterMap.find(kDisableStreamableFlagName);
- }
-
- static inline const std::string kDisableStreamableFlagName =
- "disableStreamableReplicaSetMonitor";
-
- /**
- * A BSONObj containing the default for the disableStreamableReplicaSetMonitor flag.
- */
- static inline const BSONObj kDefaultParameter =
- BSON(kDisableStreamableFlagName << disableStreamableReplicaSetMonitor.load());
};
/**
diff --git a/src/mongo/client/disable_streamable_rsm_flag_test.cpp b/src/mongo/client/disable_streamable_rsm_flag_test.cpp
deleted file mode 100644
index 0cad97280d5..00000000000
--- a/src/mongo/client/disable_streamable_rsm_flag_test.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Copyright (C) 2020-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/client/replica_set_monitor.h"
-#include "mongo/client/replica_set_monitor_params_gen.h"
-#include "mongo/client/scanning_replica_set_monitor.h"
-#include "mongo/client/streamable_replica_set_monitor.h"
-#include "mongo/unittest/unittest.h"
-#include "mongo/util/assert_util.h"
-
-namespace mongo {
-namespace {
-
-class RSMDisableStreamableFlagTestFixture : public unittest::Test {
-protected:
- void setUp() {
- setGlobalServiceContext(ServiceContext::make());
- ReplicaSetMonitor::cleanup();
- }
-
- void tearDown() {
- unsetParameter();
- }
-
- /**
- * Sets the data of the disableStreamableReplicaSetMonitor parameter to flagValue.
- */
- void setParameter(bool flagValue) {
- const BSONObj newFlagParameter = BSON(kDisableStreamableFlagName << flagValue);
- BSONObjIterator parameterIterator(newFlagParameter);
- BSONElement newParameter = parameterIterator.next();
- const auto foundParameter = findDisableStreamableServerParameter();
-
- uassertStatusOK(foundParameter->second->set(newParameter));
- ASSERT_EQ(flagValue, disableStreamableReplicaSetMonitor.load());
- }
-
- /**
- * Restores the disableStreamableReplicaSetMonitor parameter to its default value.
- */
- void unsetParameter() {
- const auto defaultParameter = kDefaultParameter[kDisableStreamableFlagName];
- const auto foundParameter = findDisableStreamableServerParameter();
-
- uassertStatusOK(foundParameter->second->set(defaultParameter));
- }
-
- /**
- * Finds the disableStreamableReplicaSetMonitor ServerParameter.
- */
- ServerParameter::Map::const_iterator findDisableStreamableServerParameter() {
- const ServerParameter::Map& parameterMap = ServerParameterSet::getGlobal()->getMap();
- return parameterMap.find(kDisableStreamableFlagName);
- }
-
- static inline const std::string kDisableStreamableFlagName =
- "disableStreamableReplicaSetMonitor";
-
- /**
- * A BSONObj containing the default for the disableStreamableReplicaSetMonitor flag.
- */
- static inline const BSONObj kDefaultParameter =
- BSON(kDisableStreamableFlagName << disableStreamableReplicaSetMonitor.load());
-};
-
-/**
- * Checks that a ScanningReplicaSetMonitor is created when the disableStreamableReplicaSetMonitor
- * flag is set to true.
- */
-TEST_F(RSMDisableStreamableFlagTestFixture, checkIsScanningIfDisableStreamableIsTrue) {
- setParameter(true);
- auto uri = MongoURI::parse("mongodb://a,b,c/?replicaSet=name");
- ASSERT_OK(uri.getStatus());
- auto createdMonitor = ReplicaSetMonitor::createIfNeeded(uri.getValue());
-
- // If the created monitor does not point to a ScanningReplicaSetMonitor, the cast returns a
- // nullptr.
- auto scanningMonitorCast = dynamic_cast<ScanningReplicaSetMonitor*>(createdMonitor.get());
- ASSERT(scanningMonitorCast);
-
- auto streamableMonitorCast = dynamic_cast<StreamableReplicaSetMonitor*>(createdMonitor.get());
- ASSERT_FALSE(streamableMonitorCast);
-}
-
-/**
- * Checks that a StreamableReplicaSetMonitor is created when the the
- * disableStreamableReplicaSetMonitor flag is set to false.
- *
- * TODO SERVER-43332: Once the StreamableReplicaSetMonitor is integrated into the codebase, this
- * test should mirror the logic in checkIsScanningIfDisableStreamableIsTrue accordingly.
- */
-TEST_F(RSMDisableStreamableFlagTestFixture, checkIsStreamableIfDisableStreamableIsFalse) {
- setParameter(false);
- auto uri = MongoURI::parse("mongodb://a,b,c/?replicaSet=name");
- ASSERT_OK(uri.getStatus());
- ASSERT_THROWS_CODE(ReplicaSetMonitor::createIfNeeded(uri.getValue()), DBException, 31451);
-}
-
-} // namespace
-} // namespace mongo
diff --git a/src/mongo/client/replica_set_monitor_manager.cpp b/src/mongo/client/replica_set_monitor_manager.cpp
index 1e81bbbb688..b55d9f5a61e 100644
--- a/src/mongo/client/replica_set_monitor_manager.cpp
+++ b/src/mongo/client/replica_set_monitor_manager.cpp
@@ -38,7 +38,7 @@
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/client/connection_string.h"
#include "mongo/client/mongo_uri.h"
-#include "mongo/client/replica_set_monitor_params_gen.h"
+#include "mongo/client/replica_set_monitor_server_parameters.h"
#include "mongo/client/scanning_replica_set_monitor.h"
#include "mongo/client/streamable_replica_set_monitor.h"
#include "mongo/executor/network_connection_hook.h"
@@ -132,14 +132,15 @@ shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorManager::getOrCreateMonitor(const
LOGV2(20186, "Starting new replica set monitor for {uri}", "uri"_attr = uri.toString());
- if (disableStreamableReplicaSetMonitor.load()) {
- auto newMonitor = std::make_shared<ScanningReplicaSetMonitor>(uri);
- _monitors[setName] = newMonitor;
+ std::shared_ptr<ReplicaSetMonitor> newMonitor;
+ if (gReplicaSetMonitorProtocol == ReplicaSetMonitorProtocol::kScanning) {
+ newMonitor = std::make_shared<ScanningReplicaSetMonitor>(uri);
newMonitor->init();
- return newMonitor;
} else {
- uasserted(31451, "StreamableReplicaSetMonitor is not yet implemented");
+ newMonitor = std::make_shared<StreamableReplicaSetMonitor>(uri);
}
+ _monitors[setName] = newMonitor;
+ return newMonitor;
}
vector<string> ReplicaSetMonitorManager::getAllSetNames() {
diff --git a/src/mongo/client/replica_set_monitor_protocol_test_fixture.cpp b/src/mongo/client/replica_set_monitor_protocol_test_fixture.cpp
new file mode 100644
index 00000000000..1fa996ab6e1
--- /dev/null
+++ b/src/mongo/client/replica_set_monitor_protocol_test_fixture.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2020-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+#include "mongo/platform/basic.h"
+
+#include "mongo/client/replica_set_monitor_protocol_test_fixture.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/assert_util.h"
+
+namespace mongo {
+void ReplicaSetMonitorProtocolTestFixture::setRSMProtocol(ReplicaSetMonitorProtocol protocol) {
+ const BSONObj newParameterObj = BSON(kRSMProtocolFieldName << toString(protocol));
+ BSONObjIterator parameterIterator(newParameterObj);
+ BSONElement newParameter = parameterIterator.next();
+ const auto foundParameter = findRSMProtocolServerParameter();
+
+ uassertStatusOK(foundParameter->second->set(newParameter));
+}
+
+void ReplicaSetMonitorProtocolTestFixture::unsetRSMProtocol() {
+ const auto defaultParameter = kDefaultParameter[kRSMProtocolFieldName];
+ const auto foundParameter = findRSMProtocolServerParameter();
+
+ uassertStatusOK(foundParameter->second->set(defaultParameter));
+}
+
+ServerParameter::Map::const_iterator
+ReplicaSetMonitorProtocolTestFixture::findRSMProtocolServerParameter() {
+ const ServerParameter::Map& parameterMap = ServerParameterSet::getGlobal()->getMap();
+ invariant(parameterMap.size());
+ return parameterMap.find(kRSMProtocolFieldName);
+}
+
+} // namespace mongo
diff --git a/src/mongo/client/replica_set_monitor_protocol_test_fixture.h b/src/mongo/client/replica_set_monitor_protocol_test_fixture.h
new file mode 100644
index 00000000000..7c2c7d0ee9d
--- /dev/null
+++ b/src/mongo/client/replica_set_monitor_protocol_test_fixture.h
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2020-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/client/replica_set_monitor_server_parameters.h"
+#include "mongo/client/replica_set_monitor_server_parameters_gen.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/assert_util.h"
+
+namespace mongo {
+
+/**
+ * Test wrapper for tests that need to set and unset the replicaSetMonitorProtocol server parameter.
+ */
+class ReplicaSetMonitorProtocolTestFixture : public unittest::Test {
+protected:
+ /**
+ * Sets the replicaSetMonitorProtocol to 'protocol'.
+ */
+ void setRSMProtocol(ReplicaSetMonitorProtocol protocol);
+
+ /**
+ * Restores the replicaSetMonitorProtocol parameter to its default value.
+ */
+ void unsetRSMProtocol();
+
+ /**
+ * Finds the replicaSetMonitorProtocol ServerParameter.
+ */
+ ServerParameter::Map::const_iterator findRSMProtocolServerParameter();
+
+ static inline const std::string kRSMProtocolFieldName = "replicaSetMonitorProtocol";
+
+ /**
+ * A BSONObj containing the default for the replicaSetMonitorProtocol server parameter.
+ */
+ const BSONObj kDefaultParameter =
+ BSON(kRSMProtocolFieldName << toString(gReplicaSetMonitorProtocol));
+};
+
+} // namespace mongo
diff --git a/src/mongo/client/replica_set_monitor_server_parameters.cpp b/src/mongo/client/replica_set_monitor_server_parameters.cpp
new file mode 100644
index 00000000000..8fe3df2b807
--- /dev/null
+++ b/src/mongo/client/replica_set_monitor_server_parameters.cpp
@@ -0,0 +1,67 @@
+/**
+ * Copyright (C) 2020-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/client/replica_set_monitor_server_parameters.h"
+
+#include "mongo/base/status.h"
+#include "mongo/client/replica_set_monitor_server_parameters_gen.h"
+#include "mongo/util/str.h"
+
+namespace mongo {
+
+ReplicaSetMonitorProtocol gReplicaSetMonitorProtocol{ReplicaSetMonitorProtocol::kScanning};
+
+std::string toString(ReplicaSetMonitorProtocol protocol) {
+ if (protocol == ReplicaSetMonitorProtocol::kScanning) {
+ return "scanning";
+ } else {
+ return "sdam";
+ }
+}
+
+void RSMProtocolServerParameter::append(OperationContext*,
+ BSONObjBuilder& builder,
+ const std::string& name) {
+ builder.append(name, toString(gReplicaSetMonitorProtocol));
+}
+
+Status RSMProtocolServerParameter::setFromString(const std::string& protocolStr) {
+ if (protocolStr == toString(ReplicaSetMonitorProtocol::kScanning)) {
+ gReplicaSetMonitorProtocol = ReplicaSetMonitorProtocol::kScanning;
+ } else if (protocolStr == toString(ReplicaSetMonitorProtocol::kSdam)) {
+ gReplicaSetMonitorProtocol = ReplicaSetMonitorProtocol::kSdam;
+ } else {
+ return Status{ErrorCodes::BadValue,
+ str::stream()
+ << "Unrecognized replicaSetMonitorProtocol '" << protocolStr << "'"};
+ }
+ return Status::OK();
+}
+
+} // namespace mongo
diff --git a/src/mongo/client/replica_set_monitor_server_parameters.h b/src/mongo/client/replica_set_monitor_server_parameters.h
new file mode 100644
index 00000000000..14d0ca7f612
--- /dev/null
+++ b/src/mongo/client/replica_set_monitor_server_parameters.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2020-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include "mongo/platform/atomic_word.h"
+#include "mongo/platform/basic.h"
+#include "mongo/util/str.h"
+
+namespace mongo {
+
+enum class ReplicaSetMonitorProtocol { kScanning, kSdam };
+extern ReplicaSetMonitorProtocol gReplicaSetMonitorProtocol;
+std::string toString(ReplicaSetMonitorProtocol protocol);
+
+} // namespace mongo
diff --git a/src/mongo/client/replica_set_monitor_params.idl b/src/mongo/client/replica_set_monitor_server_parameters.idl
index f5b0e571305..8255897b3a4 100644
--- a/src/mongo/client/replica_set_monitor_params.idl
+++ b/src/mongo/client/replica_set_monitor_server_parameters.idl
@@ -29,11 +29,10 @@ global:
cpp_namespace: mongo
server_parameters:
- disableStreamableReplicaSetMonitor:
+ replicaSetMonitorProtocol:
description: >-
- Disable the StreamableReplicaSetMonitor and revert to the prior behavior with the
- ScanningReplicaSetMonitor
+ Select which replica set monitor protocol to use - the new 'sdam' compliant protocol or
+ the old 'scanning' protocol.
set_at: startup
- cpp_vartype: AtomicWord<bool>
- cpp_varname: disableStreamableReplicaSetMonitor
- default: true
+ cpp_class:
+ name: RSMProtocolServerParameter
diff --git a/src/mongo/client/replica_set_monitor_server_parameters_test.cpp b/src/mongo/client/replica_set_monitor_server_parameters_test.cpp
new file mode 100644
index 00000000000..f9644bada88
--- /dev/null
+++ b/src/mongo/client/replica_set_monitor_server_parameters_test.cpp
@@ -0,0 +1,97 @@
+/**
+ * Copyright (C) 2020-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/client/replica_set_monitor.h"
+#include "mongo/client/replica_set_monitor_protocol_test_fixture.h"
+#include "mongo/client/replica_set_monitor_server_parameters.h"
+#include "mongo/client/scanning_replica_set_monitor.h"
+#include "mongo/client/streamable_replica_set_monitor.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/assert_util.h"
+
+namespace mongo {
+namespace {
+
+/**
+ * Tests the replicaSetMonitorProtocol server parameter.
+ */
+class ReplicaSetMonitorProtocolTest : public ReplicaSetMonitorProtocolTestFixture {
+protected:
+ void setUp() {
+ setGlobalServiceContext(ServiceContext::make());
+ ReplicaSetMonitor::cleanup();
+ }
+
+ void tearDown() {
+ ReplicaSetMonitor::cleanup();
+ unsetRSMProtocol();
+ }
+};
+
+/**
+ * Checks that a StreamableReplicaSetMonitor is created when the replicaSetMonitorProtocol server
+ * parameter is set to 'sdam'.
+ */
+TEST_F(ReplicaSetMonitorProtocolTest, checkRSMProtocolParamSdam) {
+ setRSMProtocol(ReplicaSetMonitorProtocol::kSdam);
+ auto uri = MongoURI::parse("mongodb:a,b,c/?replicaSet=name");
+ ASSERT_OK(uri.getStatus());
+ auto createdMonitor = ReplicaSetMonitor::createIfNeeded(uri.getValue());
+
+ // If the created monitor does not point to a ScanningReplicaSetMonitor, the cast returns a
+ // nullptr.
+ auto streamableMonitorCast = dynamic_cast<StreamableReplicaSetMonitor*>(createdMonitor.get());
+ ASSERT(streamableMonitorCast);
+
+ auto scanningMonitorCast = dynamic_cast<ScanningReplicaSetMonitor*>(createdMonitor.get());
+ ASSERT_FALSE(scanningMonitorCast);
+}
+
+/**
+ * Checks that a ScanningReplicaSetMonitor is created when the replicaSetMonitorProtocol server
+ * parameter is set to 'scanning'.
+ */
+TEST_F(ReplicaSetMonitorProtocolTest, checkRSMProtocolParamScanning) {
+ setRSMProtocol(ReplicaSetMonitorProtocol::kScanning);
+ auto uri = MongoURI::parse("mongodb:a,b,c/?replicaSet=name");
+ ASSERT_OK(uri.getStatus());
+ auto createdMonitor = ReplicaSetMonitor::createIfNeeded(uri.getValue());
+
+ // If the created monitor does not point to a ScanningReplicaSetMonitor, the cast returns a
+ // nullptr.
+ auto scanningMonitorCast = dynamic_cast<ScanningReplicaSetMonitor*>(createdMonitor.get());
+ ASSERT(scanningMonitorCast);
+
+ auto streamableMonitorCast = dynamic_cast<StreamableReplicaSetMonitor*>(createdMonitor.get());
+ ASSERT_FALSE(streamableMonitorCast);
+}
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/client/scanning_replica_set_monitor_test_fixture.cpp b/src/mongo/client/scanning_replica_set_monitor_test_fixture.cpp
index fa7f13cccc8..9416bfa785c 100644
--- a/src/mongo/client/scanning_replica_set_monitor_test_fixture.cpp
+++ b/src/mongo/client/scanning_replica_set_monitor_test_fixture.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018-present MongoDB, Inc.
+ * Copyright (C) 2020-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
@@ -32,6 +32,21 @@
#include "mongo/client/scanning_replica_set_monitor_test_fixture.h"
namespace mongo {
+
+/**
+ * Setup every test to use replicaSetMonitorProtocol::kScanning.
+ */
+void ScanningReplicaSetMonitorTest::setUp() {
+ setGlobalServiceContext(ServiceContext::make());
+ setRSMProtocol(ReplicaSetMonitorProtocol::kScanning);
+ ReplicaSetMonitor::cleanup();
+}
+
+void ScanningReplicaSetMonitorTest::tearDown() {
+ ReplicaSetMonitor::cleanup();
+ unsetRSMProtocol();
+}
+
const std::vector<HostAndPort> ScanningReplicaSetMonitorTest::basicSeeds = {
HostAndPort("a"), HostAndPort("b"), HostAndPort("c")};
const std::set<HostAndPort> ScanningReplicaSetMonitorTest::basicSeedsSet = {std::begin(basicSeeds),
diff --git a/src/mongo/client/scanning_replica_set_monitor_test_fixture.h b/src/mongo/client/scanning_replica_set_monitor_test_fixture.h
index a48584ad362..3ecf3454bca 100644
--- a/src/mongo/client/scanning_replica_set_monitor_test_fixture.h
+++ b/src/mongo/client/scanning_replica_set_monitor_test_fixture.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018-present MongoDB, Inc.
+ * Copyright (C) 2020-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
@@ -34,6 +34,7 @@
#include <vector>
#include "mongo/client/replica_set_change_notifier.h"
+#include "mongo/client/replica_set_monitor_protocol_test_fixture.h"
#include "mongo/client/scanning_replica_set_monitor.h"
#include "mongo/client/scanning_replica_set_monitor_internal.h"
#include "mongo/unittest/unittest.h"
@@ -44,7 +45,7 @@ namespace mongo {
// current (only) thread, so they do not lock SetState::mutex before examining state. This is
// NOT something that non-test code should do.
-class ScanningReplicaSetMonitorTest : public unittest::Test {
+class ScanningReplicaSetMonitorTest : public ReplicaSetMonitorProtocolTestFixture {
public:
// Pull in nested types
using SetState = ScanningReplicaSetMonitor::SetState;
@@ -73,8 +74,8 @@ public:
std::forward<Args>(args)..., &_notifier, nullptr);
}
- void setUp() override {}
- void tearDown() override {}
+ void setUp() override;
+ void tearDown() override;
static const std::vector<HostAndPort> basicSeeds;
static const std::set<HostAndPort> basicSeedsSet;
diff --git a/src/mongo/client/streamable_replica_set_monitor.cpp b/src/mongo/client/streamable_replica_set_monitor.cpp
index 0056a98c567..e8c0b2b9756 100644
--- a/src/mongo/client/streamable_replica_set_monitor.cpp
+++ b/src/mongo/client/streamable_replica_set_monitor.cpp
@@ -105,4 +105,8 @@ bool StreamableReplicaSetMonitor::isKnownToHaveGoodPrimary() const {
MONGO_UNREACHABLE;
}
+void StreamableReplicaSetMonitor::runScanForMockReplicaSet() {
+ MONGO_UNREACHABLE;
+}
+
} // namespace mongo
diff --git a/src/mongo/client/streamable_replica_set_monitor.h b/src/mongo/client/streamable_replica_set_monitor.h
index 8c27301660e..1d411c23c31 100644
--- a/src/mongo/client/streamable_replica_set_monitor.h
+++ b/src/mongo/client/streamable_replica_set_monitor.h
@@ -88,6 +88,8 @@ public:
void appendInfo(BSONObjBuilder& b, bool forFTDC = false) const override;
bool isKnownToHaveGoodPrimary() const override;
+
+ void runScanForMockReplicaSet() override;
};
} // namespace mongo
diff --git a/src/mongo/dbtests/SConscript b/src/mongo/dbtests/SConscript
index 3a79afad55a..ad90560f7c2 100644
--- a/src/mongo/dbtests/SConscript
+++ b/src/mongo/dbtests/SConscript
@@ -114,10 +114,10 @@ if not has_option('noshell') and usemozjs:
'query_stage_trial.cpp',
'query_stage_update.cpp',
'querytests.cpp',
- 'replica_set_monitor_test.cpp',
'replica_set_tests.cpp',
'repltests.cpp',
'rollbacktests.cpp',
+ 'scanning_replica_set_monitor_test.cpp',
'socktests.cpp',
'storage_timestamp_tests.cpp',
'threadedtests.cpp',
@@ -128,6 +128,7 @@ if not has_option('noshell') and usemozjs:
],
LIBDEPS=[
"$BUILD_DIR/mongo/bson/mutable/mutable_bson_test_utils",
+ "$BUILD_DIR/mongo/client/replica_set_monitor_protocol_test_fixture",
"$BUILD_DIR/mongo/db/auth/authmongod",
"$BUILD_DIR/mongo/db/bson/dotted_path_support",
"$BUILD_DIR/mongo/db/catalog/collection_validation",
diff --git a/src/mongo/dbtests/replica_set_monitor_test.cpp b/src/mongo/dbtests/scanning_replica_set_monitor_test.cpp
index 14571926693..69f90bb561a 100644
--- a/src/mongo/dbtests/replica_set_monitor_test.cpp
+++ b/src/mongo/dbtests/scanning_replica_set_monitor_test.cpp
@@ -36,6 +36,7 @@
#include "mongo/client/connpool.h"
#include "mongo/client/dbclient_rs.h"
#include "mongo/client/replica_set_monitor.h"
+#include "mongo/client/replica_set_monitor_protocol_test_fixture.h"
#include "mongo/client/scanning_replica_set_monitor_internal.h"
#include "mongo/dbtests/mock/mock_conn_registry.h"
#include "mongo/dbtests/mock/mock_replica_set.h"
@@ -62,12 +63,15 @@ MONGO_INITIALIZER(DisableReplicaSetMonitorRefreshRetries)(InitializerContext*) {
* Warning: Tests running this fixture cannot be run in parallel with other tests
* that uses ConnectionString::setConnectionHook
*/
-class ReplicaSetMonitorTest : public mongo::unittest::Test {
+class ScanningReplicaSetMonitorDBTest : public ReplicaSetMonitorProtocolTestFixture {
protected:
void setUp() {
_replSet.reset(new MockReplicaSet("test", 3));
_originalConnectionHook = ConnectionString::getConnectionHook();
ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook());
+
+ // Restrict the test to use ReplicaSetMonitorProtocol::kScanning only.
+ setRSMProtocol(ReplicaSetMonitorProtocol::kScanning);
}
void tearDown() {
@@ -75,6 +79,7 @@ protected:
ReplicaSetMonitor::cleanup();
_replSet.reset();
mongo::ScopedDbConnection::clearPool();
+ unsetRSMProtocol();
}
MockReplicaSet* getReplSet() {
@@ -86,7 +91,7 @@ private:
std::unique_ptr<MockReplicaSet> _replSet;
};
-TEST_F(ReplicaSetMonitorTest, SeedWithPriOnlySecDown) {
+TEST_F(ScanningReplicaSetMonitorDBTest, SeedWithPriOnlySecDown) {
// Test to make sure that the monitor doesn't crash when
// ConnectionString::connect returns NULL
MockReplicaSet* replSet = getReplSet();
@@ -144,7 +149,7 @@ repl::ReplSetConfig _getConfigWithMemberRemoved(const repl::ReplSetConfig& oldCo
// 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) {
+TEST(ScanningReplicaSetMonitorDBTest, PrimaryRemovedFromSetStress) {
const size_t NODE_COUNT = 5;
MockReplicaSet replSet("test", NODE_COUNT);
ConnectionString::ConnectionHook* originalConnHook = ConnectionString::getConnectionHook();