142 lines
4.7 KiB
JavaScript
142 lines
4.7 KiB
JavaScript
/**
|
|
* Tests that the shell helper db.currentOpCursor isn't constrained by the legacy currentOp server
|
|
* command - ie. the result set isn't limited to 16MB and long operations aren't truncated.
|
|
*
|
|
* @tags: [
|
|
* uses_parallel_shell,
|
|
* # This test uses currentOp to check whether an aggregate command is running. In replica set
|
|
* # environments, because currentOp is run against the admin database it is routed to the
|
|
* # primary, while the aggregate may be routed to a secondary. If currentOp is running on one
|
|
* # node and the expected command is run on another, the latter will not show up in the
|
|
* # currentOp results.
|
|
* assumes_read_preference_unchanged,
|
|
* no_selinux,
|
|
* ]
|
|
*/
|
|
|
|
(function() {
|
|
"use strict";
|
|
|
|
load("jstests/libs/fixture_helpers.js"); // for FixtureHelpers
|
|
|
|
const coll = db.currentOp_cursor;
|
|
coll.drop();
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
assert.commandWorked(coll.insert({val: 1}));
|
|
}
|
|
|
|
// Test that db.currentOpCursor() returns an iterable cursor.
|
|
let res = db.currentOpCursor();
|
|
assert(res.hasNext());
|
|
assert(res.next());
|
|
|
|
// Test that db.currentOp() interface does not change.
|
|
res = db.currentOp();
|
|
assert("inprog" in res, "Result contains 'inprog' field");
|
|
assert("ok" in res, "Result contains 'ok' field");
|
|
|
|
// Attempting to access the fsyncLock field from the results throws with an error message.
|
|
let error = assert.throws(() => res.fsyncLock);
|
|
assert(
|
|
/fsyncLock is no longer included in the currentOp shell helper, run db\.runCommand\({currentOp: 1}\) instead/
|
|
.test(error));
|
|
|
|
function shellOp() {
|
|
function createLargeDoc() {
|
|
let doc = {};
|
|
for (let i = 0; i < 100; i++) {
|
|
doc[i] = "Testing testing 1 2 3...";
|
|
}
|
|
return doc;
|
|
}
|
|
|
|
assert.commandFailedWithCode(db.runCommand({
|
|
aggregate: "currentOp_cursor",
|
|
pipeline: [{
|
|
$addFields: {
|
|
newVal: {$function: {args: [], body: "sleep(1000000)", lang: "js"}},
|
|
bigDoc: createLargeDoc()
|
|
}
|
|
}],
|
|
comment: TestData.comment,
|
|
cursor: {}
|
|
}),
|
|
ErrorCodes.Interrupted);
|
|
}
|
|
|
|
function startShellWithOp(comment) {
|
|
TestData.comment = comment;
|
|
const awaitShell = startParallelShell(shellOp);
|
|
|
|
// Confirm that the operation has started in the parallel shell.
|
|
assert.soon(
|
|
function() {
|
|
let aggRes =
|
|
db.getSiblingDB("admin")
|
|
.aggregate([
|
|
{$currentOp: {}},
|
|
{$match: {ns: "test.currentOp_cursor", "command.comment": TestData.comment}}
|
|
])
|
|
.toArray();
|
|
return aggRes.length >= 1;
|
|
},
|
|
function() {
|
|
return "Failed to find parallel shell operation in $currentOp output: " +
|
|
tojson(db.currentOp());
|
|
});
|
|
return awaitShell;
|
|
}
|
|
|
|
// Test that the currentOp server command truncates long operations with a warning logged.
|
|
const serverCommandTest = startShellWithOp("currentOp_server");
|
|
res = db.adminCommand({
|
|
currentOp: true,
|
|
$and: [{"ns": "test.currentOp_cursor"}, {"command.comment": "currentOp_server"}]
|
|
});
|
|
|
|
if (FixtureHelpers.isMongos(db) && FixtureHelpers.isSharded(coll)) {
|
|
// Assert currentOp truncation behavior for each shard in the cluster.
|
|
assert(res.inprog.length >= 1, res);
|
|
res.inprog.forEach((result) => {
|
|
assert.eq(result.op, "getmore", result);
|
|
assert(result.cursor.originatingCommand.hasOwnProperty("$truncated"), result);
|
|
});
|
|
} else {
|
|
// Assert currentOp truncation behavior for unsharded collections.
|
|
assert.eq(res.inprog.length, 1, res);
|
|
assert.eq(res.inprog[0].op, "command", res);
|
|
assert(res.inprog[0].command.hasOwnProperty("$truncated"), res);
|
|
}
|
|
|
|
const log = FixtureHelpers.getPrimaryForNodeHostingDatabase(db).adminCommand({getLog: "global"});
|
|
assert(/will be truncated/.test(log.log));
|
|
|
|
res.inprog.forEach((op) => {
|
|
assert.commandWorked(db.killOp(op.opid));
|
|
});
|
|
|
|
serverCommandTest();
|
|
|
|
// Test that the db.currentOp() shell helper does not truncate ops.
|
|
const shellHelperTest = startShellWithOp("currentOp_shell");
|
|
res = db.currentOp({"ns": "test.currentOp_cursor", "command.comment": "currentOp_shell"});
|
|
|
|
if (FixtureHelpers.isMongos(db) && FixtureHelpers.isSharded(coll)) {
|
|
assert(res.inprog.length >= 1, res);
|
|
res.inprog.forEach((result) => {
|
|
assert.eq(result.op, "getmore", result);
|
|
assert(!result.cursor.originatingCommand.hasOwnProperty("$truncated"), result);
|
|
});
|
|
} else {
|
|
assert.eq(res.inprog.length, 1, res);
|
|
assert(!res.inprog[0].command.hasOwnProperty("$truncated"), res);
|
|
}
|
|
|
|
res.inprog.forEach((op) => {
|
|
assert.commandWorked(db.killOp(op.opid));
|
|
});
|
|
|
|
shellHelperTest();
|
|
})();
|