summaryrefslogtreecommitdiff
path: root/test/legacy28/jstests/libs/servers.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/legacy28/jstests/libs/servers.js')
-rwxr-xr-xtest/legacy28/jstests/libs/servers.js957
1 files changed, 957 insertions, 0 deletions
diff --git a/test/legacy28/jstests/libs/servers.js b/test/legacy28/jstests/libs/servers.js
new file mode 100755
index 00000000000..30734822845
--- /dev/null
+++ b/test/legacy28/jstests/libs/servers.js
@@ -0,0 +1,957 @@
+// Wrap whole file in a function to avoid polluting the global namespace
+(function() {
+
+_parsePath = function() {
+ var dbpath = "";
+ for( var i = 0; i < arguments.length; ++i )
+ if ( arguments[ i ] == "--dbpath" )
+ dbpath = arguments[ i + 1 ];
+
+ if ( dbpath == "" )
+ throw Error("No dbpath specified");
+
+ return dbpath;
+}
+
+_parsePort = function() {
+ var port = "";
+ for( var i = 0; i < arguments.length; ++i )
+ if ( arguments[ i ] == "--port" )
+ port = arguments[ i + 1 ];
+
+ if ( port == "" )
+ throw Error("No port specified");
+ return port;
+}
+
+connectionURLTheSame = function( a , b ){
+
+ if ( a == b )
+ return true;
+
+ if ( ! a || ! b )
+ return false;
+
+ if( a.host ) return connectionURLTheSame( a.host, b )
+ if( b.host ) return connectionURLTheSame( a, b.host )
+
+ if( a.name ) return connectionURLTheSame( a.name, b )
+ if( b.name ) return connectionURLTheSame( a, b.name )
+
+ if( a.indexOf( "/" ) < 0 && b.indexOf( "/" ) < 0 ){
+ a = a.split( ":" )
+ b = b.split( ":" )
+
+ if( a.length != b.length ) return false
+
+ if( a.length == 2 && a[1] != b[1] ) return false
+
+ if( a[0] == "localhost" || a[0] == "127.0.0.1" ) a[0] = getHostName()
+ if( b[0] == "localhost" || b[0] == "127.0.0.1" ) b[0] = getHostName()
+
+ return a[0] == b[0]
+ }
+ else {
+ var a0 = a.split( "/" )[0]
+ var b0 = b.split( "/" )[0]
+ return a0 == b0
+ }
+}
+
+assert( connectionURLTheSame( "foo" , "foo" ) )
+assert( ! connectionURLTheSame( "foo" , "bar" ) )
+
+assert( connectionURLTheSame( "foo/a,b" , "foo/b,a" ) )
+assert( ! connectionURLTheSame( "foo/a,b" , "bar/a,b" ) )
+
+createMongoArgs = function( binaryName , args ){
+ var fullArgs = [ binaryName ];
+
+ if ( args.length == 1 && isObject( args[0] ) ){
+ var o = args[0];
+ for ( var k in o ){
+ if ( o.hasOwnProperty(k) ){
+ if ( k == "v" && isNumber( o[k] ) ){
+ var n = o[k];
+ if ( n > 0 ){
+ if ( n > 10 ) n = 10;
+ var temp = "-";
+ while ( n-- > 0 ) temp += "v";
+ fullArgs.push( temp );
+ }
+ }
+ else {
+ fullArgs.push( "--" + k );
+ if ( o[k] != "" )
+ fullArgs.push( "" + o[k] );
+ }
+ }
+ }
+ }
+ else {
+ for ( var i=0; i<args.length; i++ )
+ fullArgs.push( args[i] )
+ }
+
+ return fullArgs;
+}
+
+
+MongoRunner = function(){}
+
+MongoRunner.dataDir = "/data/db"
+MongoRunner.dataPath = "/data/db/"
+MongoRunner.usedPortMap = {}
+
+MongoRunner.VersionSub = function(regex, version) {
+ this.regex = regex;
+ this.version = version;
+}
+
+// These patterns allow substituting the binary versions used for each
+// version string to support the dev/stable MongoDB release cycle.
+MongoRunner.binVersionSubs = [ new MongoRunner.VersionSub(/^latest$/, ""),
+ new MongoRunner.VersionSub(/^oldest-supported$/, "1.8"),
+ // To-be-updated when 2.8 becomes available
+ new MongoRunner.VersionSub(/^last-stable$/, "2.6"),
+ // Latest unstable and next stable are effectively the
+ // same release
+ new MongoRunner.VersionSub(/^2\.7(\..*){0,1}/, ""),
+ new MongoRunner.VersionSub(/^2\.8(\..*){0,1}/, "") ];
+
+MongoRunner.getBinVersionFor = function(version) {
+
+ // If this is a version iterator, iterate the version via toString()
+ if (version instanceof MongoRunner.versionIterator.iterator) {
+ version = version.toString();
+ }
+
+ // No version set means we use no suffix, this is *different* from "latest"
+ // since latest may be mapped to a different version.
+ if (version == null) version = "";
+ version = version.trim();
+ if (version === "") return "";
+
+ // See if this version is affected by version substitutions
+ for (var i = 0; i < MongoRunner.binVersionSubs.length; i++) {
+ var sub = MongoRunner.binVersionSubs[i];
+ if (sub.regex.test(version)) {
+ version = sub.version;
+ }
+ }
+
+ return version;
+}
+
+MongoRunner.areBinVersionsTheSame = function(versionA, versionB) {
+
+ versionA = MongoRunner.getBinVersionFor(versionA);
+ versionB = MongoRunner.getBinVersionFor(versionB);
+
+ if (versionA === "" || versionB === "") {
+ return versionA === versionB;
+ }
+
+ return versionA.startsWith(versionB) ||
+ versionB.startsWith(versionA);
+}
+
+MongoRunner.logicalOptions = { runId : true,
+ pathOpts : true,
+ remember : true,
+ noRemember : true,
+ appendOptions : true,
+ restart : true,
+ noCleanData : true,
+ cleanData : true,
+ startClean : true,
+ forceLock : true,
+ useLogFiles : true,
+ logFile : true,
+ useHostName : true,
+ useHostname : true,
+ noReplSet : true,
+ forgetPort : true,
+ arbiter : true,
+ noJournalPrealloc : true,
+ noJournal : true,
+ binVersion : true,
+ waitForConnect : true }
+
+MongoRunner.toRealPath = function( path, pathOpts ){
+
+ // Replace all $pathOptions with actual values
+ pathOpts = pathOpts || {}
+ path = path.replace( /\$dataPath/g, MongoRunner.dataPath )
+ path = path.replace( /\$dataDir/g, MongoRunner.dataDir )
+ for( key in pathOpts ){
+ path = path.replace( RegExp( "\\$" + RegExp.escape(key), "g" ), pathOpts[ key ] )
+ }
+
+ // Relative path
+ // Detect Unix and Windows absolute paths
+ // as well as Windows drive letters
+ // Also captures Windows UNC paths
+
+ if( ! path.match( /^(\/|\\|[A-Za-z]:)/ ) ){
+ if( path != "" && ! path.endsWith( "/" ) )
+ path += "/"
+
+ path = MongoRunner.dataPath + path
+ }
+
+ return path
+
+}
+
+MongoRunner.toRealDir = function( path, pathOpts ){
+
+ path = MongoRunner.toRealPath( path, pathOpts )
+
+ if( path.endsWith( "/" ) )
+ path = path.substring( 0, path.length - 1 )
+
+ return path
+}
+
+MongoRunner.toRealFile = MongoRunner.toRealDir
+
+MongoRunner.nextOpenPort = function(){
+
+ var i = 0;
+ while( MongoRunner.usedPortMap[ "" + ( 27000 + i ) ] ) i++;
+ MongoRunner.usedPortMap[ "" + ( 27000 + i ) ] = true
+
+ return 27000 + i
+
+}
+
+/**
+ * Returns an iterator object which yields successive versions on toString(), starting from a
+ * random initial position, from an array of versions.
+ *
+ * If passed a single version string or an already-existing version iterator, just returns the
+ * object itself, since it will yield correctly on toString()
+ *
+ * @param {Array.<String>}|{String}|{versionIterator}
+ */
+MongoRunner.versionIterator = function( arr, isRandom ){
+
+ // If this isn't an array of versions, or is already an iterator, just use it
+ if( typeof arr == "string" ) return arr
+ if( arr.isVersionIterator ) return arr
+
+ if (isRandom == undefined) isRandom = false;
+
+ // Starting pos
+ var i = isRandom ? parseInt( Random.rand() * arr.length ) : 0;
+
+ return new MongoRunner.versionIterator.iterator(i, arr);
+}
+
+MongoRunner.versionIterator.iterator = function(i, arr) {
+
+ this.toString = function() {
+ i = ( i + 1 ) % arr.length
+ print( "Returning next version : " + i +
+ " (" + arr[i] + ") from " + tojson( arr ) + "..." );
+ return arr[ i ]
+ }
+
+ this.isVersionIterator = true;
+
+}
+
+/**
+ * Converts the args object by pairing all keys with their value and appending
+ * dash-dash (--) to the keys. The only exception to this rule are keys that
+ * are defined in MongoRunner.logicalOptions, of which they will be ignored.
+ *
+ * @param {string} binaryName
+ * @param {Object} args
+ *
+ * @return {Array.<String>} an array of parameter strings that can be passed
+ * to the binary.
+ */
+MongoRunner.arrOptions = function( binaryName , args ){
+
+ var fullArgs = [ "" ]
+
+ // isObject returns true even if "args" is an array, so the else branch of this statement is
+ // dead code. See SERVER-14220.
+ if ( isObject( args ) || ( args.length == 1 && isObject( args[0] ) ) ){
+
+ var o = isObject( args ) ? args : args[0]
+
+ // If we've specified a particular binary version, use that
+ if (o.binVersion && o.binVersion != "") {
+ binaryName += "-" + o.binVersion;
+ }
+
+ // Manage legacy options
+ var isValidOptionForBinary = function( option, value ){
+
+ if( ! o.binVersion ) return true
+
+ // Version 1.x options
+ if( o.binVersion.startsWith( "1." ) ){
+
+ return [ "nopreallocj" ].indexOf( option ) < 0
+ }
+
+ return true
+ }
+
+ for ( var k in o ){
+
+ // Make sure our logical option should be added to the array of options
+ if( ! o.hasOwnProperty( k ) ||
+ k in MongoRunner.logicalOptions ||
+ ! isValidOptionForBinary( k, o[k] ) ) continue
+
+ if ( ( k == "v" || k == "verbose" ) && isNumber( o[k] ) ){
+ var n = o[k]
+ if ( n > 0 ){
+ if ( n > 10 ) n = 10
+ var temp = "-"
+ while ( n-- > 0 ) temp += "v"
+ fullArgs.push( temp )
+ }
+ }
+ else {
+ if( o[k] == undefined || o[k] == null ) continue
+ fullArgs.push( "--" + k )
+ if ( o[k] != "" )
+ fullArgs.push( "" + o[k] )
+ }
+ }
+ }
+ else {
+ for ( var i=0; i<args.length; i++ )
+ fullArgs.push( args[i] )
+ }
+
+ fullArgs[ 0 ] = binaryName
+ return fullArgs
+}
+
+MongoRunner.arrToOpts = function( arr ){
+
+ var opts = {}
+ for( var i = 1; i < arr.length; i++ ){
+ if( arr[i].startsWith( "-" ) ){
+ var opt = arr[i].replace( /^-/, "" ).replace( /^-/, "" )
+
+ if( arr.length > i + 1 && ! arr[ i + 1 ].startsWith( "-" ) ){
+ opts[ opt ] = arr[ i + 1 ]
+ i++
+ }
+ else{
+ opts[ opt ] = ""
+ }
+
+ if( opt.replace( /v/g, "" ) == "" ){
+ opts[ "verbose" ] = opt.length
+ }
+ }
+ }
+
+ return opts
+}
+
+MongoRunner.savedOptions = {}
+
+MongoRunner.mongoOptions = function( opts ){
+
+ // Don't remember waitForConnect
+ var waitForConnect = opts.waitForConnect;
+ delete opts.waitForConnect;
+
+ // If we're a mongo object
+ if( opts.getDB ){
+ opts = { restart : opts.runId }
+ }
+
+ // Initialize and create a copy of the opts
+ opts = Object.merge( opts || {}, {} )
+
+ if( ! opts.restart ) opts.restart = false
+
+ // RunId can come from a number of places
+ // If restart is passed as an old connection
+ if( opts.restart && opts.restart.getDB ){
+ opts.runId = opts.restart.runId
+ opts.restart = true
+ }
+ // If it's the runId itself
+ else if( isObject( opts.restart ) ){
+ opts.runId = opts.restart
+ opts.restart = true
+ }
+
+ if( isObject( opts.remember ) ){
+ opts.runId = opts.remember
+ opts.remember = true
+ }
+ else if( opts.remember == undefined ){
+ // Remember by default if we're restarting
+ opts.remember = opts.restart
+ }
+
+ // If we passed in restart : <conn> or runId : <conn>
+ if( isObject( opts.runId ) && opts.runId.runId ) opts.runId = opts.runId.runId
+
+ if( opts.restart && opts.remember ) opts = Object.merge( MongoRunner.savedOptions[ opts.runId ], opts )
+
+ // Create a new runId
+ opts.runId = opts.runId || ObjectId()
+
+ // Save the port if required
+ if( ! opts.forgetPort ) opts.port = opts.port || MongoRunner.nextOpenPort()
+
+ var shouldRemember = ( ! opts.restart && ! opts.noRemember ) || ( opts.restart && opts.appendOptions )
+
+ // Normalize and get the binary version to use
+ opts.binVersion = MongoRunner.getBinVersionFor(opts.binVersion);
+
+ if ( shouldRemember ){
+ MongoRunner.savedOptions[ opts.runId ] = Object.merge( opts, {} )
+ }
+
+ // Default for waitForConnect is true
+ opts.waitForConnect = (waitForConnect == undefined || waitForConnect == null) ?
+ true : waitForConnect;
+
+ if( jsTestOptions().useSSL ) {
+ if (!opts.sslMode) opts.sslMode = "requireSSL";
+ if (!opts.sslPEMKeyFile) opts.sslPEMKeyFile = "jstests/libs/server.pem";
+ if (!opts.sslCAFile) opts.sslCAFile = "jstests/libs/ca.pem";
+
+ // Needed for jstest/ssl/upgrade_to_ssl.js
+ opts.sslWeakCertificateValidation = "";
+
+ // Needed for jstest/ssl/ssl_hostname_validation.js
+ opts.sslAllowInvalidHostnames = "";
+ }
+
+ if ( jsTestOptions().useX509 && !opts.clusterAuthMode ) {
+ opts.clusterAuthMode = "x509";
+ }
+
+ opts.port = opts.port || MongoRunner.nextOpenPort()
+ MongoRunner.usedPortMap[ "" + parseInt( opts.port ) ] = true
+
+ opts.pathOpts = Object.merge( opts.pathOpts || {}, { port : "" + opts.port, runId : "" + opts.runId } )
+
+ return opts
+}
+
+/**
+ * @option {object} opts
+ *
+ * {
+ * dbpath {string}
+ * useLogFiles {boolean}: use with logFile option.
+ * logFile {string}: path to the log file. If not specified and useLogFiles
+ * is true, automatically creates a log file inside dbpath.
+ * noJournalPrealloc {boolean}
+ * noJournal {boolean}
+ * keyFile
+ * replSet
+ * oplogSize
+ * }
+ */
+MongoRunner.mongodOptions = function( opts ){
+
+ opts = MongoRunner.mongoOptions( opts )
+
+ opts.dbpath = MongoRunner.toRealDir( opts.dbpath || "$dataDir/mongod-$port",
+ opts.pathOpts )
+
+ opts.pathOpts = Object.merge( opts.pathOpts, { dbpath : opts.dbpath } )
+
+ if( ! opts.logFile && opts.useLogFiles ){
+ opts.logFile = opts.dbpath + "/mongod.log"
+ }
+ else if( opts.logFile ){
+ opts.logFile = MongoRunner.toRealFile( opts.logFile, opts.pathOpts )
+ }
+
+ if ( opts.logFile !== undefined ) {
+ opts.logpath = opts.logFile;
+ }
+
+ if( jsTestOptions().noJournalPrealloc || opts.noJournalPrealloc )
+ opts.nopreallocj = ""
+
+ if( jsTestOptions().noJournal || opts.noJournal )
+ opts.nojournal = ""
+
+ if( jsTestOptions().keyFile && !opts.keyFile) {
+ opts.keyFile = jsTestOptions().keyFile
+ }
+
+ if( jsTestOptions().useSSL ) {
+ if (!opts.sslMode) opts.sslMode = "requireSSL";
+ if (!opts.sslPEMKeyFile) opts.sslPEMKeyFile = "jstests/libs/server.pem";
+ if (!opts.sslCAFile) opts.sslCAFile = "jstests/libs/ca.pem";
+
+ // Needed for jstest/ssl/upgrade_to_ssl.js
+ opts.sslWeakCertificateValidation = "";
+
+ // Needed for jstest/ssl/ssl_hostname_validation.js
+ opts.sslAllowInvalidHostnames = "";
+ }
+
+ if ( jsTestOptions().useX509 && !opts.clusterAuthMode ) {
+ opts.clusterAuthMode = "x509";
+ }
+
+ if( opts.noReplSet ) opts.replSet = null
+ if( opts.arbiter ) opts.oplogSize = 1
+
+ return opts
+}
+
+MongoRunner.mongosOptions = function( opts ){
+
+ opts = MongoRunner.mongoOptions( opts )
+
+ // Normalize configdb option to be host string if currently a host
+ if( opts.configdb && opts.configdb.getDB ){
+ opts.configdb = opts.configdb.host
+ }
+
+ opts.pathOpts = Object.merge( opts.pathOpts,
+ { configdb : opts.configdb.replace( /:|,/g, "-" ) } )
+
+ if( ! opts.logFile && opts.useLogFiles ){
+ opts.logFile = MongoRunner.toRealFile( "$dataDir/mongos-$configdb-$port.log",
+ opts.pathOpts )
+ }
+ else if( opts.logFile ){
+ opts.logFile = MongoRunner.toRealFile( opts.logFile, opts.pathOpts )
+ }
+
+ if ( opts.logFile !== undefined ){
+ opts.logpath = opts.logFile;
+ }
+
+ if( jsTestOptions().keyFile && !opts.keyFile) {
+ opts.keyFile = jsTestOptions().keyFile
+ }
+
+ return opts
+}
+
+/**
+ * Starts a mongod instance.
+ *
+ * @param {Object} opts
+ *
+ * {
+ * useHostName {boolean}: Uses hostname of machine if true
+ * forceLock {boolean}: Deletes the lock file if set to true
+ * dbpath {string}: location of db files
+ * cleanData {boolean}: Removes all files in dbpath if true
+ * startClean {boolean}: same as cleanData
+ * noCleanData {boolean}: Do not clean files (cleanData takes priority)
+ *
+ * @see MongoRunner.mongodOptions for other options
+ * }
+ *
+ * @return {Mongo} connection object to the started mongod instance.
+ *
+ * @see MongoRunner.arrOptions
+ */
+MongoRunner.runMongod = function( opts ){
+
+ opts = opts || {}
+ var useHostName = false;
+ var runId = null;
+ var waitForConnect = true;
+ var fullOptions = opts;
+
+ if( isObject( opts ) ) {
+
+ opts = MongoRunner.mongodOptions( opts );
+ fullOptions = opts;
+
+ useHostName = opts.useHostName || opts.useHostname;
+ runId = opts.runId;
+ waitForConnect = opts.waitForConnect;
+
+ if( opts.forceLock ) removeFile( opts.dbpath + "/mongod.lock" )
+ if( ( opts.cleanData || opts.startClean ) || ( ! opts.restart && ! opts.noCleanData ) ){
+ print( "Resetting db path '" + opts.dbpath + "'" )
+ resetDbpath( opts.dbpath )
+ }
+
+ opts = MongoRunner.arrOptions( "mongod", opts )
+ }
+
+ var mongod = MongoRunner.startWithArgs(opts, waitForConnect);
+ if (!waitForConnect) mongos = {};
+ if (!mongod) return null;
+
+ mongod.commandLine = MongoRunner.arrToOpts( opts )
+ mongod.name = (useHostName ? getHostName() : "localhost") + ":" + mongod.commandLine.port
+ mongod.host = mongod.name
+ mongod.port = parseInt( mongod.commandLine.port )
+ mongod.runId = runId || ObjectId()
+ mongod.savedOptions = MongoRunner.savedOptions[ mongod.runId ];
+ mongod.fullOptions = fullOptions;
+
+ return mongod
+}
+
+MongoRunner.runMongos = function( opts ){
+
+ opts = opts || {}
+ var useHostName = false;
+ var runId = null;
+ var waitForConnect = true;
+ var fullOptions = opts;
+
+ if( isObject( opts ) ) {
+
+ opts = MongoRunner.mongosOptions( opts );
+ fullOptions = opts;
+
+ useHostName = opts.useHostName || opts.useHostname;
+ runId = opts.runId;
+ waitForConnect = opts.waitForConnect;
+
+ opts = MongoRunner.arrOptions( "mongos", opts )
+ }
+
+ var mongos = MongoRunner.startWithArgs(opts, waitForConnect);
+ if (!waitForConnect) mongos = {};
+ if (!mongos) return null;
+
+ mongos.commandLine = MongoRunner.arrToOpts( opts )
+ mongos.name = (useHostName ? getHostName() : "localhost") + ":" + mongos.commandLine.port
+ mongos.host = mongos.name
+ mongos.port = parseInt( mongos.commandLine.port )
+ mongos.runId = runId || ObjectId()
+ mongos.savedOptions = MongoRunner.savedOptions[ mongos.runId ]
+ mongos.fullOptions = fullOptions;
+
+ return mongos
+}
+
+/**
+ * Kills a mongod process.
+ *
+ * @param {number} port the port of the process to kill
+ * @param {number} signal The signal number to use for killing
+ * @param {Object} opts Additional options. Format:
+ * {
+ * auth: {
+ * user {string}: admin user name
+ * pwd {string}: admin password
+ * }
+ * }
+ *
+ * Note: The auth option is required in a authenticated mongod running in Windows since
+ * it uses the shutdown command, which requires admin credentials.
+ */
+MongoRunner.stopMongod = function( port, signal, opts ){
+
+ if( ! port ) {
+ print( "Cannot stop mongo process " + port )
+ return
+ }
+
+ signal = signal || 15
+
+ if( port.port )
+ port = parseInt( port.port )
+
+ if( port instanceof ObjectId ){
+ var opts = MongoRunner.savedOptions( port )
+ if( opts ) port = parseInt( opts.port )
+ }
+
+ var exitCode = stopMongod( parseInt( port ), parseInt( signal ), opts )
+
+ delete MongoRunner.usedPortMap[ "" + parseInt( port ) ]
+
+ return exitCode
+}
+
+MongoRunner.stopMongos = MongoRunner.stopMongod
+
+MongoRunner.isStopped = function( port ){
+
+ if( ! port ) {
+ print( "Cannot detect if process " + port + " is stopped." )
+ return
+ }
+
+ if( port.port )
+ port = parseInt( port.port )
+
+ if( port instanceof ObjectId ){
+ var opts = MongoRunner.savedOptions( port )
+ if( opts ) port = parseInt( opts.port )
+ }
+
+ return MongoRunner.usedPortMap[ "" + parseInt( port ) ] ? false : true
+}
+
+/**
+ * Starts an instance of the specified mongo tool
+ *
+ * @param {String} binaryName The name of the tool to run
+ * @param {Object} opts options to pass to the tool
+ * {
+ * binVersion {string}: version of tool to run
+ * }
+ *
+ * @see MongoRunner.arrOptions
+ */
+MongoRunner.runMongoTool = function( binaryName, opts ){
+
+ var opts = opts || {}
+ // Normalize and get the binary version to use
+ opts.binVersion = MongoRunner.getBinVersionFor(opts.binVersion);
+
+ var argsArray = MongoRunner.arrOptions(binaryName, opts)
+
+ return runMongoProgram.apply(null, argsArray);
+
+}
+
+// Given a test name figures out a directory for that test to use for dump files and makes sure
+// that directory exists and is empty.
+MongoRunner.getAndPrepareDumpDirectory = function(testName) {
+ var dir = MongoRunner.dataPath + testName + "_external/";
+ resetDbpath(dir);
+ return dir;
+}
+
+// Start a mongod instance and return a 'Mongo' object connected to it.
+// This function's arguments are passed as command line arguments to mongod.
+// The specified 'dbpath' is cleared if it exists, created if not.
+// var conn = startMongodEmpty("--port", 30000, "--dbpath", "asdf");
+startMongodEmpty = function () {
+ var args = createMongoArgs("mongod", arguments);
+
+ var dbpath = _parsePath.apply(null, args);
+ resetDbpath(dbpath);
+
+ return startMongoProgram.apply(null, args);
+}
+startMongod = function () {
+ print("startMongod WARNING DELETES DATA DIRECTORY THIS IS FOR TESTING ONLY");
+ return startMongodEmpty.apply(null, arguments);
+}
+startMongodNoReset = function(){
+ var args = createMongoArgs( "mongod" , arguments );
+ return startMongoProgram.apply( null, args );
+}
+
+startMongos = function(args){
+ return MongoRunner.runMongos(args);
+}
+
+/**
+ * Returns a new argArray with any test-specific arguments added.
+ */
+function appendSetParameterArgs(argArray) {
+ var programName = argArray[0];
+ if (programName.endsWith('mongod') || programName.endsWith('mongos')) {
+ if (jsTest.options().enableTestCommands) {
+ argArray.push.apply(argArray, ['--setParameter', "enableTestCommands=1"]);
+ }
+ if (jsTest.options().authMechanism && jsTest.options().authMechanism != "SCRAM-SHA-1") {
+ var hasAuthMechs = false;
+ for (i in argArray) {
+ if (typeof argArray[i] === 'string' &&
+ argArray[i].indexOf('authenticationMechanisms') != -1) {
+ hasAuthMechs = true;
+ break;
+ }
+ }
+ if (!hasAuthMechs) {
+ argArray.push.apply(argArray,
+ ['--setParameter',
+ "authenticationMechanisms=" + jsTest.options().authMechanism]);
+ }
+ }
+ if (jsTest.options().auth) {
+ argArray.push.apply(argArray, ['--setParameter', "enableLocalhostAuthBypass=false"]);
+ }
+
+ if ( jsTestOptions().useSSL ) {
+ if ( argArray.indexOf('--sslMode') < 0 ) {
+ argArray.push.apply(argArray, [ '--sslMode', 'requireSSL', '--sslPEMKeyFile', 'jstests/libs/server.pem', '--sslCAFile', 'jstests/libs/ca.pem', '--sslWeakCertificateValidation' ] );
+ }
+ }
+
+ // mongos only options
+ if (programName.endsWith('mongos')) {
+ // apply setParameters for mongos
+ if (jsTest.options().setParametersMongos) {
+ var params = jsTest.options().setParametersMongos.split(",");
+ if (params && params.length > 0) {
+ params.forEach(function(p) {
+ if (p) argArray.push.apply(argArray, ['--setParameter', p])
+ });
+ }
+ }
+ }
+ // mongod only options
+ else if (programName.endsWith('mongod')) {
+ // set storageEngine for mongod
+ if (jsTest.options().storageEngine) {
+ argArray.push.apply(argArray, ['--storageEngine', jsTest.options().storageEngine]);
+ }
+ // apply setParameters for mongod
+ if (jsTest.options().setParameters) {
+ var params = jsTest.options().setParameters.split(",");
+ if (params && params.length > 0) {
+ params.forEach(function(p) {
+ if (p) argArray.push.apply(argArray, ['--setParameter', p])
+ });
+ }
+ }
+ }
+ }
+ return argArray;
+};
+
+/**
+ * Start a mongo process with a particular argument array. If we aren't waiting for connect,
+ * return null.
+ */
+MongoRunner.startWithArgs = function(argArray, waitForConnect) {
+ // TODO: Make there only be one codepath for starting mongo processes
+
+ argArray = appendSetParameterArgs(argArray);
+ var port = _parsePort.apply(null, argArray);
+ var pid = _startMongoProgram.apply(null, argArray);
+
+ var conn = null;
+ if (waitForConnect) {
+ assert.soon( function() {
+ try {
+ conn = new Mongo("127.0.0.1:" + port);
+ return true;
+ } catch( e ) {
+ if (!checkProgram(pid)) {
+
+ print("Could not start mongo program at " + port + ", process ended")
+
+ // Break out
+ return true;
+ }
+ }
+ return false;
+ }, "unable to connect to mongo program on port " + port, 600 * 1000);
+ }
+
+ return conn;
+}
+
+/**
+ * DEPRECATED
+ *
+ * Start mongod or mongos and return a Mongo() object connected to there.
+ * This function's first argument is "mongod" or "mongos" program name, \
+ * and subsequent arguments to this function are passed as
+ * command line arguments to the program.
+ */
+startMongoProgram = function(){
+ var port = _parsePort.apply( null, arguments );
+
+ // Enable test commands.
+ // TODO: Make this work better with multi-version testing so that we can support
+ // enabling this on 2.4 when testing 2.6
+ var args = argumentsToArray( arguments );
+ args = appendSetParameterArgs(args);
+ var pid = _startMongoProgram.apply( null, args );
+
+ var m;
+ assert.soon
+ ( function() {
+ try {
+ m = new Mongo( "127.0.0.1:" + port );
+ return true;
+ } catch( e ) {
+ if (!checkProgram(pid)) {
+
+ print("Could not start mongo program at " + port + ", process ended")
+
+ // Break out
+ m = null;
+ return true;
+ }
+ }
+ return false;
+ }, "unable to connect to mongo program on port " + port, 600 * 1000 );
+
+ return m;
+}
+
+runMongoProgram = function() {
+ var args = argumentsToArray( arguments );
+ var progName = args[0];
+
+ if ( jsTestOptions().auth ) {
+ args = args.slice(1);
+ args.unshift( progName,
+ '-u', jsTestOptions().authUser,
+ '-p', jsTestOptions().authPassword,
+ '--authenticationMechanism', DB.prototype._defaultAuthenticationMechanism,
+ '--authenticationDatabase=admin'
+ );
+ }
+
+ if ( jsTestOptions().useSSL ) {
+ args.push("--ssl", "--sslPEMKeyFile", "jstests/libs/server.pem", "--sslCAFile", "jstests/libs/ca.pem", "--sslAllowInvalidHosts");
+ }
+
+ if (progName == 'mongo' && !_useWriteCommandsDefault()) {
+ progName = args[0];
+ args = args.slice(1);
+ args.unshift(progName, '--useLegacyWriteOps');
+ }
+
+ return _runMongoProgram.apply( null, args );
+}
+
+// Start a mongo program instance. This function's first argument is the
+// program name, and subsequent arguments to this function are passed as
+// command line arguments to the program. Returns pid of the spawned program.
+startMongoProgramNoConnect = function() {
+ var args = argumentsToArray( arguments );
+ var progName = args[0];
+
+ if ( jsTestOptions().auth ) {
+ args = args.slice(1);
+ args.unshift(progName,
+ '-u', jsTestOptions().authUser,
+ '-p', jsTestOptions().authPassword,
+ '--authenticationMechanism', DB.prototype._defaultAuthenticationMechanism,
+ '--authenticationDatabase=admin');
+ }
+
+ if (progName == 'mongo' && !_useWriteCommandsDefault()) {
+ args = args.slice(1);
+ args.unshift(progName, '--useLegacyWriteOps');
+ }
+
+ return _startMongoProgram.apply( null, args );
+}
+
+myPort = function() {
+ var m = db.getMongo();
+ if ( m.host.match( /:/ ) )
+ return m.host.match( /:(.*)/ )[ 1 ];
+ else
+ return 27017;
+}
+
+}());