mirror of https://github.com/mongodb/mongo
54 lines
2.3 KiB
JavaScript
54 lines
2.3 KiB
JavaScript
/**
|
|
* Overrides Mongo.prototype.runCommand for read-only commands in order to run them multiple times
|
|
* in a row and return the result from the final execution. It is intended to help with testing any
|
|
* caches that might be involved in query processing, in particular the plan cache.
|
|
*/
|
|
import {OverrideHelpers} from "jstests/libs/override_methods/override_helpers.js";
|
|
|
|
// Represents the number of repeated runs of the command. The number is set to 3, as at first run we
|
|
// will create a plan cache entry, at the second run we will promote the cache entry to active and
|
|
// at the third run we will use the active cache entry.
|
|
const numberOfRuns = 3;
|
|
const kRerunnableReadCommands = new Set(["aggregate", "find", "count", "distinct", "mapReduce", "mapreduce"]);
|
|
|
|
function isRerunnableQuery(cmdName, cmdObj) {
|
|
if (
|
|
OverrideHelpers.isAggregationWithOutOrMergeStage(cmdName, cmdObj) ||
|
|
(cmdName.toLowerCase() == "mapreduce" && !OverrideHelpers.isMapReduceWithInlineOutput(cmdName, cmdObj))
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
return kRerunnableReadCommands.has(cmdName);
|
|
}
|
|
|
|
function runCommandOverride(conn, dbName, cmdName, cmdObj, clientFunction, makeFuncArgs) {
|
|
if (!isRerunnableQuery(cmdName, cmdObj)) {
|
|
return clientFunction.apply(conn, makeFuncArgs(cmdObj));
|
|
}
|
|
|
|
let lastResult;
|
|
for (let run = 0; run < numberOfRuns; run++) {
|
|
lastResult = clientFunction.apply(conn, makeFuncArgs(cmdObj));
|
|
if (run < numberOfRuns - 1) {
|
|
// Close any cursor the command might have returned.
|
|
if (lastResult.cursor) {
|
|
const {id, ns} = lastResult.cursor;
|
|
const respDbName = ns.split(".")[0];
|
|
const respCollName = ns.split(".").slice(1).join(".");
|
|
// It's ok if the cursor ID is 0 or otherwise invalid:
|
|
// killCursors will succeed and report it under "cursorsNotFound".
|
|
assert.commandWorked(conn.getDB(respDbName).runCommand({killCursors: respCollName, cursors: [id]}));
|
|
}
|
|
}
|
|
}
|
|
|
|
return lastResult;
|
|
}
|
|
|
|
// Override the default runCommand with our custom version.
|
|
OverrideHelpers.overrideRunCommand(runCommandOverride);
|
|
|
|
// Always apply the override if a test spawns a parallel shell.
|
|
OverrideHelpers.prependOverrideInParallelShell("jstests/libs/override_methods/rerun_queries.js");
|