summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/count_plan_summary.js5
-rw-r--r--jstests/core/currentop.js5
-rw-r--r--jstests/core/distinct3.js8
-rw-r--r--jstests/core/drop2.js31
-rw-r--r--jstests/core/evald.js10
-rw-r--r--jstests/core/geo_update_btree.js2
-rw-r--r--jstests/core/killop.js42
-rw-r--r--jstests/core/mr_killop.js7
-rw-r--r--jstests/core/shellstartparallel.js9
-rw-r--r--jstests/disk/killall.js16
-rw-r--r--jstests/dur/closeall.js9
-rw-r--r--jstests/multiVersion/kill_op_pseudocommand.js7
-rw-r--r--jstests/noPassthrough/repair2.js15
-rw-r--r--jstests/noPassthroughWithMongod/index_killop.js11
-rw-r--r--jstests/noPassthroughWithMongod/index_no_retry.js4
-rw-r--r--jstests/noPassthroughWithMongod/index_retry.js4
-rw-r--r--jstests/replsets/stepdown3.js5
-rw-r--r--jstests/replsets/stepdown_kill_other_ops.js5
-rw-r--r--jstests/replsets/stepdown_long_wait_time.js8
-rw-r--r--jstests/replsets/stepdown_wrt_electable.js3
-rw-r--r--jstests/sharding/features3.js20
-rw-r--r--src/mongo/shell/servers_misc.js24
22 files changed, 147 insertions, 103 deletions
diff --git a/jstests/core/count_plan_summary.js b/jstests/core/count_plan_summary.js
index be9c764fc47..a822c7666b5 100644
--- a/jstests/core/count_plan_summary.js
+++ b/jstests/core/count_plan_summary.js
@@ -10,7 +10,7 @@ for (var i = 0; i < 1000; i++) {
// Mock a long-running count operation by sleeping for each of
// the documents in the collection.
-s = startParallelShell(
+var awaitShell = startParallelShell(
"db.jstests_count_plan_summary.find({x: 1, $where: 'sleep(100)'}).count()"
);
@@ -44,4 +44,5 @@ assert.soon(function() {
return true;
});
-s(); \ No newline at end of file
+var exitCode = awaitShell({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected shell to exit abnormally due to JS execution being terminated");
diff --git a/jstests/core/currentop.js b/jstests/core/currentop.js
index 587d3c9cf81..c84556226cd 100644
--- a/jstests/core/currentop.js
+++ b/jstests/core/currentop.js
@@ -72,8 +72,9 @@ for(var i in o) {
start = new Date();
-s1();
-s2();
+// The operations running in the parallel shells may or may not have been killed.
+s1({checkExitSuccess: false});
+s2({checkExitSuccess: false});
// don't want to pass if timeout killed the js function
assert( ( new Date() ) - start < 30000 );
diff --git a/jstests/core/distinct3.js b/jstests/core/distinct3.js
index 0add7aeb95e..c82dc7e9043 100644
--- a/jstests/core/distinct3.js
+++ b/jstests/core/distinct3.js
@@ -18,13 +18,13 @@ for( i = 0; i < 100; ++i ) {
assert.writeOK(bulk.execute());
// Attempt to remove the last match for the {a:1} index scan while distinct is yielding.
-p = startParallelShell( 'var bulk = db.jstests_distinct3.initializeUnorderedBulkOp();' +
- 'for( i = 0; i < 100; ++i ) { ' +
- ' bulk.remove( { a:49 } ); ' +
+p = startParallelShell( 'for( i = 0; i < 100; ++i ) { ' +
+ ' var bulk = db.jstests_distinct3.initializeUnorderedBulkOp();' +
+ ' bulk.find( { a:49 } ).remove(); ' +
' for( j = 0; j < 20; ++j ) { ' +
' bulk.insert( { a:49, c:49, d:j } ); ' +
' } ' +
- ' bulk.execute(); ' +
+ ' assert.writeOK(bulk.execute()); ' +
'} ' );
for( i = 0; i < 100; ++i ) {
diff --git a/jstests/core/drop2.js b/jstests/core/drop2.js
index 5eef20adc61..f0dee81b592 100644
--- a/jstests/core/drop2.js
+++ b/jstests/core/drop2.js
@@ -25,28 +25,31 @@ function getOpId( drop ) {
return null;
}
-var shell1 = startParallelShell( "print(\"Count thread started\");"
- + "db.getMongo().getCollection(\""
- + (coll + "") + "\")"
- + ".count( { $where: function() {"
- + "while( 1 ) { sleep( 1 ); } } } );"
- + "print(\"Count thread terminating\");" );
+var awaitCount = startParallelShell( "print(\"Count thread started\");"
+ + "db.getMongo().getCollection(\""
+ + (coll + "") + "\")"
+ + ".count( { $where: function() {"
+ + "while( 1 ) { sleep( 1 ); } } } );"
+ + "print(\"Count thread terminating\");" );
countOpId = null;
assert.soon( function() { countOpId = getOpId( false ); return countOpId; } );
-var shell2 = startParallelShell( "print(\"Drop thread started\");"
- + "print(\"drop result: \" + "
- + "db.getMongo().getCollection(\""
- + (coll + "") + "\")"
- + ".drop() );"
- + "print(\"Drop thread terminating\")" );
+var awaitDrop = startParallelShell( "print(\"Drop thread started\");"
+ + "print(\"drop result: \" + "
+ + "db.getMongo().getCollection(\""
+ + (coll + "") + "\")"
+ + ".drop() );"
+ + "print(\"Drop thread terminating\")" );
dropOpId = null;
assert.soon( function() { dropOpId = getOpId( true ); return dropOpId; } );
db.killOp( dropOpId );
db.killOp( countOpId );
-shell1();
-shell2();
+var exitCode = awaitCount({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected shell to exit abnormally due to JS execution being terminated");
+
+// The drop operation may or may not have been killed.
+awaitDrop({checkExitSuccess: false});
coll.drop(); // in SERVER-1818, this fails
diff --git a/jstests/core/evald.js b/jstests/core/evald.js
index 7bb0eb825b1..031c0f802ef 100644
--- a/jstests/core/evald.js
+++ b/jstests/core/evald.js
@@ -28,11 +28,12 @@ function op( ev, where ) {
}
function doIt( ev, wait, where ) {
+ var awaitShell;
if ( where ) {
- s = startParallelShell( ev );
+ awaitShell = startParallelShell( ev );
} else {
- s = startParallelShell( "db.eval( '" + ev + "' )" );
+ awaitShell = startParallelShell( "db.eval( '" + ev + "' )" );
}
o = null;
@@ -48,8 +49,9 @@ function doIt( ev, wait, where ) {
debug( "sent kill" );
- s();
-
+ var exitCode = awaitShell({checkExitSuccess: false});
+ assert.neq(0, exitCode,
+ "expected shell to exit abnormally due to JS execution being terminated");
}
// nested scope with nested invoke()
diff --git a/jstests/core/geo_update_btree.js b/jstests/core/geo_update_btree.js
index 225a6635903..474be72e3e1 100644
--- a/jstests/core/geo_update_btree.js
+++ b/jstests/core/geo_update_btree.js
@@ -13,7 +13,7 @@ if (testingReplication) {
var parallelInsert = startParallelShell(
"for ( var i = 0; i < 1000; i++ ) {" +
- " var doc = { loc: [ Random.rand() * 180, Random.rand() * 180 ], v: '' }" +
+ " var doc = { loc: [ Random.rand() * 180, Random.rand() * 180 ], v: '' };" +
" db.jstests_geo_update_btree.insert(doc);" +
"}");
diff --git a/jstests/core/killop.js b/jstests/core/killop.js
index 915add2c318..220c636848f 100644
--- a/jstests/core/killop.js
+++ b/jstests/core/killop.js
@@ -36,28 +36,28 @@ function ops() {
return ids;
}
-var s1 = null;
-var s2 = null;
-try {
- jsTestLog("Starting long-running $where operation");
- s1 = startParallelShell( "db.jstests_killop.count( { $where: function() { while( 1 ) { ; } } } )" );
- s2 = startParallelShell( "db.jstests_killop.count( { $where: function() { while( 1 ) { ; } } } )" );
+jsTestLog("Starting long-running $where operation");
+var s1 = startParallelShell(
+ "db.jstests_killop.count( { $where: function() { while( 1 ) { ; } } } )" );
+var s2 = startParallelShell(
+ "db.jstests_killop.count( { $where: function() { while( 1 ) { ; } } } )" );
- jsTestLog("Finding ops in currentOp() output");
- o = [];
- assert.soon(function() { o = ops(); return o.length == 2; },
- { toString: function () { return tojson(db.currentOp().inprog); } },
- 10000);
- start = new Date();
- jsTestLog("Killing ops");
- db.killOp( o[ 0 ] );
- db.killOp( o[ 1 ] );
-}
-finally {
- jsTestLog("Waiting for ops to terminate");
- if (s1) s1();
- if (s2) s2();
-}
+jsTestLog("Finding ops in currentOp() output");
+o = [];
+assert.soon(function() { o = ops(); return o.length == 2; },
+ { toString: function () { return tojson(db.currentOp().inprog); } },
+ 10000);
+start = new Date();
+jsTestLog("Killing ops");
+db.killOp( o[ 0 ] );
+db.killOp( o[ 1 ] );
+
+jsTestLog("Waiting for ops to terminate");
+[s1, s2].forEach(function(awaitShell) {
+ var exitCode = awaitShell({checkExitSuccess: false});
+ assert.neq(0, exitCode,
+ "expected shell to exit abnormally due to JS execution being terminated");
+});
// don't want to pass if timeout killed the js function.
var end = new Date();
diff --git a/jstests/core/mr_killop.js b/jstests/core/mr_killop.js
index 8e9735007c9..db1f2b945ec 100644
--- a/jstests/core/mr_killop.js
+++ b/jstests/core/mr_killop.js
@@ -76,7 +76,8 @@ function testOne( map, reduce, finalize, scope, childLoop, wait ) {
// The assert below won't be caught by this test script, but it will cause error messages
// to be printed.
- s = startParallelShell( "assert.commandWorked( db.runCommand( " + stringifiedSpec + " ) );" );
+ var awaitShell = startParallelShell( "assert.commandWorked( db.runCommand( " +
+ stringifiedSpec + " ) );" );
if ( wait ) {
sleep( 2000 );
@@ -89,7 +90,9 @@ function testOne( map, reduce, finalize, scope, childLoop, wait ) {
debug( "did kill : " + tojson( res ) );
// When the map reduce op is killed, the spawned shell will exit
- s();
+ var exitCode = awaitShell({checkExitSuccess: false});
+ assert.neq(0, exitCode,
+ "expected shell to exit abnormally due to map-reduce execution being terminated");
debug( "parallel shell completed" );
assert.eq( -1, op( childLoop ) );
diff --git a/jstests/core/shellstartparallel.js b/jstests/core/shellstartparallel.js
index 9a8efe038b4..7e288e0d589 100644
--- a/jstests/core/shellstartparallel.js
+++ b/jstests/core/shellstartparallel.js
@@ -5,13 +5,14 @@ assert.throws(f);
// verify that join works
db.sps.drop();
-join = startParallelShell("sleep(1000); db.sps.insert({x:1});");
-join();
+var awaitShell = startParallelShell("sleep(1000); db.sps.insert({x:1});");
+awaitShell();
assert.eq(1, db.sps.count(), "join problem?");
// test with a throw
-join = startParallelShell("db.sps.insert({x:1}); throw Error('intentionally_uncaught');");
-join();
+awaitShell = startParallelShell("db.sps.insert({x:1}); throw Error('intentionally_uncaught');");
+var exitCode = awaitShell({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected shell to exit abnormally due to an uncaught exception");
assert.eq(2, db.sps.count(), "join2 problem?");
print("shellstartparallel.js SUCCESS");
diff --git a/jstests/disk/killall.js b/jstests/disk/killall.js
index c10fec18dc2..ba294a53504 100644
--- a/jstests/disk/killall.js
+++ b/jstests/disk/killall.js
@@ -11,12 +11,12 @@ var port = allocatePorts( 1 )[ 0 ]
var baseName = "jstests_disk_killall";
var dbpath = MongoRunner.dataPath + baseName;
-var mongod = MongoRunner.runMongod({});
+var mongod = MongoRunner.runMongod({port: port, dbpath: dbpath});
var db = mongod.getDB( "test" );
var collection = db.getCollection( baseName );
assert.writeOK(collection.insert({}));
-var s1 = startParallelShell(
+var awaitShell = startParallelShell(
"db." + baseName + ".count( { $where: function() { while( 1 ) { ; } } } )",
port);
sleep( 1000 );
@@ -32,9 +32,15 @@ var exitCode = MongoRunner.stopMongod(mongod);
assert.eq(0, exitCode, "got unexpected exitCode");
// Waits for shell to complete
-s1();
-
-mongod = MongoRunner.runMongod({restart:true, cleanData: false, dbpath: mongod.dbpath});
+exitCode = awaitShell({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected shell to exit abnormally due to mongod being terminated");
+
+mongod = MongoRunner.runMongod({
+ port: port,
+ restart: true,
+ cleanData: false,
+ dbpath: mongod.dbpath
+});
db = mongod.getDB( "test" );
collection = db.getCollection( baseName );
diff --git a/jstests/dur/closeall.js b/jstests/dur/closeall.js
index 44ff1cb7c2b..937c9c34a4b 100644
--- a/jstests/dur/closeall.js
+++ b/jstests/dur/closeall.js
@@ -39,16 +39,17 @@ function f(variant, quickCommits, paranoid) {
print("initial sync done")
var writeOps = startParallelShell('var coll = db.getSiblingDB("' + ourdb + '").foo; \
- var bulk = coll.initializeUnorderedBulkOp(); \
for( var i = 0; i < ' + N + '; i++ ) { \
+ var bulk = coll.initializeUnorderedBulkOp(); \
bulk.insert({ x: 1 }); \
if ( i % 7 == 0 ) \
bulk.insert({ x: 99, y: 2 }); \
if ( i % 49 == 0 ) \
bulk.find({ x: 99 }).update( \
- { a: 1, b: 2, c: 3, d: 4 }); \
+ { $set: { a: 1, b: 2, c: 3, d: 4 }}); \
if( i == 800 ) \
coll.ensureIndex({ x: 1 }); \
+ assert.writeOK(bulk.execute()); \
}', conn.port);
for( var i = 0; i < N; i++ ) {
@@ -80,14 +81,14 @@ function f(variant, quickCommits, paranoid) {
assert( res.ok, "dropDatabase res.ok=false");
}
+ writeOps();
+
print("closeall.js end test loop. slave.foo.count:");
print(slave.foo.count());
print("closeall.js shutting down servers");
MongoRunner.stopMongod(connSlave);
MongoRunner.stopMongod(conn);
-
- writeOps();
}
// Skip this test on 32-bit Windows (unfixable failures in MapViewOfFileEx)
diff --git a/jstests/multiVersion/kill_op_pseudocommand.js b/jstests/multiVersion/kill_op_pseudocommand.js
index b5acd4ad774..07954684204 100644
--- a/jstests/multiVersion/kill_op_pseudocommand.js
+++ b/jstests/multiVersion/kill_op_pseudocommand.js
@@ -56,9 +56,10 @@
} while (opToKill === null);
db.killOp(opToKill);
- try {
- parShell(); // wait for query to end
- } catch (ex) {} // ignore
+
+ var exitCode = parShell({checkExitSuccess: false}); // wait for query to end
+ assert.neq(0, exitCode,
+ "expected shell to exit abnormally due to JS execution being terminated");
var end = new Date();
diff --git a/jstests/noPassthrough/repair2.js b/jstests/noPassthrough/repair2.js
index e80a3edf02b..32e89742903 100644
--- a/jstests/noPassthrough/repair2.js
+++ b/jstests/noPassthrough/repair2.js
@@ -8,15 +8,11 @@ testServer = new SlowWeeklyMongod( baseName )
t = testServer.getDB( baseName )[ baseName ];
t.drop();
-function protect( f ) {
- try {
- f();
- } catch( e ) {
- printjson( e );
- }
-}
-
-s = startParallelShell( "db = db.getSisterDB( '" + baseName + "'); for( i = 0; i < 10; ++i ) { db.repairDatabase(); sleep( 5000 ); }" );
+var awaitShell = startParallelShell( "db = db.getSiblingDB( '" + baseName + "');" +
+ "for( i = 0; i < 10; ++i ) { " +
+ "db.repairDatabase();" +
+ "sleep( 5000 );" +
+ " }", testServer.port );
for( i = 0; i < 30; ++i ) {
var bulk = t.initializeUnorderedBulkOp();
@@ -32,5 +28,6 @@ for( i = 0; i < 30; ++i ) {
assert.eq( 0, t.count() );
}
+awaitShell();
testServer.stop();
diff --git a/jstests/noPassthroughWithMongod/index_killop.js b/jstests/noPassthroughWithMongod/index_killop.js
index 417df2535d6..a755f042264 100644
--- a/jstests/noPassthroughWithMongod/index_killop.js
+++ b/jstests/noPassthroughWithMongod/index_killop.js
@@ -34,8 +34,10 @@ function getIndexBuildOpId() {
/** Test that building an index with @param 'options' can be aborted using killop. */
function testAbortIndexBuild( options ) {
- var createIdx = startParallelShell('var coll = db.jstests_slownightly_index_killop; \
- coll.createIndex({ a: 1 }, ' + tojson(options) + ');');
+ var createIdx = startParallelShell(
+ 'var coll = db.jstests_slownightly_index_killop;' +
+ 'assert.commandWorked(coll.createIndex({ a: 1 }, ' + tojson(options) + '));'
+ );
// When the index build starts, find its op id.
assert.soon( function() { return ( opId = getIndexBuildOpId() ) != -1; } );
@@ -44,7 +46,10 @@ function testAbortIndexBuild( options ) {
// Wait for the index build to stop.
assert.soon( function() { return getIndexBuildOpId() == -1; } );
- createIdx();
+
+ var exitCode = createIdx({checkExitSuccess: false});
+ assert.neq(0, exitCode,
+ 'expected shell to exit abnormally due to index build being terminated');
// Check that no new index has been created. This verifies that the index build was aborted
// rather than successfully completed.
diff --git a/jstests/noPassthroughWithMongod/index_no_retry.js b/jstests/noPassthroughWithMongod/index_no_retry.js
index 5b7aac4350f..c9514f13a51 100644
--- a/jstests/noPassthroughWithMongod/index_no_retry.js
+++ b/jstests/noPassthroughWithMongod/index_no_retry.js
@@ -76,7 +76,9 @@
print("killing the mongod");
MongoRunner.stopMongod(ports[0], /* signal */ 9);
- createIdx();
+
+ var exitCode = createIdx({checkExitSuccess: false});
+ assert.neq(0, exitCode, "expected shell to exit abnormally due to mongod being terminated");
}
abortDuringIndexBuild();
diff --git a/jstests/noPassthroughWithMongod/index_retry.js b/jstests/noPassthroughWithMongod/index_retry.js
index 1fbb645c418..a093260066e 100644
--- a/jstests/noPassthroughWithMongod/index_retry.js
+++ b/jstests/noPassthroughWithMongod/index_retry.js
@@ -76,7 +76,9 @@
print("killing the mongod");
MongoRunner.stopMongod(ports[0], /* signal */ 9);
- createIdx();
+
+ var exitCode = createIdx({checkExitSuccess: false});
+ assert.neq(0, exitCode, "expected shell to exit abnormally due to mongod being terminated");
}
abortDuringIndexBuild();
diff --git a/jstests/replsets/stepdown3.js b/jstests/replsets/stepdown3.js
index 05ce573c883..2995ef62d99 100644
--- a/jstests/replsets/stepdown3.js
+++ b/jstests/replsets/stepdown3.js
@@ -28,7 +28,7 @@ master.getDB("test").foo.insert({x:3});
// step down the primary asyncronously
print("stepdown");
var command = "sleep(4000); tojson(db.adminCommand( { replSetStepDown : 60, force : 1 } ));"
-var waitfunc = startParallelShell(command, master.port);
+var awaitShell = startParallelShell(command, master.port);
print("getlasterror; should assert or return an error, depending on timing");
var gleFunction = function() {
@@ -45,6 +45,9 @@ var result = assert.throws(gleFunction);
print("result of gle:");
printjson(result);
+var exitCode = awaitShell({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected replSetStepDown to close the shell's connection");
+
// unlock and shut down
printjson(locked.getDB("admin").fsyncUnlock());
replTest.stopSet();
diff --git a/jstests/replsets/stepdown_kill_other_ops.js b/jstests/replsets/stepdown_kill_other_ops.js
index 3c91bc93d48..b37eda0f63e 100644
--- a/jstests/replsets/stepdown_kill_other_ops.js
+++ b/jstests/replsets/stepdown_kill_other_ops.js
@@ -62,6 +62,7 @@
var newPrimary = replSet.getPrimary();
assert.neq(primary, newPrimary, "SECONDARY did not become PRIMARY");
- var code = evalRunner();
- assert.neq(0, code); // Eval should have exited with an error due to being interrupted
+ var exitCode = evalRunner({checkExitSuccess: false});
+ assert.neq(0, exitCode,
+ "expected shell to exit abnormally due to JS execution being terminated");
})();
diff --git a/jstests/replsets/stepdown_long_wait_time.js b/jstests/replsets/stepdown_long_wait_time.js
index 3ec955eab24..e4d6419a419 100644
--- a/jstests/replsets/stepdown_long_wait_time.js
+++ b/jstests/replsets/stepdown_long_wait_time.js
@@ -78,7 +78,11 @@
jsTestLog("signal update thread to exit");
var newPrimary = replSet.getPrimary();
assert.writeOK(newPrimary.getDB(name).foo.remove({}));
- stepDowner();
- writer();
+ var exitCode = stepDowner({checkExitSuccess: false});
+ assert.neq(0, exitCode, "expected replSetStepDown to close the shell's connection");
+
+ // The connection for the 'writer' may be closed due to the primary stepping down, or signaled
+ // by the main thread to quit.
+ writer({checkExitSuccess: false});
})();
diff --git a/jstests/replsets/stepdown_wrt_electable.js b/jstests/replsets/stepdown_wrt_electable.js
index 85f32071b91..cb0d2446fe3 100644
--- a/jstests/replsets/stepdown_wrt_electable.js
+++ b/jstests/replsets/stepdown_wrt_electable.js
@@ -23,7 +23,8 @@ assert(master.getDB("a").isMaster().ismaster, "not master")
// step down the primary asyncronously so it doesn't kill this test
var wait = startParallelShell("db.adminCommand({replSetStepDown:1000, force:true})", master.port);
-wait();
+var exitCode = wait({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected replSetStepDown to close the shell's connection");
// check that the old primary is no longer master
assert.soon( function() {
diff --git a/jstests/sharding/features3.js b/jstests/sharding/features3.js
index afa7eeb1367..16cb955b696 100644
--- a/jstests/sharding/features3.js
+++ b/jstests/sharding/features3.js
@@ -59,20 +59,14 @@ var start = new Date();
// solution is to increase sleep time
var whereKillSleepTime = 10000;
var parallelCommand =
- "try { " +
- " db.foo.find(function(){ " +
- " sleep( " + whereKillSleepTime + " ); " +
- " return false; " +
- " }).itcount(); " +
- "} " +
- "catch(e) { " +
- " print('PShell execution ended:'); " +
- " printjson(e) " +
- "}";
+ "db.foo.find(function() { " +
+ " sleep( " + whereKillSleepTime + " ); " +
+ " return false; " +
+ "}).itcount(); ";
// fork a parallel shell, but do not wait for it to start
print("about to fork new shell at: " + Date());
-join = startParallelShell(parallelCommand);
+var awaitShell = startParallelShell(parallelCommand);
print("done forking shell at: " + Date());
// Get all current $where operations
@@ -133,7 +127,9 @@ print("time if run full: " + (numDocs * whereKillSleepTime));
assert.gt(whereKillSleepTime * numDocs / 20, killTime, "took too long to kill");
// wait for the parallel shell we spawned to complete
-join();
+var exitCode = awaitShell({checkExitSuccess: false});
+assert.neq(0, exitCode, "expected shell to exit abnormally due to JS execution being terminated");
+
var end = new Date();
print("elapsed: " + (end.getTime() - start.getTime()));
diff --git a/src/mongo/shell/servers_misc.js b/src/mongo/shell/servers_misc.js
index 46df568dc28..778d1d2ab75 100644
--- a/src/mongo/shell/servers_misc.js
+++ b/src/mongo/shell/servers_misc.js
@@ -217,8 +217,6 @@ SyncCCTest.prototype.tempStart = function( num ){
function startParallelShell( jsCode, port, noConnect ){
- var x;
-
var args = ["mongo"];
if (typeof db == "object") {
@@ -256,9 +254,25 @@ function startParallelShell( jsCode, port, noConnect ){
args.push("--eval", jsCode);
- x = startMongoProgramNoConnect.apply(null, args);
- return function(){
- return waitProgram( x );
+ var pid = startMongoProgramNoConnect.apply(null, args);
+
+ // Returns a function that when called waits for the parallel shell to exit and returns the exit
+ // code of the process. By default an error is thrown if the parallel shell exits with a nonzero
+ // exit code.
+ return function(options) {
+ if (arguments.length > 0) {
+ if (typeof options !== "object") {
+ throw new Error("options must be an object");
+ }
+ if (options === null) {
+ throw new Error("options cannot be null");
+ }
+ }
+ var exitCode = waitProgram(pid);
+ if (arguments.length === 0 || options.checkExitSuccess) {
+ assert.eq(0, exitCode, "encountered an error in the parallel shell");
+ }
+ return exitCode;
};
}