diff options
author | Kevin Albertson <kevin.albertson@10gen.com> | 2018-01-24 11:44:17 -0500 |
---|---|---|
committer | Kevin Albertson <kevin.albertson@10gen.com> | 2018-02-20 09:25:18 -0500 |
commit | 8821cdb5508f8a26c025b3e0124903e9ae64c479 (patch) | |
tree | c14704442eb088a67d4dfd23c3feca569062a95b /src | |
parent | 7f5f161abc0355b71823be7b768075547f30a0cb (diff) | |
download | mongo-8821cdb5508f8a26c025b3e0124903e9ae64c479.tar.gz |
SERVER-25640 check if jstests leave unterminated processes
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/shell/dbshell.cpp | 35 | ||||
-rw-r--r-- | src/mongo/shell/shell_utils_launcher.cpp | 17 | ||||
-rw-r--r-- | src/mongo/shell/shell_utils_launcher.h | 3 |
3 files changed, 51 insertions, 4 deletions
diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp index 83e07975a68..fea0aefc995 100644 --- a/src/mongo/shell/dbshell.cpp +++ b/src/mongo/shell/dbshell.cpp @@ -930,10 +930,37 @@ int _main(int argc, char* argv[], char** envp) { cout << "failed to load: " << shellGlobalParams.files[i] << endl; return -3; } - if (mongo::shell_utils::KillMongoProgramInstances() != EXIT_SUCCESS) { - cout << "one more more child processes exited with an error during " - << shellGlobalParams.files[i] << endl; - return -3; + + // Check if the process left any running child processes. + std::vector<ProcessId> pids = mongo::shell_utils::getRunningMongoChildProcessIds(); + + if (!pids.empty()) { + cout << "terminating the following processes started by " << shellGlobalParams.files[i] + << ": "; + std::copy(pids.begin(), pids.end(), std::ostream_iterator<ProcessId>(cout, " ")); + cout << endl; + + if (mongo::shell_utils::KillMongoProgramInstances() != EXIT_SUCCESS) { + cout << "one more more child processes exited with an error during " + << shellGlobalParams.files[i] << endl; + return -3; + } + + bool failIfUnterminatedProcesses = false; + const StringData code = + "function() { return typeof TestData === 'object' && TestData !== null && " + "TestData.hasOwnProperty('failIfUnterminatedProcesses') && " + "TestData.failIfUnterminatedProcesses; }"_sd; + shellMainScope->invokeSafe(code.rawData(), 0, 0); + failIfUnterminatedProcesses = shellMainScope->getBoolean("__returnValue"); + + if (failIfUnterminatedProcesses) { + cout << "exiting with a failure due to unterminated processes" << endl + << "a call to MongoRunner.stopMongod(), ReplSetTest#stopSet(), or " + "ShardingTest#stop() may be missing from the test" + << endl; + return -6; + } } } diff --git a/src/mongo/shell/shell_utils_launcher.cpp b/src/mongo/shell/shell_utils_launcher.cpp index 680a1c235b2..f37f4b6964c 100644 --- a/src/mongo/shell/shell_utils_launcher.cpp +++ b/src/mongo/shell/shell_utils_launcher.cpp @@ -1048,6 +1048,23 @@ int KillMongoProgramInstances() { return returnCode; } +std::vector<ProcessId> getRunningMongoChildProcessIds() { + std::vector<ProcessId> registeredPids, outPids; + registry.getRegisteredPids(registeredPids); + // Only return processes that are still alive. A client may have started a program using a mongo + // helper but terminated another way. E.g. if a mongod is started with MongoRunner.startMongod + // but exited with db.shutdownServer. + std::copy_if(registeredPids.begin(), + registeredPids.end(), + std::back_inserter(outPids), + [](const ProcessId& pid) { + const bool block = false; + bool isDead = wait_for_pid(pid, block); + return !isDead; + }); + return outPids; +} + MongoProgramScope::~MongoProgramScope() { DESTRUCTOR_GUARD(KillMongoProgramInstances(); ClearRawMongoProgramOutput(BSONObj(), 0);) } diff --git a/src/mongo/shell/shell_utils_launcher.h b/src/mongo/shell/shell_utils_launcher.h index 0b79180fc19..1a38b21c7b1 100644 --- a/src/mongo/shell/shell_utils_launcher.h +++ b/src/mongo/shell/shell_utils_launcher.h @@ -56,6 +56,9 @@ struct MongoProgramScope { }; int KillMongoProgramInstances(); +// Returns true if there are running child processes. +std::vector<ProcessId> getRunningMongoChildProcessIds(); + void installShellUtilsLauncher(Scope& scope); /** Record log lines from concurrent programs. All public members are thread safe. */ |