summaryrefslogtreecommitdiff
path: root/jstests/noPassthroughWithMongod/tailable_getmore_does_not_timeout.js
blob: 54c00aa554da4a45a90baa624883e5b61d8e1513 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Tests that specifying a maxTimeMS on a getMore for a tailable + awaitData cursor is not
// interpreted as a deadline for the operation.
// This test was designed to reproduce SERVER-33942 against a mongod.
// @tags: [requires_capped]
(function() {
"use strict";

// This test runs a getMore in a parallel shell, which will not inherit the implicit session of
// the cursor establishing command.
TestData.disableImplicitSessions = true;

const coll = db.tailable_getmore_no_timeout;
coll.drop();

assert.commandWorked(db.runCommand({create: coll.getName(), capped: true, size: 1024}));

for (let i = 0; i < 10; ++i) {
    assert.commandWorked(coll.insert({_id: i}));
}

const findResponse = assert.commandWorked(
    db.runCommand({find: coll.getName(), filter: {}, tailable: true, awaitData: true}));
const cursorId = findResponse.cursor.id;
assert.neq(0, cursorId);

// Start an operation in a parallel shell that holds the lock for a while.
const awaitSleepShell = startParallelShell(
    () => assert.commandFailedWithCode(db.adminCommand({sleep: 1, lock: "w", secs: 600}),
                                       ErrorCodes.Interrupted));

// Start a getMore and verify that it is waiting for the lock.
const getMoreMaxTimeMS = 10;
const awaitGetMoreShell = startParallelShell(`
        // Wait for the sleep command to take the lock.
        assert.soon(() => db.getSiblingDB("admin")
                              .currentOp({"command.sleep": 1, active: true})
                              .inprog.length === 1);
        // Start the getMore with a low maxTimeMS.
        assert.commandWorked(db.runCommand({
            getMore: ${cursorId.toString()},
            collection: "${coll.getName()}",
            maxTimeMS: ${getMoreMaxTimeMS}
        }));
    `);

// Wait to see the getMore waiting on the lock.
assert.soon(
    () => db.currentOp({"command.getMore": cursorId, waitingForLock: true}).inprog.length === 1);

// Sleep for twice the maxTimeMS to prove that the getMore won't time out waiting for the lock.
sleep(2 * getMoreMaxTimeMS);

// Then kill the command with the lock, allowing the getMore to continue successfully.
const sleepOps = db.getSiblingDB("admin").currentOp({"command.sleep": 1, active: true}).inprog;
assert.eq(sleepOps.length, 1);
const sleepOpId = sleepOps[0].opid;
assert.commandWorked(db.adminCommand({killOp: 1, op: sleepOpId}));

awaitSleepShell();
awaitGetMoreShell();
}());