diff options
author | James Wahlin <james.wahlin@10gen.com> | 2016-06-06 09:41:33 -0400 |
---|---|---|
committer | James Wahlin <james.wahlin@10gen.com> | 2016-06-08 09:25:32 -0400 |
commit | f2d4b6f79ce6d14c1a7c2545df6bc054bf8941b2 (patch) | |
tree | 99ed8f44e56561af0b4e590f9e13dd41c2c17b29 /jstests/noPassthrough/currentop_query.js | |
parent | 070d49e2c66f96adf17883638cee43a25f136fea (diff) | |
download | mongo-f2d4b6f79ce6d14c1a7c2545df6bc054bf8941b2.tar.gz |
SERVER-23260 Test currentOp content for both operations and commands
Diffstat (limited to 'jstests/noPassthrough/currentop_query.js')
-rw-r--r-- | jstests/noPassthrough/currentop_query.js | 495 |
1 files changed, 263 insertions, 232 deletions
diff --git a/jstests/noPassthrough/currentop_query.js b/jstests/noPassthrough/currentop_query.js index 5847ff7015e..7b607d03966 100644 --- a/jstests/noPassthrough/currentop_query.js +++ b/jstests/noPassthrough/currentop_query.js @@ -5,263 +5,294 @@ (function() { "use strict"; - var conn = MongoRunner.runMongod({smallfiles: "", nojournal: ""}); - assert.neq(null, conn, "mongod was unable to start up"); - - var testDB = conn.getDB("test"); - assert.commandWorked(testDB.dropDatabase()); + /** + * @param {Object} params - Configuration options for the test. + * @param {string} params.readMode - The read mode to use for the parallel shell. This allows + * testing currentOp() output for both OP_QUERY and OP_GET_MORE queries, as well as "find" and + * "getMore" commands. + */ + function runTest(params) { + var conn = MongoRunner.runMongod({smallfiles: "", nojournal: ""}); + assert.neq(null, conn, "mongod was unable to start up"); - var coll = testDB.currentop_query; + var testDB = conn.getDB("test"); + assert.commandWorked(testDB.dropDatabase()); - // Force yield to occur on every PlanExecutor iteration. - assert.commandWorked( - testDB.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1})); + var coll = testDB.currentop_query; - /** - * Captures currentOp() for a given test command/operation and confirms that namespace, - * operation type and planSummary are correct. - * - * @param {Object} testObj - Contains test arguments. - * @param {function} testObj.test - A function that runs the desired test op/cmd. - * @param {string} testObj.planSummary - A string containing the expected planSummary. - * @param {Object} testObj.currentOpFilter - A filter to be used to narrow currentOp() output - * to only the relevant operation or command. - * @param {string} [testObj.command] - The command to test against. Will look for this to be - * a key in the currentOp().query object. - * @param {string} [testObj.operation] - The operation to test against. Will look for this - * to be the value of the currentOp().op field. - */ - function confirmCurrentOpContents(testObj) { - // Force queries to hang on yield to allow for currentOp capture. + // Force yield to occur on every PlanExecutor iteration. assert.commandWorked( - testDB.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "alwaysOn"})); + testDB.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1})); - // Run query. - var awaitShell = startParallelShell(testObj.test, conn.port); + /** + * Captures currentOp() for a given test command/operation and confirms that namespace, + * operation type and planSummary are correct. + * + * @param {Object} testObj - Contains test arguments. + * @param {function} testObj.test - A function that runs the desired test op/cmd. + * @param {string} testObj.planSummary - A string containing the expected planSummary. + * @param {Object} testObj.currentOpFilter - A filter to be used to narrow currentOp() + * output to only the relevant operation or command. + * @param {string} [testObj.command] - The command to test against. Will look for this to + * be a key in the currentOp().query object. + * @param {string} [testObj.operation] - The operation to test against. Will look for this + * to be the value of the currentOp().op field. + */ + function confirmCurrentOpContents(testObj) { + // Force queries to hang on yield to allow for currentOp capture. + assert.commandWorked(testDB.adminCommand( + {configureFailPoint: "setYieldAllLocksHang", mode: "alwaysOn"})); - // Capture currentOp record for the query and confirm that the 'query' and 'planSummary' - // fields contain the content expected. We are indirectly testing the 'ns' field as well - // with the currentOp query argument. - assert.soon( - function() { - testObj.currentOpFilter.ns = coll.getFullName(); - testObj.currentOpFilter.planSummary = testObj.planSummary; - if (testObj.hasOwnProperty("command")) { - testObj.currentOpFilter["query." + testObj.command] = {$exists: true}; - } else if (testObj.hasOwnProperty("operation")) { - testObj.currentOpFilter.op = testObj.operation; - } + // Set shell read mode for the parallel shell test. + TestData.shellReadMode = params.readMode; + TestData.currentOpTest = testObj.test; + testObj.test = function() { + db.getMongo().forceReadMode(TestData.shellReadMode); + TestData.currentOpTest(); + }; - var result = testDB.currentOp(testObj.currentOpFilter); - assert.commandWorked(result); + // Run query. + var awaitShell = startParallelShell(testObj.test, conn.port); - if (result.inprog.length === 1) { - return true; - } + // Capture currentOp record for the query and confirm that the 'query' and 'planSummary' + // fields contain the content expected. We are indirectly testing the 'ns' field as well + // with the currentOp query argument. + assert.soon( + function() { + testObj.currentOpFilter.ns = coll.getFullName(); + testObj.currentOpFilter.planSummary = testObj.planSummary; + if (testObj.hasOwnProperty("command")) { + testObj.currentOpFilter["query." + testObj.command] = {$exists: true}; + } else if (testObj.hasOwnProperty("operation")) { + testObj.currentOpFilter.op = testObj.operation; + } - return false; - }, - function() { - return "Failed to find operation from " + tojson(testObj) + - " in currentOp() output: " + tojson(testDB.currentOp()); - }); + var result = testDB.currentOp(testObj.currentOpFilter); + assert.commandWorked(result); - // Allow the query to complete. - assert.commandWorked( - testDB.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "off"})); + if (result.inprog.length === 1) { + return true; + } - awaitShell(); - } + return false; + }, + function() { + return "Failed to find operation from " + tojson(testObj) + + " in currentOp() output: " + tojson(testDB.currentOp()); + }); - // - // Confirm currentOp content for commands defined in 'testList'. - // - var testList = [ - { - test: function() { - assert.eq( - db.currentop_query.aggregate([{$match: {a: 1, $comment: "currentop_query"}}]) - .itcount(), - 1); - }, - command: "aggregate", - planSummary: "COLLSCAN", - currentOpFilter: {"query.pipeline.0.$match.$comment": "currentop_query"} - }, - { - test: function() { - assert.eq(db.currentop_query.find({a: 1, $comment: "currentop_query"}).count(), 1); - }, - command: "count", - planSummary: "COLLSCAN", - currentOpFilter: {"query.query.$comment": "currentop_query"} - }, - { - test: function() { - assert.eq(db.currentop_query.distinct("a", {a: 1, $comment: "currentop_query"}), [1]); - }, - command: "distinct", - planSummary: "COLLSCAN", - currentOpFilter: {"query.query.$comment": "currentop_query"} - }, - { - test: function() { - assert.eq(db.currentop_query.find({a: 1}).comment("currentop_query").itcount(), 1); - }, - command: "find", - planSummary: "COLLSCAN", - currentOpFilter: {"query.comment": "currentop_query"} - }, - { - test: function() { - assert.eq(db.currentop_query.findAndModify( - {query: {a: 1, $comment: "currentop_query"}, update: {$inc: {b: 1}}}), - {"_id": 1, "a": 1}); - }, - command: "findandmodify", - planSummary: "COLLSCAN", - currentOpFilter: {"query.query.$comment": "currentop_query"} - }, - { - test: function() { - assert.eq(db.currentop_query.group({ - key: {a: 1}, - cond: {a: 1, $comment: "currentop_query"}, - reduce: function() {}, - initial: {} - }), - [{"a": 1}]); - }, - command: "group", - planSummary: "COLLSCAN", - currentOpFilter: {"query.group.cond.$comment": "currentop_query"} - }, - { - test: function() { - assert.commandWorked(db.currentop_query.mapReduce( - function() { - emit(this.a, this.b); - }, - function(a, b) { - return Array.sum(b); - }, - {query: {a: 1, $comment: "currentop_query"}, out: {inline: 1}})); - }, - command: "mapreduce", - planSummary: "COLLSCAN", - currentOpFilter: {"query.query.$comment": "currentop_query"} - }, - { - test: function() { - assert.writeOK(db.currentop_query.remove({a: 2, $comment: "currentop_query"})); - }, - operation: "remove", - planSummary: "COLLSCAN", - currentOpFilter: {"query.$comment": "currentop_query"} - }, - { - test: function() { - assert.writeOK( - db.currentop_query.update({a: 1, $comment: "currentop_query"}, {$inc: {b: 1}})); - }, - operation: "update", - planSummary: "COLLSCAN", - currentOpFilter: {"query.$comment": "currentop_query"} + // Allow the query to complete. + assert.commandWorked( + testDB.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "off"})); + + awaitShell(); + delete TestData.currentOpTest; + delete TestData.shellReadMode; } - ]; - coll.drop(); - var i; - for (i = 0; i < 5; ++i) { - assert.writeOK(coll.insert({_id: i, a: i})); - } + // + // Confirm currentOp content for commands defined in 'testList'. + // + var testList = [ + { + test: function() { + assert.eq( + db.currentop_query.aggregate([{$match: {a: 1, $comment: "currentop_query"}}]) + .itcount(), + 1); + }, + command: "aggregate", + planSummary: "COLLSCAN", + currentOpFilter: {"query.pipeline.0.$match.$comment": "currentop_query"} + }, + { + test: function() { + assert.eq(db.currentop_query.find({a: 1, $comment: "currentop_query"}).count(), + 1); + }, + command: "count", + planSummary: "COLLSCAN", + currentOpFilter: {"query.query.$comment": "currentop_query"} + }, + { + test: function() { + assert.eq(db.currentop_query.distinct("a", {a: 1, $comment: "currentop_query"}), + [1]); + }, + command: "distinct", + planSummary: "COLLSCAN", + currentOpFilter: {"query.query.$comment": "currentop_query"} + }, + { + test: function() { + assert.eq(db.currentop_query.find({a: 1}).comment("currentop_query").itcount(), + 1); + }, + command: "find", + planSummary: "COLLSCAN", + currentOpFilter: {"query.comment": "currentop_query"} + }, + { + test: function() { + assert.eq( + db.currentop_query.findAndModify( + {query: {a: 1, $comment: "currentop_query"}, update: {$inc: {b: 1}}}), + {"_id": 1, "a": 1}); + }, + command: "findandmodify", + planSummary: "COLLSCAN", + currentOpFilter: {"query.query.$comment": "currentop_query"} + }, + { + test: function() { + assert.eq(db.currentop_query.group({ + key: {a: 1}, + cond: {a: 1, $comment: "currentop_query"}, + reduce: function() {}, + initial: {} + }), + [{"a": 1}]); + }, + command: "group", + planSummary: "COLLSCAN", + currentOpFilter: {"query.group.cond.$comment": "currentop_query"} + }, + { + test: function() { + assert.commandWorked(db.currentop_query.mapReduce( + function() { + emit(this.a, this.b); + }, + function(a, b) { + return Array.sum(b); + }, + {query: {a: 1, $comment: "currentop_query"}, out: {inline: 1}})); + }, + command: "mapreduce", + planSummary: "COLLSCAN", + currentOpFilter: {"query.query.$comment": "currentop_query"} + }, + { + test: function() { + assert.writeOK(db.currentop_query.remove({a: 2, $comment: "currentop_query"})); + }, + operation: "remove", + planSummary: "COLLSCAN", + currentOpFilter: {"query.$comment": "currentop_query"} + }, + { + test: function() { + assert.writeOK(db.currentop_query.update({a: 1, $comment: "currentop_query"}, + {$inc: {b: 1}})); + }, + operation: "update", + planSummary: "COLLSCAN", + currentOpFilter: {"query.$comment": "currentop_query"} + } + ]; - testList.forEach(confirmCurrentOpContents); + coll.drop(); + var i; + for (i = 0; i < 5; ++i) { + assert.writeOK(coll.insert({_id: i, a: i})); + } - // - // Confirm currentOp content for geoNear. - // - coll.drop(); - for (i = 0; i < 10; ++i) { - assert.writeOK(coll.insert({a: i, loc: {type: "Point", coordinates: [i, i]}})); - } - assert.commandWorked(coll.createIndex({loc: "2dsphere"})); + testList.forEach(confirmCurrentOpContents); - confirmCurrentOpContents({ - test: function() { - assert.commandWorked(db.runCommand({ - geoNear: "currentop_query", - near: {type: "Point", coordinates: [1, 1]}, - spherical: true, - query: {$comment: "currentop_query"} - })); - }, - command: "geoNear", - planSummary: "GEO_NEAR_2DSPHERE { loc: \"2dsphere\" }", - currentOpFilter: {"query.query.$comment": "currentop_query"} - }); + // + // Confirm currentOp content for geoNear. + // + coll.drop(); + for (i = 0; i < 10; ++i) { + assert.writeOK(coll.insert({a: i, loc: {type: "Point", coordinates: [i, i]}})); + } + assert.commandWorked(coll.createIndex({loc: "2dsphere"})); - // - // Confirm currentOp content for getMore. - // - coll.drop(); - for (i = 0; i < 10; ++i) { - assert.writeOK(coll.insert({a: i})); - } + confirmCurrentOpContents({ + test: function() { + assert.commandWorked(db.runCommand({ + geoNear: "currentop_query", + near: {type: "Point", coordinates: [1, 1]}, + spherical: true, + query: {$comment: "currentop_query"} + })); + }, + command: "geoNear", + planSummary: "GEO_NEAR_2DSPHERE { loc: \"2dsphere\" }", + currentOpFilter: {"query.query.$comment": "currentop_query"} + }); - var cmdRes = testDB.runCommand( - {find: "currentop_query", filter: {$comment: "currentop_query"}, batchSize: 2}); - assert.commandWorked(cmdRes); + // + // Confirm currentOp content for getMore. + // + coll.drop(); + for (i = 0; i < 10; ++i) { + assert.writeOK(coll.insert({a: i})); + } - // Adding cursorId to TestData to make available within the context of a parallel shell. - TestData.cursorId = cmdRes.cursor.id; + var cmdRes = testDB.runCommand( + {find: "currentop_query", filter: {$comment: "currentop_query"}, batchSize: 0}); + assert.commandWorked(cmdRes); - confirmCurrentOpContents({ - test: function() { - assert.commandWorked( - db.runCommand({getMore: TestData.cursorId, collection: "currentop_query"})); - }, - planSummary: "COLLSCAN", - currentOpFilter: { - "query.getMore": TestData.cursorId, - "originatingCommand.filter.$comment": "currentop_query" + TestData.commandResult = cmdRes; + + var filter; + if (params.readMode === "legacy") { + filter = {"op": "getmore", "query.filter.$comment": "currentop_query"}; + } else { + filter = { + "query.getMore": TestData.commandResult.cursor.id, + "originatingCommand.filter.$comment": "currentop_query" + }; } - }); - delete TestData.cursorId; + confirmCurrentOpContents({ + test: function() { + var cursor = new DBCommandCursor(db.getMongo(), TestData.commandResult, 5); + assert.eq(cursor.itcount(), 10); + }, + planSummary: "COLLSCAN", + currentOpFilter: filter + }); + + delete TestData.commandResult; - // - // Confirm 512 byte size limit for currentOp query field. - // - coll.drop(); - assert.writeOK(coll.insert({a: 1})); + // + // Confirm 512 byte size limit for currentOp query field. + // + coll.drop(); + assert.writeOK(coll.insert({a: 1})); - // When the currentOp command serializes the query object as a string, individual string values - // inside it are truncated at 150 characters. To test "total length" truncation we need to pass - // multiple values, each smaller than 150 bytes. - TestData.queryFilter = { - "1": "1".repeat(100), - "2": "2".repeat(100), - "3": "3".repeat(100), - "4": "4".repeat(100), - "5": "5".repeat(100), - "6": "6".repeat(100), - }; - var truncatedQueryString = "{ find: \"currentop_query\", filter: { " + - "1: \"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\", " + - "2: \"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222\", " + - "3: \"3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333\", " + - "4: \"4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444\", " + - "5: \"5555555555555555555555555555555555555555..."; + // When the currentOp command serializes the query object as a string, individual string + // values inside it are truncated at 150 characters. To test "total length" truncation we + // need to pass multiple values, each smaller than 150 bytes. + TestData.queryFilter = { + "1": "1".repeat(100), + "2": "2".repeat(100), + "3": "3".repeat(100), + "4": "4".repeat(100), + "5": "5".repeat(100), + "6": "6".repeat(100), + }; + var truncatedQueryString = "{ find: \"currentop_query\", filter: { " + + "1: \"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\", " + + "2: \"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222\", " + + "3: \"3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333\", " + + "4: \"4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444\", " + + "5: \"5555555555555555555555555555555555555555..."; - confirmCurrentOpContents({ - test: function() { - assert.commandWorked( - db.runCommand({find: "currentop_query", filter: TestData.queryFilter})); - }, - planSummary: "COLLSCAN", - currentOpFilter: {"query": truncatedQueryString} - }); + confirmCurrentOpContents({ + test: function() { + assert.eq(db.currentop_query.find(TestData.queryFilter).itcount(), 0); + }, + planSummary: "COLLSCAN", + currentOpFilter: {"query": truncatedQueryString} + }); + + delete TestData.queryFilter; + } + + runTest({readMode: "commands"}); + runTest({readMode: "legacy"}); - delete TestData.queryFilter; })(); |