0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-27576 Fix quit() in shell and all the tests that depend on it

This commit is contained in:
Jonathan Reams 2017-01-10 15:37:04 -05:00
parent e3cf6a7d9f
commit f3d5da9195
7 changed files with 292 additions and 266 deletions

View File

@ -34,7 +34,7 @@ var badStrings = [
{s: "/", r: badHost},
{s: "/test", r: badHost},
{s: ":/", r: emptyHost},
{s: ":/test", r: noReplSet},
{s: ":/test", r: emptyHost},
{s: "mongodb://:" + port + "/", r: emptyHost},
{s: "mongodb://:" + port + "/test", r: emptyHost},
{s: "mongodb://localhost:/test", r: noPort},

View File

@ -0,0 +1,17 @@
(function() {
'use strict';
var checkShell = function(retCode) {
var args = [
"mongo",
"--nodb",
"--eval",
"quit(" + retCode + ");",
];
var actualRetCode = _runMongoProgram.apply(null, args);
assert.eq(retCode, actualRetCode);
};
checkShell(0);
checkShell(5);
})();

View File

@ -1,115 +1,115 @@
// Test --host.
(function() {
// This "inner_mode" method of spawning a mongod and re-running was copied from
// ipv6_connection_string_validation.js
if ("undefined" == typeof inner_mode) {
// Start a mongod with --ipv6
jsTest.log("Outer mode test starting mongod with --ipv6");
// NOTE: bind_ip arg is present to test if it can parse ipv6 addresses (::1 in this case).
// Unfortunately, having bind_ip = ::1 won't work in the test framework (But does work when
// tested manually), so 127.0.0.1 is also present so the test mongo shell can connect
// with that address.
var mongod = MongoRunner.runMongod({ipv6: "", bind_ip: "::1,127.0.0.1"});
var args = [
"mongo",
"--nodb",
"--ipv6",
"--host",
"::1",
"--port",
mongod.port,
"--eval",
"inner_mode=true;port=" + mongod.port + ";",
"jstests/noPassthroughWithMongod/host_connection_string_validation.js"
];
var exitCode = _runMongoProgram.apply(null, args);
jsTest.log("Inner mode test finished, exit code was " + exitCode);
// This "inner_mode" method of spawning a mongod and re-running was copied from
// ipv6_connection_string_validation.js
if ("undefined" == typeof inner_mode) {
// Start a mongod with --ipv6
jsTest.log("Outer mode test starting mongod with --ipv6");
// NOTE: bind_ip arg is present to test if it can parse ipv6 addresses (::1 in this case).
// Unfortunately, having bind_ip = ::1 won't work in the test framework (But does work when
// tested manually), so 127.0.0.1 is also present so the test mongo shell can connect
// with that address.
var mongod = MongoRunner.runMongod({ipv6: "", bind_ip: "::1,127.0.0.1"});
var args = [
"mongo",
"--nodb",
"--ipv6",
"--host",
"::1",
"--port",
mongod.port,
"--eval",
"inner_mode=true;port=" + mongod.port + ";",
"jstests/noPassthroughWithMongod/host_connection_string_validation.js"
// Pass the inner test's exit code back as the outer test's exit code
if (exitCode != 0) {
doassert("inner test failed with exit code " + exitcode);
}
return;
}
var testHost = function(host, shouldSucceed) {
var exitCode = runMongoProgram('mongo', '--ipv6', '--eval', ';', '--host', host);
if (shouldSucceed) {
if (exitCode !== 0) {
doassert("failed to connect with `--host " + host +
"`, but expected success. Exit code: " + exitCode);
}
} else {
if (exitCode === 0) {
doassert("successfully connected with `--host " + host +
"`, but expected to fail.");
}
}
};
var goodStrings = [
"[::1]:27999",
"localhost:27999",
"127.0.0.1:27999",
"[0:0:0:0:0:0:0:1]:27999",
"[0000:0000:0000:0000:0000:0000:0000:0001]:27999",
];
var exitCode = _runMongoProgram.apply(null, args);
jsTest.log("Inner mode test finished, exit code was " + exitCode);
// Stop the server we started
jsTest.log("Outer mode test stopping server");
MongoRunner.stopMongod(mongod.port, 15);
var goodSocketStrings = [
"/tmp/mongodb-27999.sock",
];
// Pass the inner test's exit code back as the outer test's exit code
quit(exitCode);
}
var badStrings = [
"::1:27999",
"::1:65536",
"::1]:27999",
":",
":27999",
"[::1:]27999",
"[::1:27999",
"[::1]:",
"[::1]:123456",
"[::1]:1cat",
"[::1]:65536",
"[::1]:cat",
"0:0::0:0:1:27999",
"0000:0000:0000:0000:0000:0000:0000:0001:27999",
"127.0.0.1:",
"127.0.0.1:123456",
"127.0.0.1:1cat",
"127.0.0.1:65536",
"127.0.0.1:cat",
"a[::1:]27999",
"a[127.0.0.1]:27999",
"localhost:",
];
var testHost = function(host, shouldSucceed) {
var exitCode = runMongoProgram('mongo', '--ipv6', '--eval', ';', '--host', host);
if (shouldSucceed) {
if (exitCode !== 0) {
doassert("failed to connect with `--host " + host +
"`, but expected success. Exit code: " + exitCode);
}
} else {
if (exitCode === 0) {
doassert("successfully connected with `--host " + host + "`, but expected to fail.");
function runUriTestFor(i, connectionString, isGood) {
connectionString = connectionString.replace("27999", "" + port);
print("Testing " + (isGood ? "good" : "bad") + " connection string " + i + "...");
print(" * testing " + connectionString);
testHost(connectionString, isGood);
print(" * testing mongodb://" + connectionString);
testHost("mongodb://" + connectionString, isGood);
}
var i;
jsTest.log("TESTING " + goodStrings.length + " good uri strings");
for (i = 0; i < goodStrings.length; ++i) {
runUriTestFor(i, goodStrings[i], true);
}
if (!_isWindows()) {
jsTest.log("TESTING " + goodSocketStrings.length + " good uri socket strings");
for (i = 0; i < goodSocketStrings.length; ++i) {
runUriTestFor(i, goodSocketStrings[i], true);
}
}
};
var goodStrings = [
"[::1]:27999",
"localhost:27999",
"127.0.0.1:27999",
"[0:0:0:0:0:0:0:1]:27999",
"[0000:0000:0000:0000:0000:0000:0000:0001]:27999",
];
var goodSocketStrings = [
"/tmp/mongodb-27999.sock",
];
var badStrings = [
"::1:27999",
"::1:65536",
"::1]:27999",
":",
":27999",
"",
"[::1:]27999",
"[::1:27999",
"[::1]:",
"[::1]:123456",
"[::1]:1cat",
"[::1]:65536",
"[::1]:cat",
"0:0::0:0:1:27999",
"0000:0000:0000:0000:0000:0000:0000:0001:27999",
"127.0.0.1:",
"127.0.0.1:123456",
"127.0.0.1:1cat",
"127.0.0.1:65536",
"127.0.0.1:cat",
"a[::1:]27999",
"a[127.0.0.1]:27999",
"localhost:",
];
function runUriTestFor(i, connectionString, isGood) {
connectionString = connectionString.replace("27999", "" + port);
print("Testing " + (isGood ? "good" : "bad") + " connection string " + i + "...");
print(" * testing " + connectionString);
testHost(connectionString, isGood);
print(" * testing mongodb://" + connectionString);
testHost("mongodb://" + connectionString, isGood);
}
var i;
jsTest.log("TESTING " + goodStrings.length + " good uri strings");
for (i = 0; i < goodStrings.length; ++i) {
runUriTestFor(i, goodStrings[i], true);
}
if (!_isWindows()) {
jsTest.log("TESTING " + goodSocketStrings.length + " good uri socket strings");
for (i = 0; i < goodSocketStrings.length; ++i) {
runUriTestFor(i, goodSocketStrings[i], true);
jsTest.log("TESTING " + badStrings.length + " bad uri strings");
for (i = 0; i < badStrings.length; ++i) {
runUriTestFor(i, badStrings[i], false);
}
}
jsTest.log("TESTING " + badStrings.length + " bad uri strings");
for (i = 0; i < badStrings.length; ++i) {
runUriTestFor(i, badStrings[i], false);
}
jsTest.log("SUCCESSFUL test completion");
jsTest.log("SUCCESSFUL test completion");
})();

View File

@ -4,162 +4,162 @@
// This file runs in two modes: outer and inner. This is to enable testing with --ipv6.
// The outer mode test starts a mongod with --ipv6 and then starts a mongo shell with --ipv6
// and a command line to run the test in inner_mode. The inner mode test is the actual test.
(function() {
if ("undefined" == typeof inner_mode) {
// Start a mongod with --ipv6
jsTest.log("Outer mode test starting mongod with --ipv6");
// NOTE: bind_ip arg is present to test if it can parse ipv6 addresses (::1 in this case).
// Unfortunately, having bind_ip = ::1 won't work in the test framework (But does work when
// tested manually), so 127.0.0.1 is also present so the test mongo shell can connect
// with that address.
var mongod = MongoRunner.runMongod({ipv6: "", bind_ip: "::1,127.0.0.1"});
var args = [
"mongo",
"--nodb",
"--ipv6",
"--host",
"::1",
"--port",
mongod.port,
"--eval",
"inner_mode=true;port=" + mongod.port + ";",
"jstests/noPassthroughWithMongod/ipv6_connection_string_validation.js"
];
var exitCode = _runMongoProgram.apply(null, args);
jsTest.log("Inner mode test finished, exit code was " + exitCode);
if ("undefined" == typeof inner_mode) {
// Start a mongod with --ipv6
jsTest.log("Outer mode test starting mongod with --ipv6");
// NOTE: bind_ip arg is present to test if it can parse ipv6 addresses (::1 in this case).
// Unfortunately, having bind_ip = ::1 won't work in the test framework (But does work when
// tested manually), so 127.0.0.1 is also present so the test mongo shell can connect
// with that address.
var mongod = MongoRunner.runMongod({ipv6: "", bind_ip: "::1,127.0.0.1"});
var args = [
"mongo",
"--nodb",
"--ipv6",
"--host",
"::1",
"--port",
mongod.port,
"--eval",
"inner_mode=true;port=" + mongod.port + ";",
"jstests/noPassthroughWithMongod/ipv6_connection_string_validation.js"
];
var exitCode = _runMongoProgram.apply(null, args);
jsTest.log("Inner mode test finished, exit code was " + exitCode);
// Stop the server we started
jsTest.log("Outer mode test stopping server");
MongoRunner.stopMongod(mongod.port, 15);
// Pass the inner test's exit code back as the outer test's exit code
quit(exitCode);
}
var goodStrings = [
"localhost:27999/test",
"[::1]:27999/test",
"[0:0:0:0:0:0:0:1]:27999/test",
"[0000:0000:0000:0000:0000:0000:0000:0001]:27999/test",
"localhost:27999",
"[::1]:27999",
"[0:0:0:0:0:0:0:1]:27999",
"[0000:0000:0000:0000:0000:0000:0000:0001]:27999",
];
var missingConnString = /^Missing connection string$/;
var incorrectType = /^Incorrect type/;
var emptyConnString = /^Empty connection string$/;
var badHost = /^Failed to parse mongodb/;
var emptyHost = /^Empty host component/;
var noPort = /^No digits/;
var badPort = /^Bad digit/;
var invalidPort = /^Port number \d+ out of range/;
var moreThanOneColon = /^More than one ':' detected/;
var charBeforeSquareBracket = /^'\[' present, but not first character/;
var noCloseBracket = /^ipv6 address is missing closing '\]'/;
var noOpenBracket = /^'\]' present without '\['/;
var noColonPrePort = /^missing colon after '\]' before the port/;
var badStrings = [
{s: undefined, r: missingConnString},
{s: 7, r: incorrectType},
{s: null, r: incorrectType},
{s: "", r: emptyConnString},
{s: " ", r: emptyConnString},
{s: ":", r: emptyHost},
{s: "/", r: badHost},
{s: ":/", r: emptyHost},
{s: ":/test", r: emptyHost},
{s: ":27999/", r: emptyHost},
{s: ":27999/test", r: emptyHost},
{s: "/test", r: badHost},
{s: "localhost:/test", r: noPort},
{s: "[::1]:/test", r: noPort},
{s: "[::1]:cat/test", r: badPort},
{s: "[::1]:1cat/test", r: badPort},
{s: "[::1]:123456/test", r: invalidPort},
{s: "[::1]:65536/test", r: invalidPort},
{s: "127.0.0.1:65536/test", r: invalidPort},
{s: "::1:27999/test", r: moreThanOneColon},
{s: "0:0::0:0:1:27999/test", r: moreThanOneColon},
{s: "0000:0000:0000:0000:0000:0000:0000:0001:27999/test", r: moreThanOneColon},
{s: "a[127.0.0.1]:27999/", r: charBeforeSquareBracket},
{s: "a[::1:]27999/", r: charBeforeSquareBracket},
{s: "[::1:27999/", r: noCloseBracket},
{s: "[::1:]27999/", r: noColonPrePort},
{s: "::1]:27999/", r: noOpenBracket},
];
var substitutePort = function(connectionString) {
// This will be called with non-strings as well as strings, so we need to catch exceptions
try {
return connectionString.replace("27999", "" + port);
} catch (e) {
return connectionString;
}
};
var testGood = function(i, connectionString) {
print("\n---\nTesting good connection string " + i + " (\"" + connectionString + "\") ...");
var gotException = false;
var exception;
try {
var connectDB = connect(connectionString);
connectDB = null;
} catch (e) {
gotException = true;
exception = e;
}
if (!gotException) {
print("Good connection string " + i + " (\"" + connectionString +
"\") correctly validated");
return;
}
var message = "FAILED to correctly validate goodString " + i + " (\"" + connectionString +
"\"): exception was \"" + tojson(exception) + "\"";
doassert(message);
};
var testBad = function(i, connectionString, errorRegex) {
print("\n---\nTesting bad connection string " + i + " (\"" + connectionString + "\") ...");
var gotException = false;
var gotCorrectErrorText = false;
var exception;
try {
var connectDB = connect(connectionString);
connectDB = null;
} catch (e) {
gotException = true;
exception = e;
if (errorRegex.test(e.message)) {
gotCorrectErrorText = true;
// Pass the inner test's exit code back as the outer test's exit code
if (exitCode != 0) {
doassert("inner test failed with exit code " + exitcode);
}
}
if (gotCorrectErrorText) {
print("Bad connection string " + i + " (\"" + connectionString +
"\") correctly rejected:\n" + tojson(exception));
return;
}
var message = "FAILED to generate correct exception for badString " + i + " (\"" +
connectionString + "\"): ";
if (gotException) {
message += "exception was \"" + tojson(exception) + "\", it should have matched \"" +
errorRegex.toString() + "\"";
} else {
message += "no exception was thrown";
var goodStrings = [
"localhost:27999/test",
"[::1]:27999/test",
"[0:0:0:0:0:0:0:1]:27999/test",
"[0000:0000:0000:0000:0000:0000:0000:0001]:27999/test",
"localhost:27999",
"[::1]:27999",
"[0:0:0:0:0:0:0:1]:27999",
"[0000:0000:0000:0000:0000:0000:0000:0001]:27999",
];
var missingConnString = /^Missing connection string$/;
var incorrectType = /^Incorrect type/;
var emptyConnString = /^Empty connection string$/;
var badHost = /^Failed to parse mongodb/;
var emptyHost = /^Empty host component/;
var noPort = /^No digits/;
var badPort = /^Bad digit/;
var invalidPort = /^Port number \d+ out of range/;
var moreThanOneColon = /^More than one ':' detected/;
var charBeforeSquareBracket = /^'\[' present, but not first character/;
var noCloseBracket = /^ipv6 address is missing closing '\]'/;
var noOpenBracket = /^'\]' present without '\['/;
var noColonPrePort = /^missing colon after '\]' before the port/;
var badStrings = [
{s: undefined, r: missingConnString},
{s: 7, r: incorrectType},
{s: null, r: incorrectType},
{s: "", r: emptyConnString},
{s: " ", r: emptyConnString},
{s: ":", r: emptyHost},
{s: "/", r: badHost},
{s: ":/", r: emptyHost},
{s: ":/test", r: emptyHost},
{s: ":27999/", r: emptyHost},
{s: ":27999/test", r: emptyHost},
{s: "/test", r: badHost},
{s: "localhost:/test", r: noPort},
{s: "[::1]:/test", r: noPort},
{s: "[::1]:cat/test", r: badPort},
{s: "[::1]:1cat/test", r: badPort},
{s: "[::1]:123456/test", r: invalidPort},
{s: "[::1]:65536/test", r: invalidPort},
{s: "127.0.0.1:65536/test", r: invalidPort},
{s: "::1:27999/test", r: moreThanOneColon},
{s: "0:0::0:0:1:27999/test", r: moreThanOneColon},
{s: "0000:0000:0000:0000:0000:0000:0000:0001:27999/test", r: moreThanOneColon},
{s: "a[127.0.0.1]:27999/", r: charBeforeSquareBracket},
{s: "a[::1:]27999/", r: charBeforeSquareBracket},
{s: "[::1:27999/", r: noCloseBracket},
{s: "[::1:]27999/", r: noColonPrePort},
{s: "::1]:27999/", r: noOpenBracket},
];
var substitutePort = function(connectionString) {
// This will be called with non-strings as well as strings, so we need to catch exceptions
try {
return connectionString.replace("27999", "" + port);
} catch (e) {
return connectionString;
}
};
var testGood = function(i, connectionString) {
print("\n---\nTesting good connection string " + i + " (\"" + connectionString + "\") ...");
var gotException = false;
var exception;
try {
var connectDB = connect(connectionString);
connectDB = null;
} catch (e) {
gotException = true;
exception = e;
}
if (!gotException) {
print("Good connection string " + i + " (\"" + connectionString +
"\") correctly validated");
return;
}
var message = "FAILED to correctly validate goodString " + i + " (\"" + connectionString +
"\"): exception was \"" + tojson(exception) + "\"";
doassert(message);
};
var testBad = function(i, connectionString, errorRegex) {
print("\n---\nTesting bad connection string " + i + " (\"" + connectionString + "\") ...");
var gotException = false;
var gotCorrectErrorText = false;
var exception;
try {
var connectDB = connect(connectionString);
connectDB = null;
} catch (e) {
gotException = true;
exception = e;
if (errorRegex.test(e.message)) {
gotCorrectErrorText = true;
}
}
if (gotCorrectErrorText) {
print("Bad connection string " + i + " (\"" + connectionString +
"\") correctly rejected:\n" + tojson(exception));
return;
}
var message = "FAILED to generate correct exception for badString " + i + " (\"" +
connectionString + "\"): ";
if (gotException) {
message += "exception was \"" + tojson(exception) + "\", it should have matched \"" +
errorRegex.toString() + "\"";
} else {
message += "no exception was thrown";
}
doassert(message);
};
var i;
jsTest.log("TESTING " + goodStrings.length + " good connection strings");
for (i = 0; i < goodStrings.length; ++i) {
testGood(i, substitutePort(goodStrings[i]));
}
doassert(message);
};
var i;
jsTest.log("TESTING " + goodStrings.length + " good connection strings");
for (i = 0; i < goodStrings.length; ++i) {
testGood(i, substitutePort(goodStrings[i]));
}
jsTest.log("TESTING " + badStrings.length + " bad connection strings");
for (i = 0; i < badStrings.length; ++i) {
testBad(i, substitutePort(badStrings[i].s), badStrings[i].r);
}
jsTest.log("TESTING " + badStrings.length + " bad connection strings");
for (i = 0; i < badStrings.length; ++i) {
testBad(i, substitutePort(badStrings[i].s), badStrings[i].r);
}
jsTest.log("SUCCESSFUL test completion");
jsTest.log("SUCCESSFUL test completion");
})();

View File

@ -19,17 +19,16 @@
"--nodb",
"--eval",
"inner_mode=true;port=" + primary.port + ";",
"jstests/noPassthroughWithMongod/host_connection_string_validation.js"
"jstests/noPassthroughWithMongod/replset_host_connection_validation.js"
];
const exitCode = _runMongoProgram(...args);
jsTest.log("Inner mode test finished, exit code was " + exitCode);
// Stop the server we started
jsTest.log("Outer mode test stopping server");
MongoRunner.stopMongod(primary.port, 15);
// Pass the inner test's exit code back as the outer test's exit code
quit(exitCode);
if (exitCode != 0) {
doassert("inner test failed with exit code " + exitcode);
}
return;
}
const testHost = function(host) {

View File

@ -227,9 +227,17 @@ string getURIFromArgs(const std::string& url, const std::string& host, const std
// If host looks like a full URI (i.e. has a slash and isn't a unix socket) and the other fields
// are empty, then just return host.
std::string::size_type slashPos;
if (url.size() == 0 && port.size() == 0 &&
(!hostEndsInSock && host.find("/") != string::npos)) {
return host;
(!hostEndsInSock && ((slashPos = host.find("/")) != string::npos))) {
if (str::startsWith(host, "mongodb://")) {
return host;
}
// If there's a slash in the host field, then it's the replica set name, not a database name
stringstream ss;
ss << "mongodb://" << host.substr(slashPos + 1)
<< "/?replicaSet=" << host.substr(0, slashPos);
return ss.str();
}
stringstream ss;
@ -712,7 +720,7 @@ int _main(int argc, char* argv[], char** envp) {
auto poolGuard = MakeGuard([] { ScriptEngine::dropScopeCache(); });
unique_ptr<mongo::Scope> scope(mongo::getGlobalScriptEngine()->newScopeForCurrentThread());
unique_ptr<mongo::Scope> scope(mongo::getGlobalScriptEngine()->newScope());
shellMainScope = scope.get();
if (shellGlobalParams.runShell)

View File

@ -228,6 +228,8 @@ connect = function(url, user, pass) {
}
if (slash == -1 && colon == -1) {
url = "mongodb://127.0.0.1:27017/" + url;
} else if (slash != -1) {
url = "mongodb://" + url;
}
}