diff options
31 files changed, 108 insertions, 60 deletions
diff --git a/src/mongo/client/dbclient.cpp b/src/mongo/client/dbclient.cpp index d7f6c164552..60547965a65 100644 --- a/src/mongo/client/dbclient.cpp +++ b/src/mongo/client/dbclient.cpp @@ -777,7 +777,7 @@ executor::RemoteCommandResponse initWireVersion(DBClientConnection* conn, BSONObjBuilder bob; bob.append("isMaster", 1); - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Only include the host:port of this process in the isMaster command request if test // commands are enabled. mongobridge uses this field to identify the process opening a // connection to it. diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp index d11ee7f1886..43f75bdb83c 100644 --- a/src/mongo/db/auth/sasl_commands.cpp +++ b/src/mongo/db/auth/sasl_commands.cpp @@ -325,7 +325,7 @@ bool CmdSaslContinue::run(OperationContext* opCtx, auto& mechanism = session->getMechanism(); // Authenticating the __system@local user to the admin database on mongos is required // by the auth passthrough test suite. - if (mechanism.getAuthenticationDatabase() != db && !Command::testCommandsEnabled) { + if (mechanism.getAuthenticationDatabase() != db && !getTestCommandsEnabled()) { return CommandHelpers::appendCommandStatus( result, Status(ErrorCodes::ProtocolError, diff --git a/src/mongo/db/auth/sasl_mechanism_registry.h b/src/mongo/db/auth/sasl_mechanism_registry.h index 6a6d8fe9d33..bd9343296c4 100644 --- a/src/mongo/db/auth/sasl_mechanism_registry.h +++ b/src/mongo/db/auth/sasl_mechanism_registry.h @@ -161,7 +161,7 @@ public: /** Returns which database contains the user which authentication is being performed against. */ StringData getAuthenticationDatabase() const { - if (Command::testCommandsEnabled && _authenticationDatabase == "admin" && + if (getTestCommandsEnabled() && _authenticationDatabase == "admin" && getPrincipalName() == internalSecurity.user->getName().getUser()) { // Allows authenticating as the internal user against the admin database. This is to // support the auth passthrough test framework on mongos (since you can't use the local diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index 033a1874a75..88cff953b83 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -60,9 +60,6 @@ using logger::LogComponent; namespace { -ExportedServerParameter<bool, ServerParameterType::kStartupOnly> testCommandsParameter( - ServerParameterSet::getGlobal(), "enableTestCommands", &Command::testCommandsEnabled); - const char kWriteConcernField[] = "writeConcern"; const WriteConcernOptions kMajorityWriteConcern( WriteConcernOptions::kMajority, diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index 2a9611fb70f..25ce1f056b0 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -39,6 +39,7 @@ #include "mongo/db/auth/resource_pattern.h" #include "mongo/db/client.h" #include "mongo/db/commands/server_status_metric.h" +#include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/jsobj.h" #include "mongo/db/query/explain.h" #include "mongo/db/repl/read_concern_args.h" @@ -379,33 +380,6 @@ public: OperationContext* opCtx, const OpMsgRequest& request); - /** - * If true, then testing commands are available. Defaults to false. - * - * Testing commands should conditionally register themselves by consulting this flag: - * - * MONGO_INITIALIZER(RegisterMyTestCommand)(InitializerContext* context) { - * if (Command::testCommandsEnabled) { - * // Leaked intentionally: a Command registers itself when constructed. - * new MyTestCommand(); - * } - * return Status::OK(); - * } - * - * To make testing commands available by default, change the value to true before running any - * mongo initializers: - * - * int myMain(int argc, char** argv, char** envp) { - * Command::testCommandsEnabled = true; - * ... - * runGlobalInitializersOrDie(argc, argv, envp); - * ... - * } - * - * Note: variable is defined in test_commands_enabled.cpp as a dependency hack. - */ - static bool testCommandsEnabled; - private: class InvocationShim; diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index d321df1eaac..6d492b765a2 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -9,6 +9,9 @@ env.Library( target="test_commands_enabled", source=[ "test_commands_enabled.cpp", + ], + LIBDEPS=[ + "server_status_core", ] ) diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index 121b1cf3aba..4d454be45fe 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -159,7 +159,7 @@ bool CmdAuthenticate::run(OperationContext* opCtx, user = UserName(cmdObj.getStringField("user"), dbname); } - if (Command::testCommandsEnabled && user.getDB() == "admin" && + if (getTestCommandsEnabled() && user.getDB() == "admin" && user.getUser() == internalSecurity.user->getName().getUser()) { // Allows authenticating as the internal user against the admin database. This is to // support the auth passthrough test framework on mongos (since you can't use the local @@ -278,7 +278,7 @@ public: BSONObjBuilder& result) { AuthorizationSession* authSession = AuthorizationSession::get(Client::getCurrent()); authSession->logoutDatabase(dbname); - if (Command::testCommandsEnabled && dbname == "admin") { + if (getTestCommandsEnabled() && dbname == "admin") { // Allows logging out as the internal user against the admin database, however // this actually logs out of the local database as well. This is to // support the auth passthrough test framework on mongos (since you can't use the diff --git a/src/mongo/db/commands/cpuload.cpp b/src/mongo/db/commands/cpuload.cpp index caa7d3f5ed0..f34804fa97e 100644 --- a/src/mongo/db/commands/cpuload.cpp +++ b/src/mongo/db/commands/cpuload.cpp @@ -82,7 +82,7 @@ public: }; MONGO_INITIALIZER(RegisterCpuLoadCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { new CPULoadCommand(); } return Status::OK(); diff --git a/src/mongo/db/commands/dbcheck.cpp b/src/mongo/db/commands/dbcheck.cpp index d0c1ee0673e..73065a744dc 100644 --- a/src/mongo/db/commands/dbcheck.cpp +++ b/src/mongo/db/commands/dbcheck.cpp @@ -548,7 +548,7 @@ public: }; MONGO_INITIALIZER(RegisterDbCheckCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { new DbCheckCmd(); } return Status::OK(); diff --git a/src/mongo/db/commands/fail_point_cmd.cpp b/src/mongo/db/commands/fail_point_cmd.cpp index 12f58504a76..8476c2d53d3 100644 --- a/src/mongo/db/commands/fail_point_cmd.cpp +++ b/src/mongo/db/commands/fail_point_cmd.cpp @@ -115,7 +115,7 @@ public: } }; MONGO_INITIALIZER(RegisterFaultInjectCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new FaultInjectCmd(); } diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp index 4f8dabc6d9f..3c1d64a5c2f 100644 --- a/src/mongo/db/commands/generic.cpp +++ b/src/mongo/db/commands/generic.cpp @@ -420,7 +420,7 @@ public: }; MONGO_INITIALIZER(RegisterClearLogCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new ClearLogCmd(); } diff --git a/src/mongo/db/commands/hashcmd.cpp b/src/mongo/db/commands/hashcmd.cpp index 709b6952e0f..342852c45ad 100644 --- a/src/mongo/db/commands/hashcmd.cpp +++ b/src/mongo/db/commands/hashcmd.cpp @@ -101,7 +101,7 @@ public: } }; MONGO_INITIALIZER(RegisterHashEltCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new CmdHashElt(); } diff --git a/src/mongo/db/commands/reap_logical_session_cache_now.cpp b/src/mongo/db/commands/reap_logical_session_cache_now.cpp index 062a5e85294..dafd446825d 100644 --- a/src/mongo/db/commands/reap_logical_session_cache_now.cpp +++ b/src/mongo/db/commands/reap_logical_session_cache_now.cpp @@ -84,7 +84,7 @@ public: }; MONGO_INITIALIZER(RegisterReapLogicalSessionCacheNowCommand)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new ReapLogicalSessionCacheNowCommand(); } diff --git a/src/mongo/db/commands/refresh_logical_session_cache_now.cpp b/src/mongo/db/commands/refresh_logical_session_cache_now.cpp index 50d99e16193..68e88bcec4c 100644 --- a/src/mongo/db/commands/refresh_logical_session_cache_now.cpp +++ b/src/mongo/db/commands/refresh_logical_session_cache_now.cpp @@ -85,7 +85,7 @@ public: }; MONGO_INITIALIZER(RegisterRefreshLogicalSessionCacheNowCommand)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new RefreshLogicalSessionCacheNowCommand(); } diff --git a/src/mongo/db/commands/restart_catalog_command.cpp b/src/mongo/db/commands/restart_catalog_command.cpp index 8c02abe44f6..46cd2cd9713 100644 --- a/src/mongo/db/commands/restart_catalog_command.cpp +++ b/src/mongo/db/commands/restart_catalog_command.cpp @@ -115,7 +115,7 @@ public: }; MONGO_INITIALIZER(RegisterRestartCatalogCommand)(InitializerContext* ctx) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new RestartCatalogCmd(); } diff --git a/src/mongo/db/commands/snapshot_management.cpp b/src/mongo/db/commands/snapshot_management.cpp index f445b448800..034d77db67b 100644 --- a/src/mongo/db/commands/snapshot_management.cpp +++ b/src/mongo/db/commands/snapshot_management.cpp @@ -130,7 +130,7 @@ public: }; MONGO_INITIALIZER(RegisterSnapshotManagementCommands)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new CmdMakeSnapshot(); new CmdSetCommittedSnapshot(); diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp index 6ffca594ad4..51f1a72db62 100644 --- a/src/mongo/db/commands/test_commands.cpp +++ b/src/mongo/db/commands/test_commands.cpp @@ -299,7 +299,7 @@ public: // ---------------------------- MONGO_INITIALIZER(RegisterEmptyCappedCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new CapTrunc(); new CmdSleep(); diff --git a/src/mongo/db/commands/test_commands_enabled.cpp b/src/mongo/db/commands/test_commands_enabled.cpp index 24803221c78..d6a60e3c42a 100644 --- a/src/mongo/db/commands/test_commands_enabled.cpp +++ b/src/mongo/db/commands/test_commands_enabled.cpp @@ -28,10 +28,26 @@ #include "mongo/platform/basic.h" -#include "mongo/db/commands.h" +#include "mongo/db/commands/test_commands_enabled.h" + +#include "mongo/db/server_parameters.h" namespace mongo { +namespace { + +bool enabled = false; + +ExportedServerParameter<bool, ServerParameterType::kStartupOnly> testCommandsParameter( + ServerParameterSet::getGlobal(), "enableTestCommands", &enabled); + +} // namespace + +bool getTestCommandsEnabled() { + return enabled; +} -bool Command::testCommandsEnabled = false; +void setTestCommandsEnabled(bool b) { + enabled = b; +} } // namespace mongo diff --git a/src/mongo/db/commands/test_commands_enabled.h b/src/mongo/db/commands/test_commands_enabled.h new file mode 100644 index 00000000000..633c18153b8 --- /dev/null +++ b/src/mongo/db/commands/test_commands_enabled.h @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2018 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * 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 GNU Affero General 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 + +namespace mongo { + +/** + * If true, then testing commands are available. Defaults to false. + * + * Testing commands should conditionally register themselves by consulting this flag: + * + * MONGO_INITIALIZER(RegisterMyTestCommand)(InitializerContext* context) { + * if (getTestCommandsEnabled()) { + * // Leaked intentionally: a Command registers itself when constructed. + * new MyTestCommand(); + * } + * return Status::OK(); + * } + * + * To make testing commands available by default, change the value to true before running any + * mongo initializers: + * + * int myMain(int argc, char** argv, char** envp) { + * setTestCommandsEnabled(true); + * ... + * runGlobalInitializersOrDie(argc, argv, envp); + * ... + * } + */ +bool getTestCommandsEnabled(); +void setTestCommandsEnabled(bool b); + +} // namespace mongo diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp index 6d6bfc1a896..39a79d3297c 100644 --- a/src/mongo/db/exec/stagedebug_cmd.cpp +++ b/src/mongo/db/exec/stagedebug_cmd.cpp @@ -518,7 +518,7 @@ public: }; MONGO_INITIALIZER(RegisterStageDebugCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new StageDebugCmd(); } diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h index f1ee7d5717c..3b4b421f358 100644 --- a/src/mongo/db/pipeline/document_source.h +++ b/src/mongo/db/pipeline/document_source.h @@ -104,7 +104,7 @@ class Document; #define REGISTER_TEST_DOCUMENT_SOURCE(key, liteParser, fullParser) \ REGISTER_DOCUMENT_SOURCE_CONDITIONALLY( \ - key, liteParser, fullParser, Command::testCommandsEnabled) + key, liteParser, fullParser, ::mongo::getTestCommandsEnabled()) /** * Registers a multi-stage alias (such as $sortByCount) to have the single name 'key'. When a stage diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp index eab353f2a39..98abed1bba3 100644 --- a/src/mongo/db/repl/bgsync.cpp +++ b/src/mongo/db/repl/bgsync.cpp @@ -458,7 +458,7 @@ void BackgroundSync::_produce() { fassertFailedWithStatus(34440, exceptionToStatus()); } - const auto logLevel = Command::testCommandsEnabled ? 0 : 1; + const auto logLevel = getTestCommandsEnabled() ? 0 : 1; LOG(logLevel) << "scheduling fetcher to read remote oplog on " << _syncSourceHost << " starting at " << oplogFetcher->getFindQuery_forTest()["filter"]; auto scheduleStatus = oplogFetcher->startup(); diff --git a/src/mongo/db/repl/noop_writer.cpp b/src/mongo/db/repl/noop_writer.cpp index d9da9526cc3..9a6bfa89a0b 100644 --- a/src/mongo/db/repl/noop_writer.cpp +++ b/src/mongo/db/repl/noop_writer.cpp @@ -164,7 +164,7 @@ void NoopWriter::_writeNoop(OperationContext* opCtx) { << " != last primary OpTime: " << lastAppliedOpTime; } else { if (writePeriodicNoops.load()) { - const auto logLevel = Command::testCommandsEnabled ? 0 : 1; + const auto logLevel = getTestCommandsEnabled() ? 0 : 1; LOG(logLevel) << "Writing noop to oplog as there has been no writes to this replica set in over " << _writeInterval; diff --git a/src/mongo/db/repl/repl_set_commands.cpp b/src/mongo/db/repl/repl_set_commands.cpp index 5394982deba..0aa7a7cc601 100644 --- a/src/mongo/db/repl/repl_set_commands.cpp +++ b/src/mongo/db/repl/repl_set_commands.cpp @@ -148,7 +148,7 @@ public: }; MONGO_INITIALIZER(RegisterReplSetTestCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new CmdReplSetTest(); } diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index c9f441637d0..a9106e56cf5 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -1540,7 +1540,7 @@ Status ReplicationCoordinatorImpl::_awaitReplication_inlock( } if (status.getValue() == stdx::cv_status::timeout) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // log state of replica set on timeout to help with diagnosis. BSONObjBuilder progress; _topCoord->fillMemberData(&progress); diff --git a/src/mongo/db/s/config/configsvr_shard_collection_command.cpp b/src/mongo/db/s/config/configsvr_shard_collection_command.cpp index 38596670b96..179e0212794 100644 --- a/src/mongo/db/s/config/configsvr_shard_collection_command.cpp +++ b/src/mongo/db/s/config/configsvr_shard_collection_command.cpp @@ -786,8 +786,7 @@ public: // (unless we are in test mode) uassert(ErrorCodes::IllegalOperation, "only special collections in the config db may be sharded", - nss.ns() == SessionsCollection::kSessionsFullNS || - Command::testCommandsEnabled); + nss.ns() == SessionsCollection::kSessionsFullNS || getTestCommandsEnabled()); auto configShard = uassertStatusOK( Grid::get(opCtx)->shardRegistry()->getShard(opCtx, dbType.getPrimary())); diff --git a/src/mongo/db/storage/mmap_v1/journal_latency_test_cmd.cpp b/src/mongo/db/storage/mmap_v1/journal_latency_test_cmd.cpp index 71ea31abe12..b31bd4945db 100644 --- a/src/mongo/db/storage/mmap_v1/journal_latency_test_cmd.cpp +++ b/src/mongo/db/storage/mmap_v1/journal_latency_test_cmd.cpp @@ -151,7 +151,7 @@ public: } }; MONGO_INITIALIZER(RegisterJournalLatencyTestCmd)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new JournalLatencyTestCmd(); } diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp index c70cd36807f..538ff213702 100644 --- a/src/mongo/dbtests/dbtests.cpp +++ b/src/mongo/dbtests/dbtests.cpp @@ -125,7 +125,7 @@ Status createIndexFromSpec(OperationContext* opCtx, StringData ns, const BSONObj int dbtestsMain(int argc, char** argv, char** envp) { - Command::testCommandsEnabled = true; + ::mongo::setTestCommandsEnabled(true); ::mongo::setupSynchronousSignalHandlers(); mongo::dbtests::initWireSpec(); mongo::runGlobalInitializersOrDie(argc, argv, envp); diff --git a/src/mongo/executor/network_interface_asio_auth.cpp b/src/mongo/executor/network_interface_asio_auth.cpp index 88d9aeae29e..8995495df3d 100644 --- a/src/mongo/executor/network_interface_asio_auth.cpp +++ b/src/mongo/executor/network_interface_asio_auth.cpp @@ -63,7 +63,7 @@ void NetworkInterfaceASIO::_runIsMaster(AsyncOp* op) { const auto versionString = VersionInfoInterface::instance().version(); ClientMetadata::serialize(_options.instanceName, versionString, &bob); - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Only include the host:port of this process in the isMaster command request if test // commands are enabled. mongobridge uses this field to identify the process opening a // connection to it. diff --git a/src/mongo/s/commands/cluster_multicast.cpp b/src/mongo/s/commands/cluster_multicast.cpp index 4f467852064..f2f1de366f8 100644 --- a/src/mongo/s/commands/cluster_multicast.cpp +++ b/src/mongo/s/commands/cluster_multicast.cpp @@ -147,7 +147,7 @@ public: }; MONGO_INITIALIZER(RegisterMulticast)(InitializerContext* context) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { new MulticastCmd(); } return Status::OK(); diff --git a/src/mongo/s/commands/cluster_restart_catalog_command.cpp b/src/mongo/s/commands/cluster_restart_catalog_command.cpp index 949fce3c88c..91a08031056 100644 --- a/src/mongo/s/commands/cluster_restart_catalog_command.cpp +++ b/src/mongo/s/commands/cluster_restart_catalog_command.cpp @@ -89,7 +89,7 @@ public: }; MONGO_INITIALIZER(RegisterClusterRestartCatalogCommand)(InitializerContext* ctx) { - if (Command::testCommandsEnabled) { + if (getTestCommandsEnabled()) { // Leaked intentionally: a Command registers itself when constructed. new ClusterRestartCatalogCmd(); } |