Files
mongo/jstests/libs/override_methods/set_read_and_write_concerns.js
David Storch 82b16740f8 SERVER-19758 add support for "executionStats" and "allPlansExecution" to agg explain
Like other explainable commands, aggregate can now be
explained using the explain command, e.g.
db.runCommand({explain: {aggregate: ...}, verbosity:
"executionStats"}). The existing explain:true flag
corresponds to "queryPlanner" mode and is still supported.
However, explain:true cannot be specified when explaining
aggregate via the explain command.

Additional execution information is provided only in the
$cursor section of the aggregation explain output. Having
aggregation stages themselves track and report execution
info is further work.
2017-03-13 09:46:14 -04:00

185 lines
6.4 KiB
JavaScript

/**
* Use prototype overrides to set read concern and write concern while running core tests.
*/
(function() {
"use strict";
var defaultWriteConcern = {
w: "majority",
// Use a "signature" value that won't typically match a value assigned in normal use.
wtimeout: 60321
};
if (typeof TestData === "undefined" || !TestData.hasOwnProperty("defaultReadConcernLevel")) {
throw new Error(
"The default read-concern level must be set as the 'defaultReadConcernLevel' " +
"property on TestData");
}
var defaultReadConcern = {level: TestData.defaultReadConcernLevel};
var originalDBQuery = DBQuery;
DBQuery = function(mongo, db, collection, ns, query, fields, limit, skip, batchSize, options) {
if (ns.endsWith("$cmd")) {
if (query.hasOwnProperty("writeConcern") &&
bsonWoCompare(query.writeConcern, defaultWriteConcern) !== 0) {
jsTestLog("Warning: DBQuery overriding existing writeConcern of: " +
tojson(query.writeConcern));
query.writeConcern = defaultWriteConcern;
}
}
return originalDBQuery.apply(this, arguments);
};
DBQuery.Option = originalDBQuery.Option;
var originalStartParallelShell = startParallelShell;
startParallelShell = function(jsCode, port, noConnect) {
var newCode;
var overridesFile = "jstests/libs/override_methods/set_read_and_write_concerns.js";
if (typeof(jsCode) === "function") {
// Load the override file and immediately invoke the supplied function.
newCode = `load("${overridesFile}"); (${jsCode})();`;
} else {
newCode = `load("${overridesFile}"); ${jsCode};`;
}
return originalStartParallelShell(newCode, port, noConnect);
};
DB.prototype._runCommandImpl = function(dbName, obj, options) {
var cmdName = "";
for (var fieldName in obj) {
cmdName = fieldName;
break;
}
// These commands directly support a writeConcern argument.
var commandsToForceWriteConcern = [
"_mergeAuthzCollections",
"appendOplogNote",
"applyOps",
"authSchemaUpgrade",
"captrunc",
"cleanupOrphaned",
"clone",
"cloneCollection",
"cloneCollectionAsCapped",
// "collMod", SERVER-25196 - not supported
"convertToCapped",
"copydb",
"create",
"createIndexes",
"createRole",
"createUser",
"delete",
"drop",
"dropDatabase",
"dropAllRolesFromDatabase",
"dropAllUsersFromDatabase",
"dropDatabase",
"dropIndexes",
"dropRole",
"dropUser",
"emptycapped",
"findAndModify",
"findandmodify",
"godinsert",
"grantPrivilegesToRole",
"grantRolesToRole",
"grantRolesToUser",
"insert",
"mapReduceFinish",
"mergeAuthzCollections",
"moveChunk",
"movePrimary",
"remove",
"renameCollection",
"resvChunkStart",
"revokePriviligesFromRole",
"revokeRolesFromRole",
"revokeRolesFromUser",
"update",
"updateRole",
"updateUser",
];
// These are reading commands that support majority readConcern.
var commandsToForceReadConcern = [
"count",
"distinct",
"find",
"geoNear",
"geoSearch",
"group",
"parallelCollectionScan",
];
var forceWriteConcern = Array.contains(commandsToForceWriteConcern, cmdName);
var forceReadConcern = Array.contains(commandsToForceReadConcern, cmdName);
if (cmdName === "aggregate") {
// Aggregate can be either a read or a write depending on whether it has a $out stage.
// $out is required to be the last stage of the pipeline.
var stages = obj.pipeline;
const lastStage = stages && Array.isArray(stages) && (stages.length !== 0)
? stages[stages.length - 1]
: undefined;
const hasOut =
lastStage && (typeof lastStage === 'object') && lastStage.hasOwnProperty('$out');
const hasExplain = obj.hasOwnProperty("explain");
if (!hasExplain) {
if (hasOut) {
forceWriteConcern = true;
} else {
forceReadConcern = true;
}
}
}
else if (cmdName === "mapReduce") {
var stages = obj.pipeline;
const lastStage = stages && Array.isArray(stages) && (stages.length !== 0)
? stages[stages.length - 1]
: undefined;
const hasOut =
lastStage && (typeof lastStage === 'object') && lastStage.hasOwnProperty('$out');
if (hasOut) {
forceWriteConcern = true;
}
}
if (forceWriteConcern) {
if (obj.hasOwnProperty("writeConcern")) {
if (bsonWoCompare(obj.writeConcern, defaultWriteConcern) !== 0) {
jsTestLog("Warning: _runCommandImpl overriding existing writeConcern of: " +
tojson(obj.writeConcern));
obj.writeConcern = defaultWriteConcern;
}
} else {
obj.writeConcern = defaultWriteConcern;
}
} else if (forceReadConcern) {
if (obj.hasOwnProperty("readConcern")) {
if (bsonWoCompare(obj.readConcern, defaultReadConcern) !== 0) {
jsTestLog("Warning: _runCommandImpl overriding existing readConcern of: " +
tojson(obj.readConcern));
obj.readConcern = defaultReadConcern;
}
} else {
obj.readConcern = defaultReadConcern;
}
}
var res = this.getMongo().runCommand(dbName, obj, options);
return res;
};
// Use a majority write concern if the operation does not specify one.
DBCollection.prototype.getWriteConcern = function() {
return new WriteConcern(defaultWriteConcern);
};
})();