summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/awaitdata_getmore_cmd.js
blob: ef47efb0e6737e10499476e863a312fddc290421 (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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Test the awaitData flag for the find/getMore commands.
(function() {
    'use strict';

    var mongo = MongoRunner.runMongod({master: ""});

    var cmdRes;
    var cursorId;
    var defaultBatchSize = 101;
    var collName = 'await_data';
    var db = mongo.getDB("test");
    var coll = db[collName];

    var localDB = db.getSiblingDB("local");
    var oplogColl = localDB.oplog.$main;

    // Create a non-capped collection with 10 documents.
    coll.drop();
    for (var i = 0; i < 10; i++) {
        assert.writeOK(coll.insert({a: i}));
    }

    // Find with tailable flag set should fail for a non-capped collection.
    cmdRes = db.runCommand({find: collName, tailable: true});
    assert.commandFailed(cmdRes);

    // Should also fail in the non-capped case if both the tailable and awaitData flags are set.
    cmdRes = db.runCommand({find: collName, tailable: true, awaitData: true});
    assert.commandFailed(cmdRes);

    // Create a capped collection with 10 documents.
    coll.drop();
    assert.commandWorked(db.createCollection(collName, {capped: true, size: 2048}));
    for (var i = 0; i < 10; i++) {
        assert.writeOK(coll.insert({a: i}));
    }

    // GetMore should succeed if query has awaitData but no maxTimeMS is supplied.
    cmdRes = db.runCommand({find: collName, batchSize: 2, awaitData: true, tailable: true});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());
    assert.eq(cmdRes.cursor.firstBatch.length, 2);
    cmdRes = db.runCommand({getMore: cmdRes.cursor.id, collection: collName});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());

    // Should also succeed if maxTimeMS is supplied on the original find.
    cmdRes = db.runCommand(
        {find: collName, batchSize: 2, awaitData: true, tailable: true, maxTimeMS: 2000});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());
    assert.eq(cmdRes.cursor.firstBatch.length, 2);
    cmdRes = db.runCommand({getMore: cmdRes.cursor.id, collection: collName});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());

    // Check that we can set up a tailable cursor over the capped collection.
    cmdRes = db.runCommand({find: collName, batchSize: 5, awaitData: true, tailable: true});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());
    assert.eq(cmdRes.cursor.firstBatch.length, 5);

    // Check that tailing the capped collection with awaitData eventually ends up returning an empty
    // batch after hitting the timeout.
    cmdRes = db.runCommand({find: collName, batchSize: 2, awaitData: true, tailable: true});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());
    assert.eq(cmdRes.cursor.firstBatch.length, 2);

    // Issue getMore until we get an empty batch of results.
    cmdRes = db.runCommand({
        getMore: cmdRes.cursor.id,
        collection: coll.getName(),
        batchSize: NumberInt(2),
        maxTimeMS: 4000
    });
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, coll.getFullName());

    // Keep issuing getMore until we get an empty batch after the timeout expires.
    while (cmdRes.cursor.nextBatch.length > 0) {
        var now = new Date();
        cmdRes = db.runCommand({
            getMore: cmdRes.cursor.id,
            collection: coll.getName(),
            batchSize: NumberInt(2),
            maxTimeMS: 4000
        });
        assert.commandWorked(cmdRes);
        assert.gt(cmdRes.cursor.id, NumberLong(0));
        assert.eq(cmdRes.cursor.ns, coll.getFullName());
    }
    assert.gte((new Date()) - now, 2000);

    // Repeat the test, this time tailing the oplog rather than a user-created capped collection.
    cmdRes = localDB.runCommand(
        {find: oplogColl.getName(), batchSize: 2, awaitData: true, tailable: true});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, oplogColl.getFullName());
    assert.eq(cmdRes.cursor.firstBatch.length, 2);

    cmdRes = localDB.runCommand(
        {getMore: cmdRes.cursor.id, collection: oplogColl.getName(), maxTimeMS: 1000});
    assert.commandWorked(cmdRes);
    assert.gt(cmdRes.cursor.id, NumberLong(0));
    assert.eq(cmdRes.cursor.ns, oplogColl.getFullName());

    while (cmdRes.cursor.nextBatch.length > 0) {
        now = new Date();
        cmdRes = localDB.runCommand(
            {getMore: cmdRes.cursor.id, collection: oplogColl.getName(), maxTimeMS: 4000});
        assert.commandWorked(cmdRes);
        assert.gt(cmdRes.cursor.id, NumberLong(0));
        assert.eq(cmdRes.cursor.ns, oplogColl.getFullName());
    }
    assert.gte((new Date()) - now, 2000);

})();