summaryrefslogtreecommitdiff
path: root/jstests/sharding/change_streams_unsharded_update_resume.js
blob: a13b3077b1b307cc987228774f0b205fc00d13b7 (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
/**
 * Tests that the post-image of an update which occurred while the collection was unsharded can
 * still be looked up after the collection becomes sharded. Exercises the fix for SERVER-44484.
 * @tags: [
 *   uses_change_streams,
 * ]
 */
(function() {
"use strict";

// Start a new sharded cluster with 2 nodes and obtain references to the test DB and collection.
const st = new ShardingTest({
    shards: 2,
    mongos: 1,
    rs: {nodes: 1, setParameter: {periodicNoopIntervalSecs: 1, writePeriodicNoops: true}}
});

const mongosDB = st.s0.getDB(jsTestName());
const mongosColl = mongosDB.test;

// Open a change stream on the unsharded collection.
let csCur = mongosColl.watch([], {fullDocument: "updateLookup"});

// Insert one document with a known _id into the unsharded collection, and obtain its resume token.
assert.commandWorked(mongosColl.insert({_id: 0, a: -100}));
assert.soon(() => csCur.hasNext());
const insertEvent = csCur.next();
assert.eq(insertEvent.operationType, "insert");

// Update the document and confirm that we can see the updateLookup fullDocument.
assert.commandWorked(mongosColl.update({_id: 0}, {$set: {updated: true}}));
assert.soon(() => csCur.hasNext());
let updateEvent = csCur.next();
assert.eq(updateEvent.operationType, "update");
assert.docEq({_id: 0, a: -100, updated: true}, updateEvent.fullDocument);

// Now shard the collection on {a: 1} and move the upper chunk to the other shard.
assert.commandWorked(mongosColl.createIndex({a: 1}));
st.shardColl(mongosColl, {a: 1}, {a: 0}, {a: 0});

// Resume a change stream just after the initial insert. We expect the update lookup to succeed,
// despite the fact that only the _id and not the entire documentKey was recorded in the oplog.
csCur = mongosColl.watch([], {resumeAfter: insertEvent._id, fullDocument: "updateLookup"});
assert.soon(() => csCur.hasNext());
updateEvent = csCur.next();
assert.eq(updateEvent.operationType, "update");
assert.docEq({_id: 0, a: -100, updated: true}, updateEvent.fullDocument);

// Insert a second document with the same _id on the second shard.
assert.commandWorked(mongosColl.insert({_id: 0, a: 100}));

// Now that two documents with the same _id are present, the update lookup fails.
csCur = mongosColl.watch([], {resumeAfter: insertEvent._id, fullDocument: "updateLookup"});
assert.soon(() => {
    try {
        assert.eq(csCur.hasNext(), false, () => tojson(csCur.next()));
        return false;
    } catch (ex) {
        assert.eq(ex.code, ErrorCodes.ChangeStreamFatalError, () => tojson({originalError: ex}));
        return true;
    }
});

st.stop();
})();