summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2012-12-04 18:11:25 -0500
committerSpencer T Brody <spencer@10gen.com>2012-12-05 18:14:04 -0500
commitfe0d238b0ac31f4b2294bda827cc913d59d6de57 (patch)
treea00d4642d0be41d166e00703f96f5d7ef1b1bfd8 /src
parent50f923938ab2058f4d1a34c72b05abb86ae4122c (diff)
downloadmongo-fe0d238b0ac31f4b2294bda827cc913d59d6de57.tar.gz
SERVER-7122 Add setParameter option to enable/disable testing commands
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/cloner.cpp2
-rwxr-xr-xsrc/mongo/db/commands.cpp11
-rw-r--r--src/mongo/db/commands.h2
-rw-r--r--src/mongo/db/commands/hashcmd.cpp16
-rw-r--r--src/mongo/db/dbcommands.cpp80
-rw-r--r--src/mongo/db/dbcommands_admin.cpp20
-rw-r--r--src/mongo/db/repl/replset_commands.cpp17
7 files changed, 113 insertions, 35 deletions
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index 30d75979bff..a3a6357cc38 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -775,7 +775,7 @@ namespace mongo {
}
};
- MONGO_INITIALIZER(RegisterGodInsertCmd)(InitializerContext* context) {
+ MONGO_INITIALIZER(RegisterNotWithAuthCommands)(InitializerContext* context) {
if (noauth) {
// Leaked intentionally: a Command registers itself when constructed.
new CmdClone();
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index e1f505115ab..5f8a13c51a4 100755
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/client.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/replutil.h"
+#include "mongo/db/server_parameters.h"
namespace mongo {
@@ -38,6 +39,16 @@ namespace mongo {
map<string,Command*> * Command::_webCommands;
map<string,Command*> * Command::_commands;
+ // TODO: set to 0 once tests have been updated to enable this
+ int Command::testCommandsEnabled = 1;
+
+ namespace {
+ // TODO: This should only be settable at the command line, not at runtime. Need SERVER-7778
+ ExportedServerParameter<int> testCommandsParameter(ServerParameterSet::getGlobal(),
+ "enableTestCommands",
+ &Command::testCommandsEnabled);
+ }
+
string Command::parseNsFullyQualified(const string& dbname, const BSONObj& cmdObj) const {
string s = cmdObj.firstElement().valuestr();
NamespaceString nss(s);
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index d02949a6ebc..42161a899ce 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -159,6 +159,8 @@ namespace mongo {
static bool runAgainstRegistered(const char *ns, BSONObj& jsobj, BSONObjBuilder& anObjBuilder, int queryOptions = 0);
static LockType locktype( const string& name );
static Command * findCommand( const string& name );
+ // Set by command line. Controls whether or not testing-only commands should be available.
+ static int testCommandsEnabled;
};
class CmdShutdown : public Command {
diff --git a/src/mongo/db/commands/hashcmd.cpp b/src/mongo/db/commands/hashcmd.cpp
index 043ab37a77b..acf4000505e 100644
--- a/src/mongo/db/commands/hashcmd.cpp
+++ b/src/mongo/db/commands/hashcmd.cpp
@@ -23,6 +23,8 @@
#include <string>
#include <vector>
+#include "mongo/base/init.h"
+#include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -33,14 +35,17 @@
namespace mongo {
+ // Testing only, enabled via command-line.
class CmdHashElt : public Command {
public:
CmdHashElt() : Command("_hashBSONElement") {};
virtual LockType locktype() const { return NONE; }
virtual bool slaveOk() const { return true; }
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
- std::vector<Privilege>* out) {} // No auth required
+ std::vector<Privilege>* out) {}
virtual void help( stringstream& help ) const {
help << "returns the hash of the first BSONElement val in a BSONObj";
}
@@ -77,5 +82,12 @@ namespace mongo {
result.append( "out" , BSONElementHasher::hash64( cmdObj.firstElement() , seed ) );
return true;
}
- } cmdHashElt;
+ };
+ MONGO_INITIALIZER(RegisterHashEltCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new CmdHashElt();
+ }
+ return Status::OK();
+ }
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index ff57ace9a88..8f962b27325 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -25,6 +25,8 @@
#include <time.h>
+#include "mongo/base/init.h"
+#include "mongo/base/status.h"
#include "mongo/bson/util/builder.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
@@ -1597,7 +1599,7 @@ namespace mongo {
}
} cmdWhatsMyUri;
- /* For testing only, not for general use */
+ /* For testing only, not for general use. Enabled via command-line */
class GodInsert : public Command {
public:
GodInsert() : Command( "godinsert" ) { }
@@ -1605,14 +1607,14 @@ namespace mongo {
virtual bool logTheOp() { return false; }
virtual bool slaveOk() const { return true; }
virtual LockType locktype() const { return NONE; }
- virtual bool requiresAuth() { return true; }
- virtual void help( stringstream &help ) const {
- help << "internal. for testing only.";
- }
- // No auth required, only enabled via command line for testing
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {}
+ virtual void help( stringstream &help ) const {
+ help << "internal. for testing only.";
+ }
virtual bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
AuthenticationInfo *ai = cc().getAuthenticationInfo();
@@ -1633,7 +1635,15 @@ namespace mongo {
}
return true;
}
- } cmdGodInsert;
+ };
+
+ MONGO_INITIALIZER(RegisterGodInsertCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new GodInsert();
+ }
+ return Status::OK();
+ }
class DBHashCmd : public Command {
public:
@@ -1733,7 +1743,7 @@ namespace mongo {
} dbhashCmd;
- /* for diagnostic / testing purposes. */
+ /* for diagnostic / testing purposes. Enabled via command line. */
class CmdSleep : public Command {
public:
virtual LockType locktype() const { return NONE; }
@@ -1744,7 +1754,8 @@ namespace mongo {
help << "internal testing command. Makes db block (in a read lock) for 100 seconds\n";
help << "w:true write lock. secs:<seconds>";
}
- // No auth required, only enabled via command line for testing
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {}
@@ -1764,23 +1775,26 @@ namespace mongo {
}
return true;
}
- } cmdSleep;
+ };
+ MONGO_INITIALIZER(RegisterSleepCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new CmdSleep();
+ }
+ return Status::OK();
+ }
- // just for testing
+ // Testing only, enabled via command-line.
class CapTrunc : public Command {
public:
CapTrunc() : Command( "captrunc" ) {}
virtual bool slaveOk() const { return false; }
virtual LockType locktype() const { return WRITE; }
- virtual bool requiresAuth() { return true; }
- // Only enabled via command line for testing
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::captrunc);
- out->push_back(Privilege(parseNs(dbname, cmdObj), actions));
- }
+ std::vector<Privilege>* out) {}
virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
string coll = cmdObj[ "captrunc" ].valuestrsafe();
uassert( 13416, "captrunc must specify a collection", !coll.empty() );
@@ -1799,24 +1813,27 @@ namespace mongo {
nsd->cappedTruncateAfter( ns.c_str(), end, inc );
return true;
}
- } capTruncCmd;
+ };
+ MONGO_INITIALIZER(RegisterCapTruncCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new CapTrunc();
+ }
+ return Status::OK();
+ }
- // just for testing
+ // Testing-only, enabled via command line.
class EmptyCapped : public Command {
public:
EmptyCapped() : Command( "emptycapped" ) {}
virtual bool slaveOk() const { return false; }
virtual LockType locktype() const { return WRITE; }
- virtual bool requiresAuth() { return true; }
virtual bool logTheOp() { return true; }
- // Only enabled via command line for testing
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::emptycapped);
- out->push_back(Privilege(parseNs(dbname, cmdObj), actions));
- }
+ std::vector<Privilege>* out) {}
virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
string coll = cmdObj[ "emptycapped" ].valuestrsafe();
uassert( 13428, "emptycapped must specify a collection", !coll.empty() );
@@ -1826,7 +1843,14 @@ namespace mongo {
nsd->emptyCappedCollection( ns.c_str() );
return true;
}
- } emptyCappedCmd;
+ };
+ MONGO_INITIALIZER(RegisterEmptyCappedCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new EmptyCapped();
+ }
+ return Status::OK();
+ }
bool _execCommand(Command *c, const string& dbname, BSONObj& cmdObj, int queryOptions, BSONObjBuilder& result, bool fromRepl) {
diff --git a/src/mongo/db/dbcommands_admin.cpp b/src/mongo/db/dbcommands_admin.cpp
index c2ebc19ab80..f0201cd58e2 100644
--- a/src/mongo/db/dbcommands_admin.cpp
+++ b/src/mongo/db/dbcommands_admin.cpp
@@ -30,6 +30,8 @@
#include <string>
#include <vector>
+#include "mongo/base/init.h"
+#include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -90,7 +92,8 @@ namespace mongo {
namespace dur {
boost::filesystem::path getJournalDir();
}
-
+
+ // Testing-only, enabled via command line
class JournalLatencyTestCmd : public Command {
public:
JournalLatencyTestCmd() : Command( "journalLatencyTest" ) {}
@@ -99,7 +102,11 @@ namespace mongo {
virtual LockType locktype() const { return NONE; }
virtual bool adminOnly() const { return true; }
virtual void help(stringstream& h) const { h << "test how long to write and fsync to a test file in the journal/ directory"; }
-
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
+ virtual void addRequiredPrivileges(const std::string& dbname,
+ const BSONObj& cmdObj,
+ std::vector<Privilege>* out) {}
bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) {
boost::filesystem::path p = dur::getJournalDir();
p /= "journalLatencyTest";
@@ -159,7 +166,14 @@ namespace mongo {
return 1;
}
- } journalLatencyTestCmd;
+ };
+ MONGO_INITIALIZER(RegisterJournalLatencyTestCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new JournalLatencyTestCmd();
+ }
+ return Status::OK();
+ }
class ValidateCmd : public Command {
public:
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index b21bba2de3b..af88f1b260e 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -16,6 +16,8 @@
#include "pch.h"
+#include "mongo/base/init.h"
+#include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -43,11 +45,17 @@ namespace mongo {
bool replSetBlind = false;
unsigned replSetForceInitialSyncFailure = 0;
+ // Testing only, enabled via command-line.
class CmdReplSetTest : public ReplSetCommand {
public:
virtual void help( stringstream &help ) const {
help << "Just for regression tests.\n";
}
+ // No auth needed because it only works when enabled via command line.
+ virtual bool requiresAuth() { return false; }
+ virtual void addRequiredPrivileges(const std::string& dbname,
+ const BSONObj& cmdObj,
+ std::vector<Privilege>* out) {}
CmdReplSetTest() : ReplSetCommand("replSetTest") { }
virtual bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
log() << "replSet replSetTest command received: " << cmdObj.toString() << rsLog;
@@ -76,7 +84,14 @@ namespace mongo {
return false;
}
- } cmdReplSetTest;
+ };
+ MONGO_INITIALIZER(RegisterReplSetTestCmd)(InitializerContext* context) {
+ if (Command::testCommandsEnabled) {
+ // Leaked intentionally: a Command registers itself when constructed.
+ new CmdReplSetTest();
+ }
+ return Status::OK();
+ }
/** get rollback id. used to check if a rollback happened during some interval of time.
as consumed, the rollback id is not in any particular order, it simply changes on each rollback.