/**
|
* Tests that "getMore" commands use the same session id as the original "find" command when a
|
* cursor is created in the mongo shell.
|
*/
|
(function() {
|
"use strict";
|
|
load("jstests/libs/parallelTester.js");
|
|
const conn = MongoRunner.runMongod({});
|
|
const db = conn.startSession().getDatabase("test");
|
const coll = db.repro_nosession_getmore;
|
|
const insertRes = coll.insert([{}, {}, {}, {}, {}]);
|
assert.writeOK(insertRes);
|
assert.eq(5, insertRes.nInserted);
|
|
const triggeredFind = new CountDownLatch(1);
|
const triggerGetMore = new CountDownLatch(1);
|
|
function runFindAndThenGetMore(host, triggeredFind, triggerGetMore) {
|
try {
|
const conn = new Mongo(host);
|
const db = conn.startSession().getDatabase("test");
|
const coll = db.repro_nosession_getmore;
|
|
const cursor = coll.find().batchSize(2);
|
cursor.next();
|
cursor.next();
|
|
triggeredFind.countDown();
|
triggerGetMore.await();
|
|
cursor.next();
|
return {ok: 1};
|
} catch (e) {
|
return {ok: 0, error: e.toString(), stack: e.stack};
|
}
|
}
|
|
assert.commandWorked(conn.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1}));
|
assert.commandWorked(
|
conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "alwaysOn"}));
|
|
//
|
// Run a "find" command and verify that it has a session id.
|
//
|
|
const cursorThread =
|
new ScopedThread(runFindAndThenGetMore, conn.host, triggeredFind, triggerGetMore);
|
cursorThread.start();
|
|
let op;
|
let currentOpRes;
|
|
assert.soon(
|
function() {
|
currentOpRes = assert.commandWorked(db.currentOp({ns: coll.getFullName()}));
|
if (currentOpRes.inprog.length === 1 && currentOpRes.inprog[0].numYields > 0) {
|
op = currentOpRes.inprog[0];
|
return true;
|
}
|
return false;
|
},
|
function() {
|
return "Failed to find operation in currentOp() output: " + tojson(currentOpRes);
|
});
|
|
assert(op.hasOwnProperty("lsid"),
|
"Expected 'find' command to have a session id: " + tojson(op));
|
const sessionId = op.lsid;
|
|
// Disable the failpoint and wait until 'cursorThread' has consumed the documents returned in
|
// the "find" command's initial batch.
|
assert.commandWorked(
|
conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "off"}));
|
|
triggeredFind.await();
|
|
assert.commandWorked(
|
conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "alwaysOn"}));
|
|
triggerGetMore.countDown();
|
|
//
|
// Run a "getMore" command and verify that it has the same session id as the "find" command.
|
//
|
|
assert.soon(
|
function() {
|
currentOpRes = assert.commandWorked(db.currentOp({ns: coll.getFullName()}));
|
if (currentOpRes.inprog.length === 1 && currentOpRes.inprog[0].numYields > 0) {
|
op = currentOpRes.inprog[0];
|
return true;
|
}
|
return false;
|
},
|
function() {
|
return "Failed to find operation in currentOp() output: " + tojson(currentOpRes);
|
});
|
|
assert.eq(sessionId,
|
op.lsid,
|
"Expected 'getMore' command to have the same session id: " + tojson(op));
|
|
// Disable the failpoint and wait for 'cursorThread' to exit.
|
assert.commandWorked(
|
conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "off"}));
|
|
cursorThread.join();
|
assert.commandWorked(cursorThread.returnData());
|
|
MongoRunner.stopMongod(conn);
|
})();
|