2016-11-15 22:17:19 +01:00
|
|
|
/**
|
|
|
|
* Tests that a batch size of zero can be used for aggregation commands, and all data can be
|
|
|
|
* retrieved via getMores.
|
|
|
|
*/
|
|
|
|
(function() {
|
2019-07-27 00:20:35 +02:00
|
|
|
"use strict";
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
const mongodOptions = {};
|
|
|
|
const conn = MongoRunner.runMongod(mongodOptions);
|
|
|
|
assert.neq(null, conn, "mongod failed to start with options " + tojson(mongodOptions));
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
const testDB = conn.getDB("test");
|
|
|
|
const coll = testDB[jsTest.name];
|
|
|
|
coll.drop();
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Test that an aggregate is successful on a non-existent collection.
|
|
|
|
assert.eq(0,
|
|
|
|
coll.aggregate([]).toArray().length,
|
|
|
|
"expected no results from an aggregation on an empty collection");
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Test that an aggregate is successful on a non-existent collection with a batchSize of 0, and
|
|
|
|
// that a getMore will succeed with an empty result set.
|
|
|
|
let res = assert.commandWorked(
|
|
|
|
testDB.runCommand({aggregate: coll.getName(), pipeline: [], cursor: {batchSize: 0}}));
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
let cursor = new DBCommandCursor(testDB, res);
|
|
|
|
assert.eq(
|
|
|
|
0, cursor.itcount(), "expected no results from getMore of aggregation on empty collection");
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Test that an aggregation can return *all* matching data via getMores if the initial aggregate
|
|
|
|
// used a batchSize of 0.
|
|
|
|
const nDocs = 1000;
|
|
|
|
const bulk = coll.initializeUnorderedBulkOp();
|
|
|
|
for (let i = 0; i < nDocs; i++) {
|
|
|
|
bulk.insert({_id: i, stringField: "string"});
|
|
|
|
}
|
2019-08-14 15:52:59 +02:00
|
|
|
assert.commandWorked(bulk.execute());
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
res = assert.commandWorked(
|
|
|
|
testDB.runCommand({aggregate: coll.getName(), pipeline: [], cursor: {batchSize: 0}}));
|
|
|
|
cursor = new DBCommandCursor(testDB, res);
|
|
|
|
assert.eq(nDocs, cursor.itcount(), "expected all results to be returned via getMores");
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Test that an error in a getMore will destroy the cursor.
|
|
|
|
function assertNumOpenCursors(nExpectedOpen) {
|
|
|
|
let serverStatus = assert.commandWorked(testDB.adminCommand({serverStatus: 1}));
|
|
|
|
assert.eq(nExpectedOpen,
|
|
|
|
serverStatus.metrics.cursor.open.total,
|
|
|
|
"expected to find " + nExpectedOpen +
|
|
|
|
" open cursor(s): " + tojson(serverStatus.metrics.cursor));
|
|
|
|
}
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Issue an aggregate command that will fail *at runtime*, so the error will happen in a
|
|
|
|
// getMore.
|
|
|
|
assertNumOpenCursors(0);
|
|
|
|
res = assert.commandWorked(testDB.runCommand({
|
|
|
|
aggregate: coll.getName(),
|
|
|
|
pipeline: [{$project: {invalidComputation: {$add: [1, "$stringField"]}}}],
|
|
|
|
cursor: {batchSize: 0}
|
|
|
|
}));
|
|
|
|
cursor = new DBCommandCursor(testDB, res);
|
|
|
|
assertNumOpenCursors(1);
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
assert.throws(() => cursor.itcount(), [], "expected getMore to fail");
|
|
|
|
assertNumOpenCursors(0);
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Test that an error in a getMore using a $out stage will destroy the cursor. This test is
|
|
|
|
// intended to reproduce SERVER-26608.
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Issue an aggregate command that will fail *at runtime*, so the error will happen in a
|
|
|
|
// getMore.
|
|
|
|
res = assert.commandWorked(testDB.runCommand({
|
|
|
|
aggregate: coll.getName(),
|
|
|
|
pipeline: [{$out: "validated_collection"}],
|
|
|
|
cursor: {batchSize: 0}
|
|
|
|
}));
|
|
|
|
cursor = new DBCommandCursor(testDB, res);
|
|
|
|
assertNumOpenCursors(1);
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
// Add a document validation rule to the $out collection so that insertion will fail.
|
|
|
|
assert.commandWorked(
|
|
|
|
testDB.runCommand({create: "validated_collection", validator: {stringField: {$type: "int"}}}));
|
2016-11-15 22:17:19 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
assert.throws(() => cursor.itcount(), [], "expected getMore to fail");
|
|
|
|
assertNumOpenCursors(0);
|
2018-02-08 15:46:57 +01:00
|
|
|
|
2019-07-27 00:20:35 +02:00
|
|
|
MongoRunner.stopMongod(conn);
|
2016-11-15 22:17:19 +01:00
|
|
|
}());
|