SERVER-108357: Chase out dead code and unused vars in Shell JS (#39374)

GitOrigin-RevId: fdf7b6be76baa4d9382155ff92fb52e204747358
This commit is contained in:
Steve McClure 2025-07-31 09:18:13 -04:00 committed by MongoDB Bot
parent 2f646188fe
commit 31663db57d
20 changed files with 53 additions and 283 deletions

3
.github/CODEOWNERS vendored
View File

@ -727,6 +727,9 @@ WORKSPACE.bazel @10gen/devprod-build @svc-auto-approve-bot
# The following patterns are parsed from ./jstests/core/replicate_record_ids/OWNERS.yml
/jstests/core/replicate_record_ids/**/* @10gen/server-storage-engine-integration @svc-auto-approve-bot
# The following patterns are parsed from ./jstests/core/shell/OWNERS.yml
/jstests/core/shell/ @10gen/devprod-correctness @svc-auto-approve-bot
# The following patterns are parsed from ./jstests/core/testing/OWNERS.yml
/jstests/core/testing/**/* @10gen/server-programmability @svc-auto-approve-bot

View File

@ -203,24 +203,17 @@ export default [
__prompt__: true,
__quiet: true,
_awaitRSHostViaRSMonitor: true,
_barFormat: true,
_getErrorWithCode: true,
_isSpiderMonkeyDebugEnabled: true,
_originalPrint: true,
_shouldRetryWrites: true,
_shouldUseImplicitSessions: true,
_validateMemberIndex: true,
_verboseShell: true,
chatty: true,
compare: true,
compareOn: true,
defaultPrompt: true,
disablePrint: true,
enablePrint: true,
executeNoThrowNetworkError: true,
friendlyEqual: true,
hasErrorCode: true,
helloStatePrompt: true,
help: true,
indentStr: true,
isNetworkError: true,
@ -230,12 +223,10 @@ export default [
jsTestLog: true,
jsTestName: true,
printStackTrace: true,
replSetMemberStatePrompt: true,
retryOnNetworkError: true,
retryOnRetryableError: true,
shellAutocomplete: true,
shellHelper: true,
shellPrint: true,
shellPrintHelper: true,
setVerboseShell: true,
timestampCmp: true,
@ -397,6 +388,7 @@ export default [
],
rules: {
"no-var": 2,
"no-unused-vars": [2, {args: "none", caughtErrors: "none"}],
},
},
];

View File

@ -0,0 +1,5 @@
version: 2.0.0
filters:
- "*":
approvers:
- 10gen/devprod-correctness

View File

@ -1,4 +1,4 @@
let baseName = "jstests_shellkillop";
const baseName = "jstests_shellkillop";
// 'retry' should be set to true in contexts where an exception should cause the test to be retried
// rather than to fail.
@ -9,14 +9,14 @@ function testShellAutokillop() {
db[baseName].drop();
print("shellkillop.js insert data");
for (let i = 0; i < 100000; ++i) {
for (let i = 0; i < 100_000; ++i) {
db[baseName].insert({i: 1});
}
assert.eq(100000, db[baseName].count());
assert.eq(100_000, db[baseName].count());
// mongo --autokillop suppressed the ctrl-c "do you want to kill current operation" message
// it's just for testing purposes and thus not in the shell help
var evalStr = "print('SKO subtask started'); db." + baseName +
let evalStr = "print('SKO subtask started'); db." + baseName +
".update( {}, {$set:{i:'abcdefghijkl'}}, false, true ); db." + baseName + ".count();";
print("shellkillop.js evalStr:" + evalStr);
let spawn = startMongoProgramNoConnect(
@ -24,7 +24,7 @@ function testShellAutokillop() {
sleep(100);
retry = true;
assert(db[baseName].find({i: 'abcdefghijkl'}).count() < 100000,
assert(db[baseName].find({i: 'abcdefghijkl'}).count() < 100_000,
"update ran too fast, test won't be valid");
retry = false;
@ -34,20 +34,36 @@ function testShellAutokillop() {
print("count abcdefghijkl:" + db[baseName].find({i: 'abcdefghijkl'}).count());
var inprog = db.currentOp().inprog;
let inprog = db.currentOp().inprog;
for (let i in inprog) {
if (inprog[i].ns == "test." + baseName)
throw Error("shellkillop.js op is still running: " + tojson(inprog[i]));
}
retry = true;
assert(db[baseName].find({i: 'abcdefghijkl'}).count() < 100000,
assert(db[baseName].find({i: 'abcdefghijkl'}).count() < 100_000,
"update ran too fast, test was not valid");
retry = false;
}
}
for (var nTries = 0; nTries < 10 && retry; ++nTries) {
function myPort() {
const hosts = globalThis.db.getMongo().host.split(',');
const ip6Numeric = hosts[0].match(/^\[[0-9A-Fa-f:]+\]:(\d+)$/);
if (ip6Numeric) {
return ip6Numeric[1];
}
const hasPort = hosts[0].match(/:(\d+)/);
if (hasPort) {
return hasPort[1];
}
return 27017;
};
for (let nTries = 0; nTries < 10 && retry; ++nTries) {
try {
testShellAutokillop();
} catch (e) {

View File

@ -71,16 +71,17 @@ describe("tojson", function() {
let json;
json = tojson(obj);
assert.eq(tojson(obj), '{ "x" : [ ], "y" : { } }');
assert.eq(json, '{ "x" : [ ], "y" : { } }');
json = tojson(obj, "", true);
assert.eq(tojson(obj), '{ "x" : [ ], "y" : { } }');
jsTest.log.info(json);
assert.eq(json, '{ "x" : [ ], "y" : { } }');
json = toJsonForLog(obj);
assert.eq(tojson(obj), '{ "x" : [ ], "y" : { } }');
assert.eq(json, '{"x":[],"y":{}}');
json = tojson(obj, "", false);
assert.eq(tojson(obj), '{ "x" : [ ], "y" : { } }');
assert.eq(json, '{\n\t"x" : [ ],\n\t"y" : {\n\t\t\n\t}\n}');
});
it("deep", function() {

View File

@ -1,4 +1,5 @@
function tryParallelShell() {
// eslint-disable-next-line no-unused-vars
let nevercalled = startParallelShell("");
// The shell running this function will generate a non-zero exit code
// because nevercalled isn't called.

View File

@ -3,7 +3,7 @@ const regexMatch = /sh([0-9]{1,10})\|/;
// Test that a normal mongo shell gives us some noise in the raw output.
{
const out = runMongoProgram('mongo', '--port', mongo.port, '--eval', ';');
runMongoProgram('mongo', '--port', mongo.port, '--eval', ';');
const mongoOutput = rawMongoProgramOutput(".*");
assert.gte(mongoOutput.match(regexMatch).length, 1);
@ -13,7 +13,7 @@ clearRawMongoProgramOutput();
// Test that a quiet shell does not output anything.
{
const out = runMongoProgram('mongo', '--port', mongo.port, '--quiet', '--eval', ';');
runMongoProgram('mongo', '--port', mongo.port, '--quiet', '--eval', ';');
const mongoOutput = rawMongoProgramOutput(".*");
assert.eq(mongoOutput.match(regexMatch), null);

View File

@ -360,7 +360,6 @@ tests.push(function soonNoExceptEventuallyPassesEvenWithExceptions() {
});
tests.push(function soonNoExceptFailsIfExceptionAlwaysThrown() {
let count = 0;
assert.throws(() => {
assert.soonNoExcept(() => {
throw new Error('failed');

View File

@ -6,7 +6,6 @@ rst.startSet();
rst.initiate();
let mongoUri = "mongodb://" + rst.nodes.map((node) => node.host).join(",") + "/test";
let conn = rst.nodes[0];
// There are three ways to enable retryable writes in the mongo shell.
// 1. (cmdline flag) start mongo shell with --retryWrites

View File

@ -1,15 +1,11 @@
// Batch types
let NONE = 0;
let INSERT = 1;
let UPDATE = 2;
let REMOVE = 3;
const INSERT = 1;
const UPDATE = 2;
const REMOVE = 3;
// Error codes
let UNKNOWN_ERROR = 8;
let WRITE_CONCERN_FAILED = 64;
let UNKNOWN_REPL_WRITE_CONCERN = 79;
let NOT_MASTER = 10107;
const WRITE_CONCERN_FAILED = 64;
/**
* Helper function to define properties
@ -519,7 +515,6 @@ let Batch = function(batchType, originalZeroIndex) {
* Wraps the operations done for the batch
***********************************************************/
let Bulk = function(collection, ordered) {
let self = this;
let coll = collection;
let executed = false;
@ -956,9 +951,6 @@ let Bulk = function(collection, ordered) {
if (currentBatch)
batches.push(currentBatch);
// Total number of batches to execute
let totalNumberToExecute = batches.length;
// Execute all the batches
for (let i = 0; i < batches.length; i++) {
// Execute the batch

View File

@ -10,6 +10,8 @@ if ((typeof DBCollection) == "undefined") {
* @param {string} shortName
* @param {string} fullName
*/
// eslint-disable-next-line no-unused-vars
function DBCollection(mongo, db, shortName, fullName) {
this._mongo = mongo;
this._db = db;

View File

@ -1409,7 +1409,6 @@ DB.prototype._authOrThrow = function() {
};
DB.prototype.auth = function() {
let ex;
try {
this._authOrThrow.apply(this, arguments);
} catch (ex) {

View File

@ -9,54 +9,6 @@ let shellVersion = version;
let serverExitCodeMap = {};
let grpcToMongoRpcPortMap = {};
let _parsePath = function() {
let dbpath = "";
for (let i = 0; i < arguments.length; ++i)
if (arguments[i] == "--dbpath")
dbpath = arguments[i + 1];
if (dbpath == "")
throw Error("No dbpath specified");
return dbpath;
};
let createMongoArgs = function(binaryName, args) {
if (!Array.isArray(args)) {
throw new Error("The second argument to createMongoArgs must be an array");
}
let fullArgs = [binaryName];
if (args.length == 1 && isObject(args[0])) {
let o = args[0];
for (let k in o) {
if (o.hasOwnProperty(k)) {
if (k == "v" && isNumber(o[k])) {
let n = o[k];
if (n > 0) {
if (n > 10)
n = 10;
let temp = "-";
while (n-- > 0)
temp += "v";
fullArgs.push(temp);
}
} else {
fullArgs.push("--" + k);
if (o[k] != "")
fullArgs.push("" + o[k]);
}
}
}
} else {
for (let i = 0; i < args.length; i++)
fullArgs.push(args[i]);
}
return fullArgs;
};
// A path.join-like thing for paths that must work
// on Windows (\-separated) and *nix (/-separated).
function pathJoin(...parts) {
@ -238,7 +190,7 @@ let convertVersionStringToArray = function(versionString) {
* This function will not work if the minor version is greater than or equal to 10
*/
let convertVersionStringToInteger = function(versionString) {
const [major, minor, point] = _convertVersionToIntegerArray(versionString);
const [major, minor] = _convertVersionToIntegerArray(versionString);
assert(
minor < 10,
`Cannot convert a minor version greater than ten to an integer value since the minor version is in the tens position in the integer. Minor version attempting to convert: ${
@ -246,17 +198,6 @@ let convertVersionStringToInteger = function(versionString) {
return (major * 100) + (minor * 10);
};
/**
* Returns the major version string from a version string.
*
* 3.3.4-fade3783 -> 3.3
* 3.2 -> 3.2
* 3 -> exception: versions must have at least two components.
*/
let extractMajorVersionFromVersionString = function(versionString) {
return convertVersionStringToArray(versionString).slice(0, 2).join('.');
};
// These patterns allow substituting the binary versions used for each version string to support
// the dev/stable MongoDB release cycle.
let fcvConstants = getFCVConstants();
@ -1236,24 +1177,6 @@ MongoRunner.getAndPrepareDumpDirectory = function(testName) {
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");
let _startMongodEmpty = function() {
let args = createMongoArgs("mongod", Array.from(arguments));
let dbpath = _parsePath.apply(null, args);
resetDbpath(dbpath);
return startMongoProgram.apply(null, args);
};
function _startMongod() {
print("startMongod WARNING DELETES DATA DIRECTORY THIS IS FOR TESTING ONLY");
return _startMongodEmpty.apply(null, arguments);
};
/**
* Returns a new argArray with any test-specific arguments added.
*/
@ -1717,7 +1640,7 @@ function _getMongoProgramArguments(args) {
const separator = _isWindows() ? '\\' : '/';
progName = progName.split(separator).pop();
const [baseProgramName, programVersion] = progName.split("-");
const [baseProgramName] = progName.split("-");
let newArgs = [];
// Non-shell binaries (which are in fact instantiated via `runMongoProgram`) may not support
@ -1783,25 +1706,8 @@ function startMongoProgramNoConnect() {
return _startMongoProgram.apply(null, _getMongoProgramArguments(arguments));
};
function myPort() {
const hosts = globalThis.db.getMongo().host.split(',');
const ip6Numeric = hosts[0].match(/^\[[0-9A-Fa-f:]+\]:(\d+)$/);
if (ip6Numeric) {
return ip6Numeric[1];
}
const hasPort = hosts[0].match(/:(\d+)/);
if (hasPort) {
return hasPort[1];
}
return 27017;
};
export {
MongoRunner,
myPort,
runMongoProgram,
startMongoProgram,
startMongoProgramNoConnect,

View File

@ -2,14 +2,12 @@
import {
MongoRunner,
myPort,
runMongoProgram,
startMongoProgram,
startMongoProgramNoConnect
} from "src/mongo/shell/servers.js";
globalThis.MongoRunner = MongoRunner;
globalThis.myPort = myPort;
globalThis.runMongoProgram = runMongoProgram;
globalThis.startMongoProgram = startMongoProgram;
globalThis.startMongoProgramNoConnect = startMongoProgramNoConnect;

View File

@ -62,8 +62,6 @@ ToolTest.prototype.runTool = function() {
return runMongoProgram.apply(null, a);
};
let uncheckedParallelShellPids;
// Defer initializing these variables until the first call, as TestData attributes may be
// initialized as part of the --eval argument (e.g. by resmoke.py), which will not be evaluated
// until after this has loaded.

View File

@ -197,8 +197,6 @@ function SessionAwareClient(client) {
function gossipClusterTime(cmdObj, clusterTime) {
cmdObj = Object.assign({}, cmdObj);
const cmdName = Object.keys(cmdObj)[0];
if (!cmdObj.hasOwnProperty("$clusterTime")) {
cmdObj.$clusterTime = clusterTime;
}
@ -558,8 +556,6 @@ function ServerSession(client) {
this.injectSessionId = function injectSessionId(cmdObj) {
cmdObj = Object.assign({}, cmdObj);
const cmdName = Object.keys(cmdObj)[0];
if (!cmdObj.hasOwnProperty("lsid")) {
if (isAcknowledged(cmdObj)) {
cmdObj.lsid = this.handle.getId();
@ -576,8 +572,6 @@ function ServerSession(client) {
this.assignTransactionNumber = function assignTransactionNumber(cmdObj) {
cmdObj = Object.assign({}, cmdObj);
const cmdName = Object.keys(cmdObj)[0];
if (!cmdObj.hasOwnProperty("txnNumber")) {
this.handle.incrementTxnNumber();
cmdObj.txnNumber = this.handle.getTxnNumber();

View File

@ -231,23 +231,6 @@ function hasErrorCode(response, errorCodes) {
return false;
}
/**
* Run the passed function and catch any network error, otherwise throw the exception back to the
* caller.
* @param {Function} func that will run and catch any network error otherwise throws.
* @returns returns the result of the function that was passed as a parameter or the exception.
*/
function executeNoThrowNetworkError(func) {
try {
return func();
} catch (e) {
if (isNetworkError(e)) {
return e;
}
throw e;
}
}
// Please consider using bsonWoCompare instead of this as much as possible.
function friendlyEqual(a, b) {
if (a == b)
@ -293,29 +276,6 @@ function setVerboseShell(value) {
_verboseShell = value;
};
// Formats a simple stacked horizontal histogram bar in the shell.
// @param data array of the form [[ratio, symbol], ...] where ratio is between 0 and 1 and
// symbol is a string of length 1
// @param width width of the bar (excluding the left and right delimiters [ ] )
// e.g. _barFormat([[.3, "="], [.5, '-']], 80) returns
// "[========================---------------------------------------- ]"
function _barFormat(data, width) {
let remaining = width;
let res = "[";
for (let i = 0; i < data.length; i++) {
for (let x = 0; x < data[i][0] * width; x++) {
if (remaining-- > 0) {
res += data[i][1];
}
}
}
while (remaining-- > 0) {
res += " ";
}
res += "]";
return res;
};
// these two are helpers for Array.sort(func)
function compare(l, r) {
return (l == r ? 0 : (l < r ? -1 : 1));
@ -328,21 +288,6 @@ function compareOn(field) {
};
};
function shellPrint(x) {
const it = x;
if (x != undefined)
shellPrintHelper(x);
};
let _originalPrint = print;
function disablePrint() {
print = Function.prototype;
};
function enablePrint() {
print = _originalPrint;
};
print.captureAllOutput = function(fn, args) {
let res = {};
res.output = [];
@ -1233,7 +1178,7 @@ shellHelper.show = function(what) {
}
if (what == "startupWarnings") {
let dbDeclared, ex;
let dbDeclared;
try {
// !!db essentially casts db to a boolean
// Will throw a reference exception if db hasn't been declared.
@ -1288,7 +1233,7 @@ shellHelper.show = function(what) {
}
if (what == "automationNotices") {
let dbDeclared, ex;
let dbDeclared;
try {
// !!db essentially casts db to a boolean
// Will throw a reference exception if db hasn't been declared.
@ -2106,24 +2051,17 @@ export {
__promptWrapper__,
__prompt__,
_awaitRSHostViaRSMonitor,
_barFormat,
_getErrorWithCode,
_isSpiderMonkeyDebugEnabled,
_originalPrint,
_shouldRetryWrites,
_shouldUseImplicitSessions,
_validateMemberIndex,
_verboseShell,
chatty,
compare,
compareOn,
defaultPrompt,
disablePrint,
enablePrint,
executeNoThrowNetworkError,
friendlyEqual,
hasErrorCode,
helloStatePrompt,
help,
indentStr,
isNetworkError,
@ -2133,13 +2071,11 @@ export {
jsTestLog,
jsTestName,
printStackTrace,
replSetMemberStatePrompt,
retryOnNetworkError,
retryOnRetryableError,
rs,
shellAutocomplete,
shellHelper,
shellPrint,
shellPrintHelper,
setVerboseShell,
timestampCmp,

View File

@ -24,13 +24,12 @@ authutil.logout = function(conn, dbname) {
* in "conns" in the logged-out-of-dbName state.
*/
authutil.assertAuthenticate = function(conns, dbName, authParams) {
let conn, i, ex, ex2;
if (conns.length == null)
conns = [conns];
try {
for (i = 0; i < conns.length; ++i) {
conn = conns[i];
for (let i = 0; i < conns.length; ++i) {
let conn = conns[i];
// Bypass the implicit auth call in getDB();
const db = new DB(conn, dbName);
try {
@ -78,8 +77,6 @@ authutil.assertAuthenticateFails = function(conns, dbName, authParams) {
* user.
*/
authutil.asCluster = function(conn, keyfile, action) {
let ex;
// put a connection in an array for uniform processing.
let connArray = conn;
if (conn.length == null)

View File

@ -5,25 +5,18 @@ import {
__prompt__,
__promptWrapper__,
_awaitRSHostViaRSMonitor,
_barFormat,
_getErrorWithCode,
_isSpiderMonkeyDebugEnabled,
_originalPrint,
_shouldRetryWrites,
_shouldUseImplicitSessions,
_validateMemberIndex,
_verboseShell,
chatty,
compare,
compareOn,
defaultPrompt,
disablePrint,
enablePrint,
executeNoThrowNetworkError,
friendlyEqual,
Geo,
hasErrorCode,
helloStatePrompt,
help,
indentStr,
isNetworkError,
@ -34,14 +27,12 @@ import {
jsTestOptions,
printStackTrace,
Random,
replSetMemberStatePrompt,
retryOnNetworkError,
retryOnRetryableError,
rs,
setVerboseShell,
shellAutocomplete,
shellHelper,
shellPrint,
shellPrintHelper,
timestampCmp,
} from "src/mongo/shell/utils.js";
@ -50,25 +41,18 @@ globalThis.__magicNoPrint = __magicNoPrint;
globalThis.__prompt__ = __prompt__;
globalThis.__promptWrapper__ = __promptWrapper__;
globalThis._awaitRSHostViaRSMonitor = _awaitRSHostViaRSMonitor;
globalThis._barFormat = _barFormat;
globalThis._getErrorWithCode = _getErrorWithCode;
globalThis._isSpiderMonkeyDebugEnabled = _isSpiderMonkeyDebugEnabled;
globalThis._originalPrint = _originalPrint;
globalThis._shouldRetryWrites = _shouldRetryWrites;
globalThis._shouldUseImplicitSessions = _shouldUseImplicitSessions;
globalThis._validateMemberIndex = _validateMemberIndex;
globalThis._verboseShell = _verboseShell;
globalThis.chatty = chatty;
globalThis.compare = compare;
globalThis.compareOn = compareOn;
globalThis.defaultPrompt = defaultPrompt;
globalThis.disablePrint = disablePrint;
globalThis.enablePrint = enablePrint;
globalThis.executeNoThrowNetworkError = executeNoThrowNetworkError;
globalThis.friendlyEqual = friendlyEqual;
globalThis.Geo = Geo;
globalThis.hasErrorCode = hasErrorCode;
globalThis.helloStatePrompt = helloStatePrompt;
globalThis.help = help;
globalThis.indentStr = indentStr;
globalThis.isNetworkError = isNetworkError;
@ -79,13 +63,11 @@ globalThis.jsTestName = jsTestName;
globalThis.jsTestOptions = jsTestOptions;
globalThis.printStackTrace = printStackTrace;
globalThis.Random = Random;
globalThis.replSetMemberStatePrompt = replSetMemberStatePrompt;
globalThis.retryOnNetworkError = retryOnNetworkError;
globalThis.retryOnRetryableError = retryOnRetryableError;
globalThis.rs = rs;
globalThis.setVerboseShell = setVerboseShell;
globalThis.shellAutocomplete = shellAutocomplete;
globalThis.shellHelper = shellHelper;
globalThis.shellPrint = shellPrint;
globalThis.shellPrintHelper = shellPrintHelper;
globalThis.timestampCmp = timestampCmp;

View File

@ -988,56 +988,6 @@ function printShardingStatus(configDB, verbose) {
print(raw);
}
function printShardingSizes(configDB) {
// configDB is a DB object that contains the sharding metadata of interest.
// Defaults to the db named "config" on the current connection.
if (configDB === undefined) {
configDB = globalThis.db.getSiblingDB('config');
}
let version = configDB.getCollection("version").findOne();
if (version == null) {
print("printShardingSizes : not a shard db!");
return;
}
let raw = "";
let output = function(indent, s) {
raw += sh._shardingStatusStr(indent, s);
};
output(0, "--- Sharding Sizes --- ");
output(1, "sharding version: " + tojson(configDB.getCollection("version").findOne()));
output(1, "shards:");
configDB.shards.find().forEach(function(z) {
output(2, tojson(z));
});
let saveDB = globalThis.db;
output(1, "databases:");
configDB.databases.find().sort({name: 1}).forEach(function(db) {
output(2, tojson(db, "", true));
configDB.collections.find({_id: new RegExp("^" + RegExp.escape(db._id) + "\.")})
.sort({_id: 1})
.forEach(function(coll) {
output(3, coll._id + " chunks:");
configDB.chunks.find({"ns": coll._id}).sort({min: 1}).forEach(function(chunk) {
let out = saveDB.adminCommand(
{dataSize: coll._id, keyPattern: coll.key, min: chunk.min, max: chunk.max});
delete out.millis;
delete out.ok;
output(4,
tojson(chunk.min) + " -->> " + tojson(chunk.max) +
" on : " + chunk.shard + " " + tojson(out));
});
});
});
print(raw);
}
export {
sh,
printShardingStatus,